summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.mailmap4
-rw-r--r--Documentation/block/queue-sysfs.txt63
-rw-r--r--Documentation/cpu-freq/user-guide.txt16
-rw-r--r--Documentation/filesystems/sysfs-pci.txt13
-rw-r--r--Documentation/filesystems/ubifs.txt7
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/mpc5200.txt180
-rw-r--r--Documentation/powerpc/mpc52xx-device-tree-bindings.txt277
-rw-r--r--Documentation/video4linux/v4lgrab.c25
-rw-r--r--MAINTAINERS13
-rw-r--r--Makefile2
-rw-r--r--arch/alpha/include/asm/bug.h4
-rw-r--r--arch/arm/kernel/entry-armv.S1
-rw-r--r--arch/arm/kernel/entry-common.S2
-rw-r--r--arch/arm/kernel/irq.c2
-rw-r--r--arch/arm/mach-msm/board-halibut.c1
-rw-r--r--arch/arm/mach-omap1/devices.c2
-rw-r--r--arch/arm/mach-omap1/mcbsp.c98
-rw-r--r--arch/arm/mach-omap2/devices.c11
-rw-r--r--arch/arm/mach-omap2/id.c6
-rw-r--r--arch/arm/mach-omap2/irq.c1
-rw-r--r--arch/arm/mach-omap2/mcbsp.c145
-rw-r--r--arch/arm/mach-omap2/sleep24xx.S3
-rw-r--r--arch/arm/mach-omap2/timer-gp.c3
-rw-r--r--arch/arm/mach-sa1100/generic.c2
-rw-r--r--arch/arm/mm/fault-armv.c5
-rw-r--r--arch/arm/plat-mxc/include/mach/mmc.h36
-rw-r--r--arch/arm/plat-omap/devices.c7
-rw-r--r--arch/arm/plat-omap/dma.c5
-rw-r--r--arch/arm/plat-omap/include/mach/cpu.h1
-rw-r--r--arch/arm/plat-omap/include/mach/mcbsp.h6
-rw-r--r--arch/arm/plat-omap/include/mach/mmc.h10
-rw-r--r--arch/arm/plat-omap/mcbsp.c52
-rw-r--r--arch/blackfin/Kconfig52
-rw-r--r--arch/blackfin/Makefile106
-rw-r--r--arch/blackfin/configs/BF518F-EZBRD_defconfig9
-rw-r--r--arch/blackfin/configs/BF526-EZBRD_defconfig2
-rw-r--r--arch/blackfin/configs/BF527-EZKIT_defconfig2
-rw-r--r--arch/blackfin/configs/BF533-EZKIT_defconfig2
-rw-r--r--arch/blackfin/configs/BF533-STAMP_defconfig2
-rw-r--r--arch/blackfin/configs/BF537-STAMP_defconfig2
-rw-r--r--arch/blackfin/configs/BF538-EZKIT_defconfig2
-rw-r--r--arch/blackfin/configs/BF548-EZKIT_defconfig2
-rw-r--r--arch/blackfin/configs/BF561-EZKIT_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF527_defconfig445
-rw-r--r--arch/blackfin/include/asm/checksum.h34
-rw-r--r--arch/blackfin/include/asm/delay.h35
-rw-r--r--arch/blackfin/include/asm/gpio.h58
-rw-r--r--arch/blackfin/include/asm/kgdb.h53
-rw-r--r--arch/blackfin/include/asm/mem_init.h2
-rw-r--r--arch/blackfin/include/asm/pda.h1
-rw-r--r--arch/blackfin/include/asm/reboot.h2
-rw-r--r--arch/blackfin/kernel/Makefile2
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c7
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c578
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbinit.c4
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbmgr.c12
-rw-r--r--arch/blackfin/kernel/irqchip.c8
-rw-r--r--arch/blackfin/kernel/reboot.c30
-rw-r--r--arch/blackfin/kernel/setup.c12
-rw-r--r--arch/blackfin/kernel/traps.c39
-rw-r--r--arch/blackfin/mach-bf518/boards/ezbrd.c59
-rw-r--r--arch/blackfin/mach-bf518/include/mach/portmux.h2
-rw-r--r--arch/blackfin/mach-bf527/boards/cm_bf527.c18
-rw-r--r--arch/blackfin/mach-bf527/boards/ezbrd.c18
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c18
-rw-r--r--arch/blackfin/mach-bf527/include/mach/portmux.h2
-rw-r--r--arch/blackfin/mach-bf533/boards/blackstamp.c4
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c4
-rw-r--r--arch/blackfin/mach-bf533/include/mach/portmux.h5
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537.c6
-rw-r--r--arch/blackfin/mach-bf537/boards/generic_board.c12
-rw-r--r--arch/blackfin/mach-bf537/boards/minotaur.c8
-rw-r--r--arch/blackfin/mach-bf537/boards/pnav10.c10
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c14
-rw-r--r--arch/blackfin/mach-bf537/boards/tcm_bf537.c10
-rw-r--r--arch/blackfin/mach-bf537/include/mach/portmux.h1
-rw-r--r--arch/blackfin/mach-bf538/include/mach/portmux.h1
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c4
-rw-r--r--arch/blackfin/mach-bf548/include/mach/anomaly.h1
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bf548.h12
-rw-r--r--arch/blackfin/mach-bf548/include/mach/gpio.h12
-rw-r--r--arch/blackfin/mach-bf548/include/mach/portmux.h1
-rw-r--r--arch/blackfin/mach-bf561/include/mach/defBF561.h2
-rw-r--r--arch/blackfin/mach-bf561/include/mach/portmux.h1
-rw-r--r--arch/blackfin/mach-common/clocks-init.c3
-rw-r--r--arch/blackfin/mach-common/entry.S9
-rw-r--r--arch/blackfin/mach-common/head.S84
-rw-r--r--arch/blackfin/mach-common/interrupt.S2
-rw-r--r--arch/blackfin/mach-common/ints-priority.c11
-rw-r--r--arch/blackfin/mach-common/pm.c11
-rw-r--r--arch/ia64/sn/kernel/io_acpi_init.c2
-rw-r--r--arch/ia64/sn/kernel/io_init.c2
-rw-r--r--arch/mips/Kconfig7
-rw-r--r--arch/mips/alchemy/common/time.c2
-rw-r--r--arch/mips/cavium-octeon/setup.c2
-rw-r--r--arch/mips/configs/ip27_defconfig2
-rw-r--r--arch/mips/include/asm/atomic.h52
-rw-r--r--arch/mips/include/asm/mach-rc32434/gpio.h5
-rw-r--r--arch/mips/include/asm/mach-rc32434/irq.h3
-rw-r--r--arch/mips/include/asm/mach-rc32434/rb.h3
-rw-r--r--arch/mips/include/asm/ptrace.h2
-rw-r--r--arch/mips/include/asm/termios.h100
-rw-r--r--arch/mips/include/asm/txx9/tx4939.h1
-rw-r--r--arch/mips/kernel/genex.S6
-rw-r--r--arch/mips/kernel/mips-mt-fpaff.c3
-rw-r--r--arch/mips/kernel/traps.c16
-rw-r--r--arch/mips/lib/memcpy-inatomic.S2
-rw-r--r--arch/mips/lib/memcpy.S2
-rw-r--r--arch/mips/mm/c-r4k.c22
-rw-r--r--arch/mips/mm/fault.c21
-rw-r--r--arch/mips/pci/pci-rc32434.c11
-rw-r--r--arch/mips/rb532/devices.c57
-rw-r--r--arch/mips/rb532/gpio.c90
-rw-r--r--arch/mips/rb532/irq.c27
-rw-r--r--arch/mips/rb532/serial.c2
-rw-r--r--arch/mips/txx9/generic/setup_tx4939.c22
-rw-r--r--arch/mips/txx9/rbtx4939/setup.c1
-rw-r--r--arch/powerpc/configs/52xx/cm5200_defconfig83
-rw-r--r--arch/powerpc/configs/52xx/lite5200b_defconfig86
-rw-r--r--arch/powerpc/configs/52xx/motionpro_defconfig85
-rw-r--r--arch/powerpc/configs/52xx/pcm030_defconfig82
-rw-r--r--arch/powerpc/configs/52xx/tqm5200_defconfig89
-rw-r--r--arch/powerpc/configs/mpc5200_defconfig104
-rw-r--r--arch/powerpc/kernel/pci-common.c5
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pci.c24
-rw-r--r--arch/sh/boards/board-ap325rxa.c63
-rw-r--r--arch/sh/configs/ap325rxa_defconfig27
-rw-r--r--arch/sh/configs/migor_defconfig42
-rw-r--r--arch/sh/include/asm/mutex-llsc.h21
-rw-r--r--arch/sh/include/asm/syscall_32.h22
-rw-r--r--arch/sh/include/asm/syscall_64.h22
-rw-r--r--arch/sh/kernel/cpu/sh4/fpu.c2
-rw-r--r--arch/sh/kernel/setup.c8
-rw-r--r--arch/sh/kernel/signal_32.c4
-rw-r--r--arch/sh/kernel/signal_64.c4
-rw-r--r--arch/sh/lib/checksum.S69
-rw-r--r--arch/sparc/include/asm/cpudata_64.h2
-rw-r--r--arch/sparc/include/asm/irq_64.h4
-rw-r--r--arch/sparc/include/asm/kdebug_64.h2
-rw-r--r--arch/sparc/include/asm/nmi.h10
-rw-r--r--arch/sparc/include/asm/pcr.h46
-rw-r--r--arch/sparc/include/asm/pil.h1
-rw-r--r--arch/sparc/kernel/Makefile2
-rw-r--r--arch/sparc/kernel/cpu.c33
-rw-r--r--arch/sparc/kernel/irq_64.c68
-rw-r--r--arch/sparc/kernel/kernel.h1
-rw-r--r--arch/sparc/kernel/nmi.c224
-rw-r--r--arch/sparc/kernel/pcr.c153
-rw-r--r--arch/sparc/kernel/process_64.c5
-rw-r--r--arch/sparc/kernel/setup_64.c2
-rw-r--r--arch/sparc/kernel/ttable.S3
-rw-r--r--arch/sparc/mm/fault_64.c44
-rw-r--r--arch/sparc/oprofile/init.c232
-rw-r--r--arch/x86/boot/video-vesa.c11
-rw-r--r--arch/x86/ia32/ia32entry.S8
-rw-r--r--arch/x86/include/asm/e820.h1
-rw-r--r--arch/x86/include/asm/kvm.h2
-rw-r--r--arch/x86/include/asm/mce.h5
-rw-r--r--arch/x86/include/asm/mtrr.h1
-rw-r--r--arch/x86/include/asm/ptrace-abi.h2
-rw-r--r--arch/x86/include/asm/sigcontext.h2
-rw-r--r--arch/x86/include/asm/sigcontext32.h2
-rw-r--r--arch/x86/include/asm/swab.h2
-rw-r--r--arch/x86/kernel/acpi/sleep.c4
-rw-r--r--arch/x86/kernel/apic.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/Kconfig11
-rw-r--r--arch/x86/kernel/cpu/intel.c2
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c15
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c3
-rw-r--r--arch/x86/kernel/ds.c31
-rw-r--r--arch/x86/kernel/entry_64.S1
-rw-r--r--arch/x86/kernel/io_apic.c5
-rw-r--r--arch/x86/kernel/irqinit_32.c12
-rw-r--r--arch/x86/mach-default/setup.c12
-rw-r--r--arch/x86/mach-voyager/setup.c12
-rw-r--r--arch/x86/mach-voyager/voyager_smp.c24
-rw-r--r--arch/x86/mm/fault.c7
-rw-r--r--arch/x86/pci/irq.c1
-rw-r--r--arch/x86/xen/multicalls.h4
-rw-r--r--block/blk-core.c6
-rw-r--r--block/blk.h8
-rw-r--r--drivers/acpi/Kconfig3
-rw-r--r--drivers/acpi/acpica/tbutils.c7
-rw-r--r--drivers/acpi/acpica/uteval.c21
-rw-r--r--drivers/acpi/container.c5
-rw-r--r--drivers/acpi/dock.c14
-rw-r--r--drivers/acpi/ec.c2
-rw-r--r--drivers/acpi/glue.c8
-rw-r--r--drivers/acpi/osl.c54
-rw-r--r--drivers/acpi/pci_link.c2
-rw-r--r--drivers/acpi/processor_idle.c667
-rw-r--r--drivers/acpi/processor_perflib.c105
-rw-r--r--drivers/acpi/sleep.c53
-rw-r--r--drivers/acpi/tables.c7
-rw-r--r--drivers/acpi/video.c16
-rw-r--r--drivers/ata/ahci.c9
-rw-r--r--drivers/ata/libata-core.c96
-rw-r--r--drivers/ata/libata-eh.c87
-rw-r--r--drivers/ata/libata-pmp.c2
-rw-r--r--drivers/ata/libata-scsi.c1
-rw-r--r--drivers/ata/libata.h4
-rw-r--r--drivers/ata/pata_qdi.c2
-rw-r--r--drivers/ata/sata_mv.c4
-rw-r--r--drivers/ata/sata_nv.c7
-rw-r--r--drivers/ata/sata_sil.c2
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/selection.c2
-rw-r--r--drivers/char/sx.c8
-rw-r--r--drivers/dca/dca-core.c51
-rw-r--r--drivers/firewire/fw-card.c9
-rw-r--r--drivers/gpu/drm/drm_gem.c2
-rw-r--r--drivers/hwmon/hp_accel.c9
-rw-r--r--drivers/ide/Kconfig10
-rw-r--r--drivers/ide/Makefile1
-rw-r--r--drivers/ide/cs5536.c308
-rw-r--r--drivers/ide/icside.c2
-rw-r--r--drivers/ide/ide-acpi.c2
-rw-r--r--drivers/ide/ide-cd.c3
-rw-r--r--drivers/ide/ide-io.c9
-rw-r--r--drivers/ide/ide-probe.c43
-rw-r--r--drivers/ide/qd65xx.c2
-rw-r--r--drivers/ide/qd65xx.h2
-rw-r--r--drivers/ide/tx4939ide.c4
-rw-r--r--drivers/ide/via82cxxx.c5
-rw-r--r--drivers/ieee1394/dv1394.c8
-rw-r--r--drivers/md/linear.c6
-rw-r--r--drivers/md/md.c24
-rw-r--r--drivers/md/raid1.c3
-rw-r--r--drivers/media/common/saa7146_video.c1
-rw-r--r--drivers/media/common/tuners/mxl5007t.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c24
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.h6
-rw-r--r--drivers/media/dvb/dvb-usb/af9005-fe.c2
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c30
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c18
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h2
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c2
-rw-r--r--drivers/media/dvb/frontends/s5h1409.c7
-rw-r--r--drivers/media/dvb/frontends/stb0899_algo.c3
-rw-r--r--drivers/media/dvb/ttpci/budget.c1
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c2
-rw-r--r--drivers/media/radio/radio-mr800.c12
-rw-r--r--drivers/media/video/cs5345.c1
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c3
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c5
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c8
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c72
-rw-r--r--drivers/media/video/cx88/cx88.h2
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c14
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c32
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c20
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c20
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c45
-rw-r--r--drivers/media/video/em28xx/em28xx.h21
-rw-r--r--drivers/media/video/gspca/gspca.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c4
-rw-r--r--drivers/media/video/pwc/pwc-if.c1
-rw-r--r--drivers/media/video/saa7127.c52
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c4
-rw-r--r--drivers/media/video/saa717x.c1
-rw-r--r--drivers/media/video/tda9875.c2
-rw-r--r--drivers/media/video/tveeprom.c3
-rw-r--r--drivers/media/video/tvp514x.c2
-rw-r--r--drivers/media/video/upd64031a.c1
-rw-r--r--drivers/media/video/upd64083.c1
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c2
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c7
-rw-r--r--drivers/media/video/uvc/uvc_driver.c55
-rw-r--r--drivers/media/video/uvc/uvc_isight.c2
-rw-r--r--drivers/media/video/uvc/uvc_queue.c31
-rw-r--r--drivers/media/video/uvc/uvc_status.c3
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c10
-rw-r--r--drivers/media/video/uvc/uvc_video.c31
-rw-r--r--drivers/media/video/uvc/uvcvideo.h232
-rw-r--r--drivers/media/video/v4l2-subdev.c4
-rw-r--r--drivers/media/video/zoran/zoran.h12
-rw-r--r--drivers/media/video/zoran/zoran_card.c620
-rw-r--r--drivers/media/video/zoran/zoran_card.h2
-rw-r--r--drivers/media/video/zoran/zoran_driver.c105
-rw-r--r--drivers/mfd/pcf50633-core.c1
-rw-r--r--drivers/misc/Kconfig1
-rw-r--r--drivers/misc/atmel-ssc.c2
-rw-r--r--drivers/misc/hpilo.c6
-rw-r--r--drivers/misc/hpilo.h2
-rw-r--r--drivers/misc/sgi-xp/xpc.h5
-rw-r--r--drivers/misc/sgi-xp/xpc_uv.c11
-rw-r--r--drivers/misc/sgi-xp/xpnet.c3
-rw-r--r--drivers/mmc/host/Kconfig10
-rw-r--r--drivers/mmc/host/Makefile1
-rw-r--r--drivers/mmc/host/mmci.c37
-rw-r--r--drivers/mmc/host/mmci.h28
-rw-r--r--drivers/mmc/host/mxcmmc.c880
-rw-r--r--drivers/mmc/host/pxamci.c25
-rw-r--r--drivers/mmc/host/ricoh_mmc.c8
-rw-r--r--drivers/mtd/maps/sa1100-flash.c4
-rw-r--r--drivers/net/arm/etherh.c2
-rw-r--r--drivers/net/cassini.c4
-rw-r--r--drivers/net/cxgb3/sge.c3
-rw-r--r--drivers/net/e1000/e1000_main.c2
-rw-r--r--drivers/net/gianfar.c3
-rw-r--r--drivers/net/gianfar.h2
-rw-r--r--drivers/net/ibm_newemac/phy.c4
-rw-r--r--drivers/net/igb/e1000_82575.c11
-rw-r--r--drivers/net/igb/igb.h9
-rw-r--r--drivers/net/igb/igb_main.c24
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c2
-rw-r--r--drivers/net/ps3_gelic_wireless.c2
-rw-r--r--drivers/net/qlge/qlge.h10
-rw-r--r--drivers/net/qlge/qlge_main.c25
-rw-r--r--drivers/net/sfc/efx.c59
-rw-r--r--drivers/net/sfc/efx.h9
-rw-r--r--drivers/net/sfc/ethtool.c3
-rw-r--r--drivers/net/sfc/falcon.c32
-rw-r--r--drivers/net/sfc/mdio_10g.c191
-rw-r--r--drivers/net/sfc/mdio_10g.h3
-rw-r--r--drivers/net/sfc/net_driver.h9
-rw-r--r--drivers/net/sfc/phy.h1
-rw-r--r--drivers/net/sfc/selftest.c7
-rw-r--r--drivers/net/sfc/sfe4001.c42
-rw-r--r--drivers/net/sfc/tenxpress.c213
-rw-r--r--drivers/net/sfc/workarounds.h12
-rw-r--r--drivers/net/sky2.c6
-rw-r--r--drivers/net/smc911x.c4
-rw-r--r--drivers/net/smsc9420.c12
-rw-r--r--drivers/net/sungem.c2
-rw-r--r--drivers/net/sungem_phy.c2
-rw-r--r--drivers/net/sunqe.c2
-rw-r--r--drivers/net/tsi108_eth.c2
-rw-r--r--drivers/net/tulip/de2104x.c2
-rw-r--r--drivers/net/usb/hso.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c2
-rw-r--r--drivers/pci/hotplug/Makefile6
-rw-r--r--drivers/pci/hotplug/fakephp.c42
-rw-r--r--drivers/pci/msi.c13
-rw-r--r--drivers/pci/pci-driver.c177
-rw-r--r--drivers/pci/pci-sysfs.c4
-rw-r--r--drivers/pci/pci.c34
-rw-r--r--drivers/pci/pcie/aspm.c4
-rw-r--r--drivers/pci/pcie/portdrv_pci.c16
-rw-r--r--drivers/pci/rom.c8
-rw-r--r--drivers/platform/x86/Kconfig1
-rw-r--r--drivers/platform/x86/asus-laptop.c176
-rw-r--r--drivers/platform/x86/asus_acpi.c16
-rw-r--r--drivers/platform/x86/eeepc-laptop.c164
-rw-r--r--drivers/platform/x86/hp-wmi.c6
-rw-r--r--drivers/platform/x86/panasonic-laptop.c2
-rw-r--r--drivers/regulator/bq24022.c6
-rw-r--r--drivers/regulator/wm8350-regulator.c2
-rw-r--r--drivers/rtc/Kconfig6
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-dm355evm.c175
-rw-r--r--drivers/rtc/rtc-ds1390.c1
-rw-r--r--drivers/usb/host/whci/asl.c9
-rw-r--r--drivers/usb/host/whci/hw.c15
-rw-r--r--drivers/usb/host/whci/pzl.c9
-rw-r--r--drivers/usb/host/whci/whcd.h1
-rw-r--r--drivers/usb/wusbcore/devconnect.c1
-rw-r--r--drivers/usb/wusbcore/rh.c3
-rw-r--r--drivers/uwb/allocator.c1
-rw-r--r--drivers/uwb/drp.c4
-rw-r--r--drivers/uwb/rsv.c21
-rw-r--r--drivers/video/aty/aty128fb.c33
-rw-r--r--drivers/video/aty/atyfb_base.c42
-rw-r--r--drivers/video/aty/mach64_ct.c11
-rw-r--r--drivers/video/aty/radeon_base.c10
-rw-r--r--drivers/video/aty/radeon_pm.c103
-rw-r--r--drivers/video/aty/radeonfb.h2
-rw-r--r--drivers/video/backlight/Makefile2
-rw-r--r--drivers/video/backlight/da903x_bl.c (renamed from drivers/video/backlight/da903x.c)0
-rw-r--r--drivers/video/fbcmap.c20
-rw-r--r--drivers/video/fbmem.c135
-rw-r--r--drivers/virtio/virtio_pci.c2
-rw-r--r--drivers/xen/balloon.c33
-rw-r--r--fs/binfmt_elf.c14
-rw-r--r--fs/btrfs/Kconfig13
-rw-r--r--fs/btrfs/async-thread.c61
-rw-r--r--fs/btrfs/compression.c1
-rw-r--r--fs/btrfs/ctree.c276
-rw-r--r--fs/btrfs/ctree.h28
-rw-r--r--fs/btrfs/disk-io.c120
-rw-r--r--fs/btrfs/disk-io.h2
-rw-r--r--fs/btrfs/extent-tree.c438
-rw-r--r--fs/btrfs/extent_io.c132
-rw-r--r--fs/btrfs/extent_io.h18
-rw-r--r--fs/btrfs/extent_map.c1
-rw-r--r--fs/btrfs/file.c5
-rw-r--r--fs/btrfs/inode.c84
-rw-r--r--fs/btrfs/ioctl.c1
-rw-r--r--fs/btrfs/locking.c208
-rw-r--r--fs/btrfs/locking.h6
-rw-r--r--fs/btrfs/ordered-data.c4
-rw-r--r--fs/btrfs/ref-cache.c1
-rw-r--r--fs/btrfs/ref-cache.h1
-rw-r--r--fs/btrfs/super.c6
-rw-r--r--fs/btrfs/transaction.c4
-rw-r--r--fs/btrfs/tree-defrag.c1
-rw-r--r--fs/btrfs/tree-log.c354
-rw-r--r--fs/btrfs/volumes.c49
-rw-r--r--fs/btrfs/xattr.c48
-rw-r--r--fs/btrfs/xattr.h2
-rw-r--r--fs/buffer.c2
-rw-r--r--fs/compat.c2
-rw-r--r--fs/compat_ioctl.c2
-rw-r--r--fs/ecryptfs/crypto.c4
-rw-r--r--fs/exec.c28
-rw-r--r--fs/internal.h2
-rw-r--r--fs/ocfs2/alloc.c3
-rw-r--r--fs/ocfs2/dcache.c42
-rw-r--r--fs/ocfs2/dcache.h9
-rw-r--r--fs/ocfs2/dlmglue.c4
-rw-r--r--fs/ocfs2/ocfs2.h6
-rw-r--r--fs/ocfs2/quota_global.c4
-rw-r--r--fs/ocfs2/super.c3
-rw-r--r--fs/ocfs2/xattr.c17
-rw-r--r--fs/seq_file.c115
-rw-r--r--fs/super.c4
-rw-r--r--fs/ubifs/budget.c35
-rw-r--r--fs/ubifs/debug.c122
-rw-r--r--fs/ubifs/debug.h36
-rw-r--r--fs/ubifs/dir.c96
-rw-r--r--fs/ubifs/file.c9
-rw-r--r--fs/ubifs/gc.c28
-rw-r--r--fs/ubifs/io.c22
-rw-r--r--fs/ubifs/journal.c2
-rw-r--r--fs/ubifs/lprops.c12
-rw-r--r--fs/ubifs/lpt_commit.c44
-rw-r--r--fs/ubifs/master.c2
-rw-r--r--fs/ubifs/orphan.c38
-rw-r--r--fs/ubifs/super.c195
-rw-r--r--fs/ubifs/tnc.c12
-rw-r--r--fs/ubifs/ubifs.h26
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c6
-rw-r--r--fs/xfs/xfs_dfrag.c10
-rw-r--r--fs/xfs/xfs_log_recover.c31
-rw-r--r--include/acpi/pdc_intel.h2
-rw-r--r--include/linux/Kbuild2
-rw-r--r--include/linux/aio_abi.h1
-rw-r--r--include/linux/async.h8
-rw-r--r--include/linux/ata.h15
-rw-r--r--include/linux/atalk.h1
-rw-r--r--include/linux/atmbr2684.h1
-rw-r--r--include/linux/auto_fs4.h1
-rw-r--r--include/linux/bfs_fs.h3
-rw-r--r--include/linux/bio.h10
-rw-r--r--include/linux/blkdev.h2
-rw-r--r--include/linux/blktrace_api.h1
-rw-r--r--include/linux/can/bcm.h2
-rw-r--r--include/linux/capability.h8
-rw-r--r--include/linux/cdrom.h1
-rw-r--r--include/linux/cgroupstats.h1
-rw-r--r--include/linux/clockchips.h1
-rw-r--r--include/linux/dlm_plock.h2
-rw-r--r--include/linux/dn.h2
-rw-r--r--include/linux/dvb/audio.h5
-rw-r--r--include/linux/dvb/dmx.h2
-rw-r--r--include/linux/dvb/frontend.h3
-rw-r--r--include/linux/dvb/net.h3
-rw-r--r--include/linux/dvb/video.h7
-rw-r--r--include/linux/edd.h2
-rw-r--r--include/linux/efs_fs_sb.h1
-rw-r--r--include/linux/elf-fdpic.h2
-rw-r--r--include/linux/elf.h3
-rw-r--r--include/linux/errqueue.h2
-rw-r--r--include/linux/fb.h15
-rw-r--r--include/linux/genetlink.h1
-rw-r--r--include/linux/gfs2_ondisk.h2
-rw-r--r--include/linux/hid.h2
-rw-r--r--include/linux/hiddev.h2
-rw-r--r--include/linux/icmpv6.h1
-rw-r--r--include/linux/if_addr.h1
-rw-r--r--include/linux/if_addrlabel.h2
-rw-r--r--include/linux/if_fc.h1
-rw-r--r--include/linux/if_hippi.h1
-rw-r--r--include/linux/if_link.h1
-rw-r--r--include/linux/if_ppp.h1
-rw-r--r--include/linux/if_strip.h2
-rw-r--r--include/linux/if_tr.h1
-rw-r--r--include/linux/if_tunnel.h3
-rw-r--r--include/linux/igmp.h1
-rw-r--r--include/linux/inet_diag.h2
-rw-r--r--include/linux/ip6_tunnel.h2
-rw-r--r--include/linux/ipv6.h1
-rw-r--r--include/linux/ipv6_route.h2
-rw-r--r--include/linux/ipx.h1
-rw-r--r--include/linux/irda.h2
-rw-r--r--include/linux/kernel.h3
-rw-r--r--include/linux/libata.h19
-rw-r--r--include/linux/minix_fs.h1
-rw-r--r--include/linux/module.h26
-rw-r--r--include/linux/msdos_fs.h1
-rw-r--r--include/linux/neighbour.h1
-rw-r--r--include/linux/netfilter/xt_conntrack.h1
-rw-r--r--include/linux/nfs_idmap.h2
-rw-r--r--include/linux/nfsd/export.h3
-rw-r--r--include/linux/nfsd/nfsfh.h3
-rw-r--r--include/linux/nfsd/syscall.h3
-rw-r--r--include/linux/nubus.h1
-rw-r--r--include/linux/pci.h2
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/linux/phonet.h2
-rw-r--r--include/linux/pkt_cls.h1
-rw-r--r--include/linux/pkt_sched.h2
-rw-r--r--include/linux/ppp_defs.h2
-rw-r--r--include/linux/raid/md_p.h2
-rw-r--r--include/linux/random.h1
-rw-r--r--include/linux/rtnetlink.h1
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/linux/signalfd.h1
-rw-r--r--include/linux/slab_def.h10
-rw-r--r--include/linux/sound.h2
-rw-r--r--include/linux/spi/spidev.h1
-rw-r--r--include/linux/synclink.h2
-rw-r--r--include/linux/taskstats.h2
-rw-r--r--include/linux/tc_act/tc_gact.h1
-rw-r--r--include/linux/tc_act/tc_mirred.h1
-rw-r--r--include/linux/tc_act/tc_pedit.h1
-rw-r--r--include/linux/tc_ematch/tc_em_cmp.h1
-rw-r--r--include/linux/tc_ematch/tc_em_meta.h1
-rw-r--r--include/linux/tc_ematch/tc_em_nbyte.h1
-rw-r--r--include/linux/tc_ematch/tc_em_text.h1
-rw-r--r--include/linux/usb/cdc.h2
-rw-r--r--include/linux/usb/gadgetfs.h2
-rw-r--r--include/linux/video_decoder.h2
-rw-r--r--include/linux/video_encoder.h2
-rw-r--r--include/linux/videodev.h1
-rw-r--r--include/linux/virtio_blk.h1
-rw-r--r--include/linux/virtio_console.h1
-rw-r--r--include/linux/virtio_net.h1
-rw-r--r--include/linux/wait.h11
-rw-r--r--include/media/v4l2-device.h8
-rw-r--r--include/mtd/inftl-user.h2
-rw-r--r--include/sound/hdsp.h2
-rw-r--r--include/video/aty128.h4
-rw-r--r--include/video/mach64.h24
-rw-r--r--include/video/radeon.h18
-rw-r--r--include/video/sisfb.h2
-rw-r--r--include/video/uvesafb.h2
-rw-r--r--ipc/shm.c8
-rw-r--r--kernel/async.c94
-rw-r--r--kernel/cpuset.c13
-rw-r--r--kernel/fork.c1
-rw-r--r--kernel/hrtimer.c41
-rw-r--r--kernel/irq/chip.c2
-rw-r--r--kernel/irq/numa_migrate.c7
-rw-r--r--kernel/module.c35
-rw-r--r--kernel/power/main.c26
-rw-r--r--kernel/sched.c14
-rw-r--r--kernel/sched_fair.c32
-rw-r--r--kernel/signal.c2
-rw-r--r--kernel/smp.c36
-rw-r--r--kernel/sys.c16
-rw-r--r--kernel/time/tick-common.c26
-rw-r--r--kernel/trace/ftrace.c32
-rw-r--r--kernel/trace/ring_buffer.c15
-rw-r--r--kernel/trace/trace.c5
-rw-r--r--kernel/trace/trace_irqsoff.c1
-rw-r--r--kernel/trace/trace_sched_wakeup.c1
-rw-r--r--kernel/wait.c59
-rw-r--r--mm/memory.c2
-rw-r--r--mm/mlock.c47
-rw-r--r--mm/mmap.c48
-rw-r--r--mm/page-writeback.c21
-rw-r--r--mm/shmem.c2
-rw-r--r--mm/slub.c2
-rw-r--r--net/ipv4/tcp_output.c12
-rw-r--r--net/ipv4/udp.c7
-rw-r--r--net/ipv6/ip6_output.c67
-rw-r--r--net/ipv6/ip6mr.c1
-rw-r--r--net/packet/af_packet.c17
-rw-r--r--net/sunrpc/Kconfig2
-rw-r--r--sound/core/oss/pcm_oss.c2
-rw-r--r--sound/pci/hda/hda_codec.c9
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_proc.c3
-rw-r--r--sound/pci/hda/patch_realtek.c5
-rw-r--r--sound/pci/hda/patch_sigmatel.c2
-rw-r--r--sound/pci/intel8x0.c2
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c2
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.h2
-rw-r--r--sound/soc/codecs/wm8350.c2
-rw-r--r--sound/soc/codecs/wm8990.c3
-rw-r--r--sound/soc/omap/omap-pcm.c5
-rw-r--r--sound/usb/usbaudio.c1
586 files changed, 9633 insertions, 5782 deletions
diff --git a/.mailmap b/.mailmap
index 4e83e7b52d15..a62e6a84fd1e 100644
--- a/.mailmap
+++ b/.mailmap
@@ -92,6 +92,7 @@ Rudolf Marek <R.Marek@sh.cvut.cz>
 Rui Saraiva <rmps@joel.ist.utl.pt>
 Sachin P Sant <ssant@in.ibm.com>
 Sam Ravnborg <sam@mars.ravnborg.org>
+Sascha Hauer <s.hauer@pengutronix.de>
 S.Çağlar Onur <caglar@pardus.org.tr>
 Simon Kelley <simon@thekelleys.org.uk>
 Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
@@ -100,6 +101,7 @@ Tejun Heo <htejun@gmail.com>
 Thomas Graf <tgraf@suug.ch>
 Tony Luck <tony.luck@intel.com>
 Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com>
-Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
 Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
+Uwe Kleine-König <ukl@pengutronix.de>
+Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
 Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
diff --git a/Documentation/block/queue-sysfs.txt b/Documentation/block/queue-sysfs.txt
new file mode 100644
index 000000000000..e164403f60e1
--- /dev/null
+++ b/Documentation/block/queue-sysfs.txt
@@ -0,0 +1,63 @@
+Queue sysfs files
+=================
+
+This text file will detail the queue files that are located in the sysfs tree
+for each block device. Note that stacked devices typically do not export
+any settings, since their queue merely functions are a remapping target.
+These files are the ones found in the /sys/block/xxx/queue/ directory.
+
+Files denoted with a RO postfix are readonly and the RW postfix means
+read-write.
+
+hw_sector_size (RO)
+-------------------
+This is the hardware sector size of the device, in bytes.
+
+max_hw_sectors_kb (RO)
+----------------------
+This is the maximum number of kilobytes supported in a single data transfer.
+
+max_sectors_kb (RW)
+-------------------
+This is the maximum number of kilobytes that the block layer will allow
+for a filesystem request. Must be smaller than or equal to the maximum
+size allowed by the hardware.
+
+nomerges (RW)
+-------------
+This enables the user to disable the lookup logic involved with IO merging
+requests in the block layer. Merging may still occur through a direct
+1-hit cache, since that comes for (almost) free. The IO scheduler will not
+waste cycles doing tree/hash lookups for merges if nomerges is 1. Defaults
+to 0, enabling all merges.
+
+nr_requests (RW)
+----------------
+This controls how many requests may be allocated in the block layer for
+read or write requests. Note that the total allocated number may be twice
+this amount, since it applies only to reads or writes (not the accumulated
+sum).
+
+read_ahead_kb (RW)
+------------------
+Maximum number of kilobytes to read-ahead for filesystems on this block
+device.
+
+rq_affinity (RW)
+----------------
+If this option is enabled, the block layer will migrate request completions
+to the CPU that originally submitted the request. For some workloads
+this provides a significant reduction in CPU cycles due to caching effects.
+
+scheduler (RW)
+--------------
+When read, this file will display the current and available IO schedulers
+for this block device. The currently active IO scheduler will be enclosed
+in [] brackets. Writing an IO scheduler name to this file will switch
+control of this block device to that new IO scheduler. Note that writing
+an IO scheduler name to this file will attempt to load that IO scheduler
+module, if it isn't already present in the system.
+
+
+
+Jens Axboe <jens.axboe@oracle.com>, February 2009
diff --git a/Documentation/cpu-freq/user-guide.txt b/Documentation/cpu-freq/user-guide.txt
index e3443ddcfb89..917918f84fc7 100644
--- a/Documentation/cpu-freq/user-guide.txt
+++ b/Documentation/cpu-freq/user-guide.txt
@@ -195,19 +195,3 @@ scaling_setspeed.		By "echoing" a new frequency into this
 				you can change the speed of the CPU,
 				but only within the limits of
 				scaling_min_freq and scaling_max_freq.
-				
-
-3.2 Deprecated Interfaces
--------------------------
-
-Depending on your kernel configuration, you might find the following 
-cpufreq-related files:
-/proc/cpufreq
-/proc/sys/cpu/*/speed
-/proc/sys/cpu/*/speed-min
-/proc/sys/cpu/*/speed-max
-
-These are files for deprecated interfaces to cpufreq, which offer far
-less functionality. Because of this, these interfaces aren't described
-here.
-
diff --git a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt
index 68ef48839c04..9f8740ca3f3b 100644
--- a/Documentation/filesystems/sysfs-pci.txt
+++ b/Documentation/filesystems/sysfs-pci.txt
@@ -9,6 +9,7 @@ that support it.  For example, a given bus might look like this:
      |   |-- class
      |   |-- config
      |   |-- device
+     |   |-- enable
      |   |-- irq
      |   |-- local_cpus
      |   |-- resource
@@ -32,6 +33,7 @@ files, each with their own function.
        class		   PCI class (ascii, ro)
        config		   PCI config space (binary, rw)
        device		   PCI device (ascii, ro)
+       enable	           Whether the device is enabled (ascii, rw)
        irq		   IRQ number (ascii, ro)
        local_cpus	   nearby CPU mask (cpumask, ro)
        resource		   PCI resource host addresses (ascii, ro)
@@ -57,10 +59,19 @@ used to do actual device programming from userspace.  Note that some platforms
 don't support mmapping of certain resources, so be sure to check the return
 value from any attempted mmap.
 
+The 'enable' file provides a counter that indicates how many times the device 
+has been enabled.  If the 'enable' file currently returns '4', and a '1' is
+echoed into it, it will then return '5'.  Echoing a '0' into it will decrease
+the count.  Even when it returns to 0, though, some of the initialisation
+may not be reversed.  
+
 The 'rom' file is special in that it provides read-only access to the device's
 ROM file, if available.  It's disabled by default, however, so applications
 should write the string "1" to the file to enable it before attempting a read
-call, and disable it following the access by writing "0" to the file.
+call, and disable it following the access by writing "0" to the file.  Note
+that the device must be enabled for a rom read to return data succesfully.
+In the event a driver is not bound to the device, it can be enabled using the
+'enable' file, documented above.
 
 Accessing legacy resources through sysfs
 ----------------------------------------
diff --git a/Documentation/filesystems/ubifs.txt b/Documentation/filesystems/ubifs.txt
index 84da2a4ba25a..12fedb7834c6 100644
--- a/Documentation/filesystems/ubifs.txt
+++ b/Documentation/filesystems/ubifs.txt
@@ -79,13 +79,6 @@ Mount options
 
 (*) == default.
 
-norm_unmount (*)	commit on unmount; the journal is committed
-			when the file-system is unmounted so that the
-			next mount does not have to replay the journal
-			and it becomes very fast;
-fast_unmount		do not commit on unmount; this option makes
-			unmount faster, but the next mount slower
-			because of the need to replay the journal.
 bulk_read		read more in one go to take advantage of flash
 			media that read faster sequentially
 no_bulk_read (*)	do not bulk-read
diff --git a/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt b/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt
new file mode 100644
index 000000000000..8447fd7090d0
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt
@@ -0,0 +1,180 @@
+MPC5200 Device Tree Bindings
+----------------------------
+
+(c) 2006-2009 Secret Lab Technologies Ltd
+Grant Likely <grant.likely@secretlab.ca>
+
+Naming conventions
+------------------
+For mpc5200 on-chip devices, the format for each compatible value is
+<chip>-<device>[-<mode>].  The OS should be able to match a device driver
+to the device based solely on the compatible value.  If two drivers
+match on the compatible list; the 'most compatible' driver should be
+selected.
+
+The split between the MPC5200 and the MPC5200B leaves a bit of a
+conundrum.  How should the compatible property be set up to provide
+maximum compatibility information; but still accurately describe the
+chip?  For the MPC5200; the answer is easy.  Most of the SoC devices
+originally appeared on the MPC5200.  Since they didn't exist anywhere
+else; the 5200 compatible properties will contain only one item;
+"fsl,mpc5200-<device>".
+
+The 5200B is almost the same as the 5200, but not quite.  It fixes
+silicon bugs and it adds a small number of enhancements.  Most of the
+devices either provide exactly the same interface as on the 5200.  A few
+devices have extra functions but still have a backwards compatible mode.
+To express this information as completely as possible, 5200B device trees
+should have two items in the compatible list:
+	compatible = "fsl,mpc5200b-<device>","fsl,mpc5200-<device>";
+
+It is *strongly* recommended that 5200B device trees follow this convention
+(instead of only listing the base mpc5200 item).
+
+ie. ethernet on mpc5200: compatible = "fsl,mpc5200-fec";
+    ethernet on mpc5200b: compatible = "fsl,mpc5200b-fec", "fsl,mpc5200-fec";
+
+Modal devices, like PSCs, also append the configured function to the
+end of the compatible field.  ie. A PSC in i2s mode would specify
+"fsl,mpc5200-psc-i2s", not "fsl,mpc5200-i2s".  This convention is chosen to
+avoid naming conflicts with non-psc devices providing the same
+function.  For example, "fsl,mpc5200-spi" and "fsl,mpc5200-psc-spi" describe
+the mpc5200 simple spi device and a PSC spi mode respectively.
+
+At the time of writing, exact chip may be either 'fsl,mpc5200' or
+'fsl,mpc5200b'.
+
+The soc node
+------------
+This node describes the on chip SOC peripherals.  Every mpc5200 based
+board will have this node, and as such there is a common naming
+convention for SOC devices.
+
+Required properties:
+name			description
+----			-----------
+ranges			Memory range of the internal memory mapped registers.
+			Should be <0 [baseaddr] 0xc000>
+reg			Should be <[baseaddr] 0x100>
+compatible		mpc5200: "fsl,mpc5200-immr"
+			mpc5200b: "fsl,mpc5200b-immr"
+system-frequency	'fsystem' frequency in Hz; XLB, IPB, USB and PCI
+			clocks are derived from the fsystem clock.
+bus-frequency		IPB bus frequency in Hz.  Clock rate
+			used by most of the soc devices.
+
+soc child nodes
+---------------
+Any on chip SOC devices available to Linux must appear as soc5200 child nodes.
+
+Note: The tables below show the value for the mpc5200.  A mpc5200b device
+tree should use the "fsl,mpc5200b-<device>","fsl,mpc5200-<device>" form.
+
+Required soc5200 child nodes:
+name				compatible		Description
+----				----------		-----------
+cdm@<addr>			fsl,mpc5200-cdm		Clock Distribution
+interrupt-controller@<addr>	fsl,mpc5200-pic		need an interrupt
+							controller to boot
+bestcomm@<addr>			fsl,mpc5200-bestcomm	Bestcomm DMA controller
+
+Recommended soc5200 child nodes; populate as needed for your board
+name		compatible		Description
+----		----------		-----------
+timer@<addr>	fsl,mpc5200-gpt		 General purpose timers
+gpio@<addr>	fsl,mpc5200-gpio	 MPC5200 simple gpio controller
+gpio@<addr>	fsl,mpc5200-gpio-wkup	 MPC5200 wakeup gpio controller
+rtc@<addr>	fsl,mpc5200-rtc		 Real time clock
+mscan@<addr>	fsl,mpc5200-mscan	 CAN bus controller
+pci@<addr>	fsl,mpc5200-pci		 PCI bridge
+serial@<addr>	fsl,mpc5200-psc-uart	 PSC in serial mode
+i2s@<addr>	fsl,mpc5200-psc-i2s	 PSC in i2s mode
+ac97@<addr>	fsl,mpc5200-psc-ac97	 PSC in ac97 mode
+spi@<addr>	fsl,mpc5200-psc-spi	 PSC in spi mode
+irda@<addr>	fsl,mpc5200-psc-irda	 PSC in IrDA mode
+spi@<addr>	fsl,mpc5200-spi		 MPC5200 spi device
+ethernet@<addr>	fsl,mpc5200-fec		 MPC5200 ethernet device
+ata@<addr>	fsl,mpc5200-ata		 IDE ATA interface
+i2c@<addr>	fsl,mpc5200-i2c		 I2C controller
+usb@<addr>	fsl,mpc5200-ohci,ohci-be USB controller
+xlb@<addr>	fsl,mpc5200-xlb		 XLB arbitrator
+
+fsl,mpc5200-gpt nodes
+---------------------
+On the mpc5200 and 5200b, GPT0 has a watchdog timer function.  If the board
+design supports the internal wdt, then the device node for GPT0 should
+include the empty property 'fsl,has-wdt'.
+
+An mpc5200-gpt can be used as a single line GPIO controller.  To do so,
+add the following properties to the gpt node:
+	gpio-controller;
+	#gpio-cells = <2>;
+When referencing the GPIO line from another node, the first cell must always
+be zero and the second cell represents the gpio flags and described in the
+gpio device tree binding.
+
+An mpc5200-gpt can be used as a single line edge sensitive interrupt
+controller.  To do so, add the following properties to the gpt node:
+	interrupt-controller;
+	#interrupt-cells = <1>;
+When referencing the IRQ line from another node, the cell represents the
+sense mode; 1 for edge rising, 2 for edge falling.
+
+fsl,mpc5200-psc nodes
+---------------------
+The PSCs should include a cell-index which is the index of the PSC in
+hardware.  cell-index is used to determine which shared SoC registers to
+use when setting up PSC clocking.  cell-index number starts at '0'.  ie:
+	PSC1 has 'cell-index = <0>'
+	PSC4 has 'cell-index = <3>'
+
+PSC in i2s mode:  The mpc5200 and mpc5200b PSCs are not compatible when in
+i2s mode.  An 'mpc5200b-psc-i2s' node cannot include 'mpc5200-psc-i2s' in the
+compatible field.
+
+
+fsl,mpc5200-gpio and fsl,mpc5200-gpio-wkup nodes
+------------------------------------------------
+Each GPIO controller node should have the empty property gpio-controller and
+#gpio-cells set to 2. First cell is the GPIO number which is interpreted
+according to the bit numbers in the GPIO control registers. The second cell
+is for flags which is currently unused.
+
+fsl,mpc5200-fec nodes
+---------------------
+The FEC node can specify one of the following properties to configure
+the MII link:
+- fsl,7-wire-mode - An empty property that specifies the link uses 7-wire
+                    mode instead of MII
+- current-speed   - Specifies that the MII should be configured for a fixed
+                    speed.  This property should contain two cells.  The
+                    first cell specifies the speed in Mbps and the second
+                    should be '0' for half duplex and '1' for full duplex
+- phy-handle      - Contains a phandle to an Ethernet PHY.
+
+Interrupt controller (fsl,mpc5200-pic) node
+-------------------------------------------
+The mpc5200 pic binding splits hardware IRQ numbers into two levels.  The
+split reflects the layout of the PIC hardware itself, which groups
+interrupts into one of three groups; CRIT, MAIN or PERP.  Also, the
+Bestcomm dma engine has it's own set of interrupt sources which are
+cascaded off of peripheral interrupt 0, which the driver interprets as a
+fourth group, SDMA.
+
+The interrupts property for device nodes using the mpc5200 pic consists
+of three cells; <L1 L2 level>
+
+    L1 := [CRIT=0, MAIN=1, PERP=2, SDMA=3]
+    L2 := interrupt number; directly mapped from the value in the
+          "ICTL PerStat, MainStat, CritStat Encoded Register"
+    level := [LEVEL_HIGH=0, EDGE_RISING=1, EDGE_FALLING=2, LEVEL_LOW=3]
+
+For external IRQs, use the following interrupt property values (how to
+specify external interrupts is a frequently asked question):
+External interrupts:
+	external irq0:	interrupts = <0 0 n>;
+	external irq1:	interrupts = <1 1 n>;
+	external irq2:	interrupts = <1 2 n>;
+	external irq3:	interrupts = <1 3 n>;
+'n' is sense (0: level high, 1: edge rising, 2: edge falling 3: level low)
+
diff --git a/Documentation/powerpc/mpc52xx-device-tree-bindings.txt b/Documentation/powerpc/mpc52xx-device-tree-bindings.txt
deleted file mode 100644
index 6f12f1c79c0c..000000000000
--- a/Documentation/powerpc/mpc52xx-device-tree-bindings.txt
+++ /dev/null
@@ -1,277 +0,0 @@
-MPC5200 Device Tree Bindings
-----------------------------
-
-(c) 2006-2007 Secret Lab Technologies Ltd
-Grant Likely <grant.likely at secretlab.ca>
-
-********** DRAFT ***********
-* WARNING: Do not depend on the stability of these bindings just yet.
-* The MPC5200 device tree conventions are still in flux
-* Keep an eye on the linuxppc-dev mailing list for more details
-********** DRAFT ***********
-
-I - Introduction
-================
-Boards supported by the arch/powerpc architecture require device tree be
-passed by the boot loader to the kernel at boot time.  The device tree
-describes what devices are present on the board and how they are
-connected.  The device tree can either be passed as a binary blob (as
-described in Documentation/powerpc/booting-without-of.txt), or passed
-by Open Firmware (IEEE 1275) compatible firmware using an OF compatible
-client interface API.
-
-This document specifies the requirements on the device-tree for mpc5200
-based boards.  These requirements are above and beyond the details
-specified in either the Open Firmware spec or booting-without-of.txt
-
-All new mpc5200-based boards are expected to match this document.  In
-cases where this document is not sufficient to support a new board port,
-this document should be updated as part of adding the new board support.
-
-II - Philosophy
-===============
-The core of this document is naming convention.  The whole point of
-defining this convention is to reduce or eliminate the number of
-special cases required to support a 5200 board.  If all 5200 boards
-follow the same convention, then generic 5200 support code will work
-rather than coding special cases for each new board.
-
-This section tries to capture the thought process behind why the naming
-convention is what it is.
-
-1.  names
----------
-There is strong convention/requirements already established for children
-of the root node.  'cpus' describes the processor cores, 'memory'
-describes memory, and 'chosen' provides boot configuration.  Other nodes
-are added to describe devices attached to the processor local bus.
-
-Following convention already established with other system-on-chip
-processors, 5200 device trees should use the name 'soc5200' for the
-parent node of on chip devices, and the root node should be its parent.
-
-Child nodes are typically named after the configured function.  ie.
-the FEC node is named 'ethernet', and a PSC in uart mode is named 'serial'.
-
-2. device_type property
------------------------
-similar to the node name convention above; the device_type reflects the
-configured function of a device.  ie. 'serial' for a uart and 'spi' for
-an spi controller.  However, while node names *should* reflect the
-configured function, device_type *must* match the configured function
-exactly.
-
-3. compatible property
-----------------------
-Since device_type isn't enough to match devices to drivers, there also
-needs to be a naming convention for the compatible property.  Compatible
-is an list of device descriptions sorted from specific to generic.  For
-the mpc5200, the required format for each compatible value is
-<chip>-<device>[-<mode>].  The OS should be able to match a device driver
-to the device based solely on the compatible value.  If two drivers
-match on the compatible list; the 'most compatible' driver should be
-selected.
-
-The split between the MPC5200 and the MPC5200B leaves a bit of a
-conundrum.  How should the compatible property be set up to provide
-maximum compatibility information; but still accurately describe the
-chip?  For the MPC5200; the answer is easy.  Most of the SoC devices
-originally appeared on the MPC5200.  Since they didn't exist anywhere
-else; the 5200 compatible properties will contain only one item;
-"mpc5200-<device>".
-
-The 5200B is almost the same as the 5200, but not quite.  It fixes
-silicon bugs and it adds a small number of enhancements.  Most of the
-devices either provide exactly the same interface as on the 5200.  A few
-devices have extra functions but still have a backwards compatible mode.
-To express this information as completely as possible, 5200B device trees
-should have two items in the compatible list;
-"mpc5200b-<device>\0mpc5200-<device>".  It is *strongly* recommended
-that 5200B device trees follow this convention (instead of only listing
-the base mpc5200 item).
-
-If another chip appear on the market with one of the mpc5200 SoC
-devices, then the compatible list should include mpc5200-<device>.
-
-ie. ethernet on mpc5200: compatible = "mpc5200-ethernet"
-    ethernet on mpc5200b: compatible = "mpc5200b-ethernet\0mpc5200-ethernet"
-
-Modal devices, like PSCs, also append the configured function to the
-end of the compatible field.  ie. A PSC in i2s mode would specify
-"mpc5200-psc-i2s", not "mpc5200-i2s".  This convention is chosen to
-avoid naming conflicts with non-psc devices providing the same
-function.  For example, "mpc5200-spi" and "mpc5200-psc-spi" describe
-the mpc5200 simple spi device and a PSC spi mode respectively.
-
-If the soc device is more generic and present on other SOCs, the
-compatible property can specify the more generic device type also.
-
-ie. mscan: compatible = "mpc5200-mscan\0fsl,mscan";
-
-At the time of writing, exact chip may be either 'mpc5200' or
-'mpc5200b'.
-
-Device drivers should always try to match as generically as possible.
-
-III - Structure
-===============
-The device tree for an mpc5200 board follows the structure defined in
-booting-without-of.txt with the following additional notes:
-
-0) the root node
-----------------
-Typical root description node; see booting-without-of
-
-1) The cpus node
-----------------
-The cpus node follows the basic layout described in booting-without-of.
-The bus-frequency property holds the XLB bus frequency
-The clock-frequency property holds the core frequency
-
-2) The memory node
-------------------
-Typical memory description node; see booting-without-of.
-
-3) The soc5200 node
--------------------
-This node describes the on chip SOC peripherals.  Every mpc5200 based
-board will have this node, and as such there is a common naming
-convention for SOC devices.
-
-Required properties:
-name			type		description
-----			----		-----------
-device_type		string		must be "soc"
-ranges			int		should be <0 baseaddr baseaddr+10000>
-reg			int		must be <baseaddr 10000>
-compatible		string		mpc5200: "mpc5200-soc"
-					mpc5200b: "mpc5200b-soc\0mpc5200-soc"
-system-frequency	int		Fsystem frequency; source of all
-					other clocks.
-bus-frequency		int		IPB bus frequency in HZ.  Clock rate
-					used by most of the soc devices.
-#interrupt-cells	int		must be <3>.
-
-Recommended properties:
-name			type		description
-----			----		-----------
-model			string		Exact model of the chip;
-					ie: model="fsl,mpc5200"
-revision		string		Silicon revision of chip
-					ie: revision="M08A"
-
-The 'model' and 'revision' properties are *strongly* recommended.  Having
-them presence acts as a bit of a safety net for working around as yet
-undiscovered bugs on one version of silicon.  For example, device drivers
-can use the model and revision properties to decide if a bug fix should
-be turned on.
-
-4) soc5200 child nodes
-----------------------
-Any on chip SOC devices available to Linux must appear as soc5200 child nodes.
-
-Note: The tables below show the value for the mpc5200.  A mpc5200b device
-tree should use the "mpc5200b-<device>\0mpc5200-<device> form.
-
-Required soc5200 child nodes:
-name		device_type		compatible	Description
-----		-----------		----------	-----------
-cdm@<addr>	cdm			mpc5200-cmd	Clock Distribution
-pic@<addr>	interrupt-controller	mpc5200-pic	need an interrupt
-							controller to boot
-bestcomm@<addr>	dma-controller		mpc5200-bestcomm 5200 pic also requires
-							 the bestcomm device
-
-Recommended soc5200 child nodes; populate as needed for your board
-name		device_type	compatible	  Description
-----		-----------	----------	  -----------
-gpt@<addr>	gpt		fsl,mpc5200-gpt	  General purpose timers
-gpt@<addr>	gpt		fsl,mpc5200-gpt-gpio	General purpose
-							timers in GPIO mode
-gpio@<addr>			fsl,mpc5200-gpio	MPC5200 simple gpio
-							controller
-gpio@<addr>			fsl,mpc5200-gpio-wkup	MPC5200 wakeup gpio
-							controller
-rtc@<addr>	rtc		mpc5200-rtc	  Real time clock
-mscan@<addr>	mscan		mpc5200-mscan	  CAN bus controller
-pci@<addr>	pci		mpc5200-pci	  PCI bridge
-serial@<addr>	serial		mpc5200-psc-uart  PSC in serial mode
-i2s@<addr>	sound		mpc5200-psc-i2s	  PSC in i2s mode
-ac97@<addr>	sound		mpc5200-psc-ac97  PSC in ac97 mode
-spi@<addr>	spi		mpc5200-psc-spi	  PSC in spi mode
-irda@<addr>	irda		mpc5200-psc-irda  PSC in IrDA mode
-spi@<addr>	spi		mpc5200-spi	  MPC5200 spi device
-ethernet@<addr>	network		mpc5200-fec	  MPC5200 ethernet device
-ata@<addr>	ata		mpc5200-ata	  IDE ATA interface
-i2c@<addr>	i2c		mpc5200-i2c	  I2C controller
-usb@<addr>	usb-ohci-be	mpc5200-ohci,ohci-be	USB controller
-xlb@<addr>	xlb		mpc5200-xlb	  XLB arbitrator
-
-Important child node properties
-name		type		description
-----		----		-----------
-cell-index	int		When multiple devices are present, is the
-				index of the device in the hardware (ie. There
-				are 6 PSC on the 5200 numbered PSC1 to PSC6)
-				    PSC1 has 'cell-index = <0>'
-				    PSC4 has 'cell-index = <3>'
-
-5) General Purpose Timer nodes (child of soc5200 node)
-On the mpc5200 and 5200b, GPT0 has a watchdog timer function.  If the board
-design supports the internal wdt, then the device node for GPT0 should
-include the empty property 'fsl,has-wdt'.
-
-6) PSC nodes (child of soc5200 node)
-PSC nodes can define the optional 'port-number' property to force assignment
-order of serial ports.  For example, PSC5 might be physically connected to
-the port labeled 'COM1' and PSC1 wired to 'COM1'.  In this case, PSC5 would
-have a "port-number = <0>" property, and PSC1 would have "port-number = <1>".
-
-PSC in i2s mode:  The mpc5200 and mpc5200b PSCs are not compatible when in
-i2s mode.  An 'mpc5200b-psc-i2s' node cannot include 'mpc5200-psc-i2s' in the
-compatible field.
-
-7) GPIO controller nodes
-Each GPIO controller node should have the empty property gpio-controller and
-#gpio-cells set to 2. First cell is the GPIO number which is interpreted
-according to the bit numbers in the GPIO control registers. The second cell
-is for flags which is currently unsused.
-
-8) FEC nodes
-The FEC node can specify one of the following properties to configure
-the MII link:
-"fsl,7-wire-mode" - An empty property that specifies the link uses 7-wire
-                    mode instead of MII
-"current-speed"   - Specifies that the MII should be configured for a fixed
-                    speed.  This property should contain two cells.  The
-                    first cell specifies the speed in Mbps and the second
-                    should be '0' for half duplex and '1' for full duplex
-"phy-handle"      - Contains a phandle to an Ethernet PHY.
-
-IV - Extra Notes
-================
-
-1. Interrupt mapping
---------------------
-The mpc5200 pic driver splits hardware IRQ numbers into two levels.  The
-split reflects the layout of the PIC hardware itself, which groups
-interrupts into one of three groups; CRIT, MAIN or PERP.  Also, the
-Bestcomm dma engine has it's own set of interrupt sources which are
-cascaded off of peripheral interrupt 0, which the driver interprets as a
-fourth group, SDMA.
-
-The interrupts property for device nodes using the mpc5200 pic consists
-of three cells; <L1 L2 level>
-
-    L1 := [CRIT=0, MAIN=1, PERP=2, SDMA=3]
-    L2 := interrupt number; directly mapped from the value in the
-          "ICTL PerStat, MainStat, CritStat Encoded Register"
-    level := [LEVEL_HIGH=0, EDGE_RISING=1, EDGE_FALLING=2, LEVEL_LOW=3]
-
-2. Shared registers
--------------------
-Some SoC devices share registers between them.  ie. the i2c devices use
-a single clock control register, and almost all device are affected by
-the port_config register.  Devices which need to manipulate shared regs
-should look to the parent SoC node.  The soc node is responsible
-for arbitrating all shared register access.
diff --git a/Documentation/video4linux/v4lgrab.c b/Documentation/video4linux/v4lgrab.c
index 079b628481cf..d6e70bef8ad0 100644
--- a/Documentation/video4linux/v4lgrab.c
+++ b/Documentation/video4linux/v4lgrab.c
@@ -4,12 +4,21 @@
  *
  *	Compile with:
  *		gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab
- *      Use as:
- *              v4lgrab >image.ppm
+ *	Use as:
+ *		v4lgrab >image.ppm
  *
  *	Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org>
- *      Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
- *      with minor modifications (Dave Forrest, drf5n@virginia.edu).
+ *	Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
+ *	with minor modifications (Dave Forrest, drf5n@virginia.edu).
+ *
+ *
+ *	For some cameras you may need to pre-load libv4l to perform
+ *	the necessary decompression, e.g.:
+ *
+ *	export LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so
+ *	./v4lgrab >image.ppm
+ *
+ *	see http://hansdegoede.livejournal.com/3636.html for details.
  *
  */
 
@@ -24,7 +33,7 @@
 #include <linux/types.h>
 #include <linux/videodev.h>
 
-#define FILE "/dev/video0"
+#define VIDEO_DEV "/dev/video0"
 
 /* Stole this from tvset.c */
 
@@ -90,7 +99,7 @@ int get_brightness_adj(unsigned char *image, long size, int *brightness) {
 
 int main(int argc, char ** argv)
 {
-  int fd = open(FILE, O_RDONLY), f;
+  int fd = open(VIDEO_DEV, O_RDONLY), f;
   struct video_capability cap;
   struct video_window win;
   struct video_picture vpic;
@@ -100,13 +109,13 @@ int main(int argc, char ** argv)
   unsigned int i, src_depth;
 
   if (fd < 0) {
-    perror(FILE);
+    perror(VIDEO_DEV);
     exit(1);
   }
 
   if (ioctl(fd, VIDIOCGCAP, &cap) < 0) {
     perror("VIDIOGCAP");
-    fprintf(stderr, "(" FILE " not a video4linux device?)\n");
+    fprintf(stderr, "(" VIDEO_DEV " not a video4linux device?)\n");
     close(fd);
     exit(1);
   }
diff --git a/MAINTAINERS b/MAINTAINERS
index 474ec0c53272..0ea3a6d98714 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -911,7 +911,7 @@ S:	Maintained
 BLACKFIN ARCHITECTURE
 P:	Bryan Wu
 M:	cooloney@kernel.org
-L:	uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+L:	uclinux-dist-devel@blackfin.uclinux.org
 W:	http://blackfin.uclinux.org
 S:	Supported
 
@@ -1021,6 +1021,14 @@ M:	mb@bu3sch.de
 W:	http://bu3sch.de/btgpio.php
 S:	Maintained
 
+BTRFS FILE SYSTEM
+P:	Chris Mason
+M:	chris.mason@oracle.com
+L:	linux-btrfs@vger.kernel.org
+W:	http://btrfs.wiki.kernel.org/
+T:	git kernel.org:/pub/scm/linux/kernel/git/mason/btrfs-unstable.git
+S:	Maintained
+
 BTTV VIDEO4LINUX DRIVER
 P:	Mauro Carvalho Chehab
 M:	mchehab@infradead.org
@@ -2212,7 +2220,7 @@ P:	Sean Hefty
 M:	sean.hefty@intel.com
 P:	Hal Rosenstock
 M:	hal.rosenstock@gmail.com
-L:	general@lists.openfabrics.org
+L:	general@lists.openfabrics.org (moderated for non-subscribers)
 W:	http://www.openib.org/
 T:	git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
 S:	Supported
@@ -4841,6 +4849,7 @@ P:	Ingo Molnar
 M:	mingo@redhat.com
 P:	H. Peter Anvin
 M:	hpa@zytor.com
+M:	x86@kernel.org
 L:	linux-kernel@vger.kernel.org
 T:	git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
 S:	Maintained
diff --git a/Makefile b/Makefile
index 7715b2c14fb4..681c1d23b4d4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 29
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
 NAME = Erotic Pickled Herring
 
 # *DOCUMENTATION*
diff --git a/arch/alpha/include/asm/bug.h b/arch/alpha/include/asm/bug.h
index 7b85b7c93709..1720c8ad86fe 100644
--- a/arch/alpha/include/asm/bug.h
+++ b/arch/alpha/include/asm/bug.h
@@ -8,12 +8,12 @@
 
 /* ??? Would be nice to use .gprel32 here, but we can't be sure that the
    function loaded the GP, so this could fail in modules.  */
-#define BUG()	{							\
+#define BUG()	do {							\
 	__asm__ __volatile__(						\
 		"call_pal %0  # bugchk\n\t"				\
 		".long %1\n\t.8byte %2"					\
 		: : "i"(PAL_bugchk), "i"(__LINE__), "i"(__FILE__));	\
-	for ( ; ; ); }
+	for ( ; ; ); } while (0)
 
 #define HAVE_ARCH_BUG
 #endif
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 77b047475539..85040cfeb5e5 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -650,6 +650,7 @@ ENTRY(fp_enter)
 no_fp:	mov	pc, lr
 
 __und_usr_unknown:
+	enable_irq
 	mov	r0, sp
 	adr	lr, ret_from_exception
 	b	do_undefinstr
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 06269ea375c5..49a6ba926c2b 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -136,7 +136,7 @@ ENTRY(mcount)
 	ldmia sp!, {r0-r3, pc}
 
 trace:
-	ldr r1, [fp, #-4]
+	ldr r1, [fp, #-4]			@ lr of instrumented routine
 	mov r0, lr
 	sub r0, r0, #MCOUNT_INSN_SIZE
 	mov lr, pc
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 4bb723eadad1..45eacb5a2ecd 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -101,7 +101,7 @@ unlock:
 /* Handle bad interrupts */
 static struct irq_desc bad_irq_desc = {
 	.handle_irq = handle_bad_irq,
-	.lock = SPIN_LOCK_UNLOCKED
+	.lock = __SPIN_LOCK_UNLOCKED(bad_irq_desc.lock),
 };
 
 #ifdef CONFIG_CPUMASK_OFFSTACK
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c
index c2a96e3965a6..e61967dde9a1 100644
--- a/arch/arm/mach-msm/board-halibut.c
+++ b/arch/arm/mach-msm/board-halibut.c
@@ -27,6 +27,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/flash.h>
 
+#include <mach/irqs.h>
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
 
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 77382d8b6b2f..ba5d7c08dc17 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -181,7 +181,7 @@ void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
 		}
 		size = OMAP1_MMC_SIZE;
 
-		omap_mmc_add(i, base, size, irq, mmc_data[i]);
+		omap_mmc_add("mmci-omap", i, base, size, irq, mmc_data[i]);
 	};
 }
 
diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
index ca7a0cc1707c..575ba31295cf 100644
--- a/arch/arm/mach-omap1/mcbsp.c
+++ b/arch/arm/mach-omap1/mcbsp.c
@@ -28,81 +28,8 @@
 #define DPS_RSTCT2_PER_EN	(1 << 0)
 #define DSP_RSTCT2_WD_PER_EN	(1 << 1)
 
-struct mcbsp_internal_clk {
-	struct clk clk;
-	struct clk **childs;
-	int n_childs;
-};
-
 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
-static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk)
-{
-	const char *clk_names[] = { "dsp_ck", "api_ck", "dspxor_ck" };
-	int i;
-
-	mclk->n_childs = ARRAY_SIZE(clk_names);
-	mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *),
-				GFP_KERNEL);
-
-	for (i = 0; i < mclk->n_childs; i++) {
-		/* We fake a platform device to get correct device id */
-		struct platform_device pdev;
-
-		pdev.dev.bus = &platform_bus_type;
-		pdev.id = mclk->clk.id;
-		mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]);
-		if (IS_ERR(mclk->childs[i]))
-			printk(KERN_ERR "Could not get clock %s (%d).\n",
-				clk_names[i], mclk->clk.id);
-	}
-}
-
-static int omap_mcbsp_clk_enable(struct clk *clk)
-{
-	struct mcbsp_internal_clk *mclk = container_of(clk,
-					struct mcbsp_internal_clk, clk);
-	int i;
-
-	for (i = 0; i < mclk->n_childs; i++)
-		clk_enable(mclk->childs[i]);
-	return 0;
-}
-
-static void omap_mcbsp_clk_disable(struct clk *clk)
-{
-	struct mcbsp_internal_clk *mclk = container_of(clk,
-					struct mcbsp_internal_clk, clk);
-	int i;
-
-	for (i = 0; i < mclk->n_childs; i++)
-		clk_disable(mclk->childs[i]);
-}
-
-static struct mcbsp_internal_clk omap_mcbsp_clks[] = {
-	{
-		.clk = {
-			.name 		= "mcbsp_clk",
-			.id		= 1,
-			.enable		= omap_mcbsp_clk_enable,
-			.disable	= omap_mcbsp_clk_disable,
-		},
-	},
-	{
-		.clk = {
-			.name 		= "mcbsp_clk",
-			.id		= 3,
-			.enable		= omap_mcbsp_clk_enable,
-			.disable	= omap_mcbsp_clk_disable,
-		},
-	},
-};
-
-#define omap_mcbsp_clks_size	ARRAY_SIZE(omap_mcbsp_clks)
-#else
-#define omap_mcbsp_clks_size	0
-static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks;
-static inline void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk)
-{ }
+const char *clk_names[] = { "dsp_ck", "api_ck", "dspxor_ck" };
 #endif
 
 static void omap1_mcbsp_request(unsigned int id)
@@ -167,8 +94,9 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
 		.rx_irq		= INT_McBSP1RX,
 		.tx_irq		= INT_McBSP1TX,
 		.ops		= &omap1_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
-		},
+		.clk_names	= clk_names,
+		.num_clks	= 3,
+	},
 	{
 		.phys_base	= OMAP1510_MCBSP2_BASE,
 		.dma_rx_sync	= OMAP_DMA_MCBSP2_RX,
@@ -184,7 +112,8 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
 		.rx_irq		= INT_McBSP3RX,
 		.tx_irq		= INT_McBSP3TX,
 		.ops		= &omap1_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 3,
 	},
 };
 #define OMAP15XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap15xx_mcbsp_pdata)
@@ -202,7 +131,8 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
 		.rx_irq		= INT_McBSP1RX,
 		.tx_irq		= INT_McBSP1TX,
 		.ops		= &omap1_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 3,
 	},
 	{
 		.phys_base	= OMAP1610_MCBSP2_BASE,
@@ -219,7 +149,8 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
 		.rx_irq		= INT_McBSP3RX,
 		.tx_irq		= INT_McBSP3TX,
 		.ops		= &omap1_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 3,
 	},
 };
 #define OMAP16XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap16xx_mcbsp_pdata)
@@ -230,15 +161,6 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
 
 int __init omap1_mcbsp_init(void)
 {
-	int i;
-
-	for (i = 0; i < omap_mcbsp_clks_size; i++) {
-		if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
-			omap_mcbsp_clk_init(&omap_mcbsp_clks[i]);
-			clk_register(&omap_mcbsp_clks[i].clk);
-		}
-	}
-
 	if (cpu_is_omap730())
 		omap_mcbsp_count = OMAP730_MCBSP_PDATA_SZ;
 	if (cpu_is_omap15xx())
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 9d7216ff6c9f..ce03fa750775 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -421,6 +421,7 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
 			int nr_controllers)
 {
 	int i;
+	char *name;
 
 	for (i = 0; i < nr_controllers; i++) {
 		unsigned long base, size;
@@ -450,12 +451,14 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
 			continue;
 		}
 
-		if (cpu_is_omap2420())
+		if (cpu_is_omap2420()) {
 			size = OMAP2420_MMC_SIZE;
-		else
+			name = "mmci-omap";
+		} else {
 			size = HSMMC_SIZE;
-
-		omap_mmc_add(i, base, size, irq, mmc_data[i]);
+			name = "mmci-omap-hs";
+		}
+		omap_mmc_add(name, i, base, size, irq, mmc_data[i]);
 	};
 }
 
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index b0f8e7d62798..b52a02fc7cd6 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -172,9 +172,13 @@ void __init omap34xx_check_revision(void)
 			omap_revision = OMAP3430_REV_ES3_0;
 			rev_name = "ES3.0";
 			break;
+		case 4:
+			omap_revision = OMAP3430_REV_ES3_1;
+			rev_name = "ES3.1";
+			break;
 		default:
 			/* Use the latest known revision as default */
-			omap_revision = OMAP3430_REV_ES3_0;
+			omap_revision = OMAP3430_REV_ES3_1;
 			rev_name = "Unknown revision\n";
 		}
 	}
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 636e2821af7d..9ba20d985dda 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -134,6 +134,7 @@ static struct irq_chip omap_irq_chip = {
 	.ack	= omap_mask_ack_irq,
 	.mask	= omap_mask_irq,
 	.unmask	= omap_unmask_irq,
+	.disable = omap_mask_irq,
 };
 
 static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index e20023c9d15d..a9e631fc1134 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -24,106 +24,7 @@
 #include <mach/cpu.h>
 #include <mach/mcbsp.h>
 
-struct mcbsp_internal_clk {
-	struct clk clk;
-	struct clk **childs;
-	int n_childs;
-};
-
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
-static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk)
-{
-	const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" };
-	int i;
-
-	mclk->n_childs = ARRAY_SIZE(clk_names);
-	mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *),
-				GFP_KERNEL);
-
-	for (i = 0; i < mclk->n_childs; i++) {
-		/* We fake a platform device to get correct device id */
-		struct platform_device pdev;
-
-		pdev.dev.bus = &platform_bus_type;
-		pdev.id = mclk->clk.id;
-		mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]);
-		if (IS_ERR(mclk->childs[i]))
-			printk(KERN_ERR "Could not get clock %s (%d).\n",
-				clk_names[i], mclk->clk.id);
-	}
-}
-
-static int omap_mcbsp_clk_enable(struct clk *clk)
-{
-	struct mcbsp_internal_clk *mclk = container_of(clk,
-					struct mcbsp_internal_clk, clk);
-	int i;
-
-	for (i = 0; i < mclk->n_childs; i++)
-		clk_enable(mclk->childs[i]);
-	return 0;
-}
-
-static void omap_mcbsp_clk_disable(struct clk *clk)
-{
-	struct mcbsp_internal_clk *mclk = container_of(clk,
-					struct mcbsp_internal_clk, clk);
-	int i;
-
-	for (i = 0; i < mclk->n_childs; i++)
-		clk_disable(mclk->childs[i]);
-}
-
-static struct mcbsp_internal_clk omap_mcbsp_clks[] = {
-	{
-		.clk = {
-			.name 		= "mcbsp_clk",
-			.id		= 1,
-			.enable		= omap_mcbsp_clk_enable,
-			.disable	= omap_mcbsp_clk_disable,
-		},
-	},
-	{
-		.clk = {
-			.name 		= "mcbsp_clk",
-			.id		= 2,
-			.enable		= omap_mcbsp_clk_enable,
-			.disable	= omap_mcbsp_clk_disable,
-		},
-	},
-	{
-		.clk = {
-			.name		= "mcbsp_clk",
-			.id		= 3,
-			.enable		= omap_mcbsp_clk_enable,
-			.disable	= omap_mcbsp_clk_disable,
-		},
-	},
-	{
-		.clk = {
-			.name		= "mcbsp_clk",
-			.id		= 4,
-			.enable		= omap_mcbsp_clk_enable,
-			.disable	= omap_mcbsp_clk_disable,
-		},
-	},
-	{
-		.clk = {
-			.name		= "mcbsp_clk",
-			.id		= 5,
-			.enable		= omap_mcbsp_clk_enable,
-			.disable	= omap_mcbsp_clk_disable,
-		},
-	},
-};
-
-#define omap_mcbsp_clks_size	ARRAY_SIZE(omap_mcbsp_clks)
-#else
-#define omap_mcbsp_clks_size	0
-static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks;
-static inline void omap_mcbsp_clk_init(struct clk *clk)
-{ }
-#endif
+const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" };
 
 static void omap2_mcbsp2_mux_setup(void)
 {
@@ -156,7 +57,8 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
 		.rx_irq		= INT_24XX_MCBSP1_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP1_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP24XX_MCBSP2_BASE,
@@ -165,7 +67,8 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
 		.rx_irq		= INT_24XX_MCBSP2_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP2_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 2,
 	},
 };
 #define OMAP2420_MCBSP_PDATA_SZ		ARRAY_SIZE(omap2420_mcbsp_pdata)
@@ -183,7 +86,8 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
 		.rx_irq		= INT_24XX_MCBSP1_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP1_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP24XX_MCBSP2_BASE,
@@ -192,7 +96,8 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
 		.rx_irq		= INT_24XX_MCBSP2_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP2_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP2430_MCBSP3_BASE,
@@ -201,7 +106,8 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
 		.rx_irq		= INT_24XX_MCBSP3_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP3_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP2430_MCBSP4_BASE,
@@ -210,7 +116,8 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
 		.rx_irq		= INT_24XX_MCBSP4_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP4_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP2430_MCBSP5_BASE,
@@ -219,7 +126,8 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
 		.rx_irq		= INT_24XX_MCBSP5_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP5_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 2,
 	},
 };
 #define OMAP2430_MCBSP_PDATA_SZ		ARRAY_SIZE(omap2430_mcbsp_pdata)
@@ -237,7 +145,8 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
 		.rx_irq		= INT_24XX_MCBSP1_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP1_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP34XX_MCBSP2_BASE,
@@ -246,7 +155,8 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
 		.rx_irq		= INT_24XX_MCBSP2_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP2_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP34XX_MCBSP3_BASE,
@@ -255,7 +165,8 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
 		.rx_irq		= INT_24XX_MCBSP3_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP3_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP34XX_MCBSP4_BASE,
@@ -264,7 +175,8 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
 		.rx_irq		= INT_24XX_MCBSP4_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP4_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 2,
 	},
 	{
 		.phys_base	= OMAP34XX_MCBSP5_BASE,
@@ -273,7 +185,8 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
 		.rx_irq		= INT_24XX_MCBSP5_IRQ_RX,
 		.tx_irq		= INT_24XX_MCBSP5_IRQ_TX,
 		.ops		= &omap2_mcbsp_ops,
-		.clk_name	= "mcbsp_clk",
+		.clk_names	= clk_names,
+		.num_clks	= 2,
 	},
 };
 #define OMAP34XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap34xx_mcbsp_pdata)
@@ -284,14 +197,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
 
 static int __init omap2_mcbsp_init(void)
 {
-	int i;
-
-	for (i = 0; i < omap_mcbsp_clks_size; i++) {
-		/* Once we call clk_get inside init, we do not register it */
-		omap_mcbsp_clk_init(&omap_mcbsp_clks[i]);
-		clk_register(&omap_mcbsp_clks[i].clk);
-	}
-
 	if (cpu_is_omap2420())
 		omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ;
 	if (cpu_is_omap2430())
diff --git a/arch/arm/mach-omap2/sleep24xx.S b/arch/arm/mach-omap2/sleep24xx.S
index 43336b93b21c..bf9e96105e11 100644
--- a/arch/arm/mach-omap2/sleep24xx.S
+++ b/arch/arm/mach-omap2/sleep24xx.S
@@ -93,9 +93,8 @@ ENTRY(omap24xx_cpu_suspend)
 	orr	r4, r4, #0x40		@ enable self refresh on idle req
 	mov	r5, #0x2000		@ set delay (DPLL relock + DLL relock)
 	str	r4, [r2]		@ make it so
-	mov	r2, #0
 	nop
-	mcr	p15, 0, r2, c7, c0, 4	@ wait for interrupt
+	mcr	p15, 0, r3, c7, c0, 4	@ wait for interrupt
 	nop
 loop:
 	subs	r5, r5, #0x1		@ awake, wait just a bit
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index ae6036300f60..9fc13a2cc3f4 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -118,7 +118,8 @@ static void __init omap2_gp_clockevent_init(void)
 	clockevent_gpt.max_delta_ns =
 		clockevent_delta2ns(0xffffffff, &clockevent_gpt);
 	clockevent_gpt.min_delta_ns =
-		clockevent_delta2ns(1, &clockevent_gpt);
+		clockevent_delta2ns(3, &clockevent_gpt);
+		/* Timer internal resynch latency. */
 
 	clockevent_gpt.cpumask = cpumask_of(0);
 	clockevents_register_device(&clockevent_gpt);
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index c1fbd5b5f9c4..23cfdd593954 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -289,7 +289,7 @@ static struct platform_device sa11x0pcmcia_device = {
 };
 
 static struct platform_device sa11x0mtd_device = {
-	.name		= "flash",
+	.name		= "sa1100-mtd",
 	.id		= -1,
 };
 
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 81d0b8772de3..bc0099d5ae85 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -66,7 +66,10 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
 	 * fault (ie, is old), we can safely ignore any issues.
 	 */
 	if (ret && (pte_val(entry) & L_PTE_MT_MASK) != shared_pte_mask) {
-		flush_cache_page(vma, address, pte_pfn(entry));
+		unsigned long pfn = pte_pfn(entry);
+		flush_cache_page(vma, address, pfn);
+		outer_flush_range((pfn << PAGE_SHIFT),
+				  (pfn << PAGE_SHIFT) + PAGE_SIZE);
 		pte_val(entry) &= ~L_PTE_MT_MASK;
 		pte_val(entry) |= shared_pte_mask;
 		set_pte_at(vma->vm_mm, address, pte, entry);
diff --git a/arch/arm/plat-mxc/include/mach/mmc.h b/arch/arm/plat-mxc/include/mach/mmc.h
new file mode 100644
index 000000000000..de2128dada5c
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mmc.h
@@ -0,0 +1,36 @@
+#ifndef ASMARM_ARCH_MMC_H
+#define ASMARM_ARCH_MMC_H
+
+#include <linux/mmc/host.h>
+
+struct device;
+
+/* board specific SDHC data, optional.
+ * If not present, a writable card with 3,3V is assumed.
+ */
+struct imxmmc_platform_data {
+	/* Return values for the get_ro callback should be:
+	 *   0 for a read/write card
+	 *   1 for a read-only card
+	 *   -ENOSYS when not supported (equal to NULL callback)
+	 *   or a negative errno value when something bad happened
+	 */
+	int (*get_ro)(struct device *);
+
+	/* board specific hook to (de)initialize the SD slot.
+	 * The board code can call 'handler' on a card detection
+	 * change giving data as argument.
+	 */
+	int (*init)(struct device *dev, irq_handler_t handler, void *data);
+	void (*exit)(struct device *dev, void *data);
+
+	/* available voltages. If not given, assume
+	 * MMC_VDD_32_33 | MMC_VDD_33_34
+	 */
+	unsigned int ocr_avail;
+
+	/* adjust slot voltage */
+	void (*setpower)(struct device *, unsigned int vdd);
+};
+
+#endif
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index ac15c23fd5da..208dbb121f47 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -200,14 +200,15 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
 /*
  * Register MMC devices. Called from mach-omap1 and mach-omap2 device init.
  */
-int __init omap_mmc_add(int id, unsigned long base, unsigned long size,
-		unsigned int irq, struct omap_mmc_platform_data *data)
+int __init omap_mmc_add(const char *name, int id, unsigned long base,
+				unsigned long size, unsigned int irq,
+				struct omap_mmc_platform_data *data)
 {
 	struct platform_device *pdev;
 	struct resource res[OMAP_MMC_NR_RES];
 	int ret;
 
-	pdev = platform_device_alloc("mmci-omap", id);
+	pdev = platform_device_alloc(name, id);
 	if (!pdev)
 		return -ENOMEM;
 
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index e77373c39f8c..47ec77af4ccb 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -709,6 +709,7 @@ int omap_request_dma(int dev_id, const char *dev_name,
 	chan->dev_name = dev_name;
 	chan->callback = callback;
 	chan->data = data;
+	chan->flags = 0;
 
 #ifndef CONFIG_ARCH_OMAP1
 	if (cpu_class_is_omap2()) {
@@ -1888,11 +1889,11 @@ static int omap2_dma_handle_ch(int ch)
 		status = dma_read(CSR(ch));
 	}
 
+	dma_write(status, CSR(ch));
+
 	if (likely(dma_chan[ch].callback != NULL))
 		dma_chan[ch].callback(ch, status, dma_chan[ch].data);
 
-	dma_write(status, CSR(ch));
-
 	return 0;
 }
 
diff --git a/arch/arm/plat-omap/include/mach/cpu.h b/arch/arm/plat-omap/include/mach/cpu.h
index b2062f1175de..a8e1178a9468 100644
--- a/arch/arm/plat-omap/include/mach/cpu.h
+++ b/arch/arm/plat-omap/include/mach/cpu.h
@@ -339,6 +339,7 @@ IS_OMAP_TYPE(3430, 0x3430)
 #define OMAP3430_REV_ES2_0	0x34301034
 #define OMAP3430_REV_ES2_1	0x34302034
 #define OMAP3430_REV_ES3_0	0x34303034
+#define OMAP3430_REV_ES3_1	0x34304034
 
 /*
  * omap_chip bits
diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h
index eef873db3d48..113c2466c86a 100644
--- a/arch/arm/plat-omap/include/mach/mcbsp.h
+++ b/arch/arm/plat-omap/include/mach/mcbsp.h
@@ -344,7 +344,8 @@ struct omap_mcbsp_platform_data {
 	u8 dma_rx_sync, dma_tx_sync;
 	u16 rx_irq, tx_irq;
 	struct omap_mcbsp_ops *ops;
-	char const *clk_name;
+	char const **clk_names;
+	int num_clks;
 };
 
 struct omap_mcbsp {
@@ -376,7 +377,8 @@ struct omap_mcbsp {
 	/* Protect the field .free, while checking if the mcbsp is in use */
 	spinlock_t lock;
 	struct omap_mcbsp_platform_data *pdata;
-	struct clk *clk;
+	struct clk **clks;
+	int num_clks;
 };
 extern struct omap_mcbsp **mcbsp_ptr;
 extern int omap_mcbsp_count;
diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h
index 031250f02805..73a9e15031b1 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -115,8 +115,9 @@ void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
 				int nr_controllers);
 void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
 				int nr_controllers);
-int omap_mmc_add(int id, unsigned long base, unsigned long size,
-			unsigned int irq, struct omap_mmc_platform_data *data);
+int omap_mmc_add(const char *name, int id, unsigned long base,
+				unsigned long size, unsigned int irq,
+				struct omap_mmc_platform_data *data);
 #else
 static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
 				int nr_controllers)
@@ -126,8 +127,9 @@ static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
 				int nr_controllers)
 {
 }
-static inline int omap_mmc_add(int id, unsigned long base, unsigned long size,
-		unsigned int irq, struct omap_mmc_platform_data *data)
+static inline int omap_mmc_add(const char *name, int id, unsigned long base,
+				unsigned long size, unsigned int irq,
+				struct omap_mmc_platform_data *data)
 {
 	return 0;
 }
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index f2401a831f99..e5842e30e534 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -214,6 +214,7 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type);
 int omap_mcbsp_request(unsigned int id)
 {
 	struct omap_mcbsp *mcbsp;
+	int i;
 	int err;
 
 	if (!omap_mcbsp_check_valid_id(id)) {
@@ -225,7 +226,8 @@ int omap_mcbsp_request(unsigned int id)
 	if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
 		mcbsp->pdata->ops->request(id);
 
-	clk_enable(mcbsp->clk);
+	for (i = 0; i < mcbsp->num_clks; i++)
+		clk_enable(mcbsp->clks[i]);
 
 	spin_lock(&mcbsp->lock);
 	if (!mcbsp->free) {
@@ -276,6 +278,7 @@ EXPORT_SYMBOL(omap_mcbsp_request);
 void omap_mcbsp_free(unsigned int id)
 {
 	struct omap_mcbsp *mcbsp;
+	int i;
 
 	if (!omap_mcbsp_check_valid_id(id)) {
 		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
@@ -286,7 +289,8 @@ void omap_mcbsp_free(unsigned int id)
 	if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
 		mcbsp->pdata->ops->free(id);
 
-	clk_disable(mcbsp->clk);
+	for (i = mcbsp->num_clks - 1; i >= 0; i--)
+		clk_disable(mcbsp->clks[i]);
 
 	spin_lock(&mcbsp->lock);
 	if (mcbsp->free) {
@@ -872,6 +876,7 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
 	struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
 	struct omap_mcbsp *mcbsp;
 	int id = pdev->id - 1;
+	int i;
 	int ret = 0;
 
 	if (!pdata) {
@@ -916,14 +921,25 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
 	mcbsp->dma_rx_sync = pdata->dma_rx_sync;
 	mcbsp->dma_tx_sync = pdata->dma_tx_sync;
 
-	if (pdata->clk_name)
-		mcbsp->clk = clk_get(&pdev->dev, pdata->clk_name);
-	if (IS_ERR(mcbsp->clk)) {
-		dev_err(&pdev->dev,
-			"Invalid clock configuration for McBSP%d.\n",
-			mcbsp->id);
-		ret = PTR_ERR(mcbsp->clk);
-		goto err_clk;
+	if (pdata->num_clks) {
+		mcbsp->num_clks = pdata->num_clks;
+		mcbsp->clks = kzalloc(mcbsp->num_clks * sizeof(struct clk *),
+					GFP_KERNEL);
+		if (!mcbsp->clks) {
+			ret = -ENOMEM;
+			goto exit;
+		}
+		for (i = 0; i < mcbsp->num_clks; i++) {
+			mcbsp->clks[i] = clk_get(&pdev->dev, pdata->clk_names[i]);
+			if (IS_ERR(mcbsp->clks[i])) {
+				dev_err(&pdev->dev,
+					"Invalid %s configuration for McBSP%d.\n",
+					pdata->clk_names[i], mcbsp->id);
+				ret = PTR_ERR(mcbsp->clks[i]);
+				goto err_clk;
+			}
+		}
+
 	}
 
 	mcbsp->pdata = pdata;
@@ -932,6 +948,9 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
 	return 0;
 
 err_clk:
+	while (i--)
+		clk_put(mcbsp->clks[i]);
+	kfree(mcbsp->clks);
 	iounmap(mcbsp->io_base);
 err_ioremap:
 	mcbsp->free = 0;
@@ -942,6 +961,7 @@ exit:
 static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
 {
 	struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
+	int i;
 
 	platform_set_drvdata(pdev, NULL);
 	if (mcbsp) {
@@ -950,12 +970,18 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
 				mcbsp->pdata->ops->free)
 			mcbsp->pdata->ops->free(mcbsp->id);
 
-		clk_disable(mcbsp->clk);
-		clk_put(mcbsp->clk);
+		for (i = mcbsp->num_clks - 1; i >= 0; i--) {
+			clk_disable(mcbsp->clks[i]);
+			clk_put(mcbsp->clks[i]);
+		}
 
 		iounmap(mcbsp->io_base);
 
-		mcbsp->clk = NULL;
+		if (mcbsp->num_clks) {
+			kfree(mcbsp->clks);
+			mcbsp->clks = NULL;
+			mcbsp->num_clks = 0;
+		}
 		mcbsp->free = 0;
 		mcbsp->dev = NULL;
 	}
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index a949c4fbbddd..8f1f97d56e1e 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -169,26 +169,51 @@ config BF542
 	help
 	  BF542 Processor Support.
 
+config BF542M
+	bool "BF542m"
+	help
+	  BF542 Processor Support.
+
 config BF544
 	bool "BF544"
 	help
 	  BF544 Processor Support.
 
+config BF544M
+	bool "BF544m"
+	help
+	  BF544 Processor Support.
+
 config BF547
 	bool "BF547"
 	help
 	  BF547 Processor Support.
 
+config BF547M
+	bool "BF547m"
+	help
+	  BF547 Processor Support.
+
 config BF548
 	bool "BF548"
 	help
 	  BF548 Processor Support.
 
+config BF548M
+	bool "BF548m"
+	help
+	  BF548 Processor Support.
+
 config BF549
 	bool "BF549"
 	help
 	  BF549 Processor Support.
 
+config BF549M
+	bool "BF549m"
+	help
+	  BF549 Processor Support.
+
 config BF561
 	bool "BF561"
 	help
@@ -224,39 +249,39 @@ config TICK_SOURCE_SYSTMR0
 
 config BF_REV_MIN
 	int
-	default 0 if (BF51x || BF52x || BF54x)
+	default 0 if (BF51x || BF52x || (BF54x && !BF54xM))
 	default 2 if (BF537 || BF536 || BF534)
-	default 3 if (BF561 ||BF533 || BF532 || BF531)
+	default 3 if (BF561 || BF533 || BF532 || BF531 || BF54xM)
 	default 4 if (BF538 || BF539)
 
 config BF_REV_MAX
 	int
-	default 2 if (BF51x || BF52x || BF54x)
-	default 3 if (BF537 || BF536 || BF534)
+	default 2 if (BF51x || BF52x || (BF54x && !BF54xM))
+	default 3 if (BF537 || BF536 || BF534 || BF54xM)
 	default 5 if (BF561 || BF538 || BF539)
 	default 6 if (BF533 || BF532 || BF531)
 
 choice
 	prompt "Silicon Rev"
-	default BF_REV_0_1 if (BF51x || BF52x || BF54x)
+	default BF_REV_0_1 if (BF51x || BF52x || (BF54x && !BF54xM))
 	default BF_REV_0_2 if (BF534 || BF536 || BF537)
-	default BF_REV_0_3 if (BF531 || BF532 || BF533 || BF561)
+	default BF_REV_0_3 if (BF531 || BF532 || BF533 || BF54xM || BF561)
 
 config BF_REV_0_0
 	bool "0.0"
-	depends on (BF51x || BF52x || BF54x)
+	depends on (BF51x || BF52x || (BF54x && !BF54xM))
 
 config BF_REV_0_1
 	bool "0.1"
-	depends on (BF52x || BF54x)
+	depends on (BF52x || (BF54x && !BF54xM))
 
 config BF_REV_0_2
 	bool "0.2"
-	depends on (BF52x || BF537 || BF536 || BF534 || BF54x)
+	depends on (BF52x || BF537 || BF536 || BF534 || (BF54x && !BF54xM))
 
 config BF_REV_0_3
 	bool "0.3"
-	depends on (BF561 || BF537 || BF536 || BF534 || BF533 || BF532 || BF531)
+	depends on (BF54xM || BF561 || BF537 || BF536 || BF534 || BF533 || BF532 || BF531)
 
 config BF_REV_0_4
 	bool "0.4"
@@ -293,9 +318,14 @@ config BF53x
 	depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537)
 	default y
 
+config BF54xM
+	bool
+	depends on (BF542M || BF544M || BF547M || BF548M || BF549M)
+	default y
+
 config BF54x
 	bool
-	depends on (BF542 || BF544 || BF547 || BF548 || BF549)
+	depends on (BF542 || BF544 || BF547 || BF548 || BF549 || BF54xM)
 	default y
 
 config MEM_GENERIC_BOARD
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
index e550c8d46066..d54c8283825c 100644
--- a/arch/blackfin/Makefile
+++ b/arch/blackfin/Makefile
@@ -21,57 +21,67 @@ KALLSYMS         += --symbol-prefix=_
 KBUILD_DEFCONFIG := BF537-STAMP_defconfig
 
 # setup the machine name and the machine dependent settings
-machine-$(CONFIG_BF512) := bf518
-machine-$(CONFIG_BF514) := bf518
-machine-$(CONFIG_BF516) := bf518
-machine-$(CONFIG_BF518) := bf518
-machine-$(CONFIG_BF522) := bf527
-machine-$(CONFIG_BF523) := bf527
-machine-$(CONFIG_BF524) := bf527
-machine-$(CONFIG_BF525) := bf527
-machine-$(CONFIG_BF526) := bf527
-machine-$(CONFIG_BF527) := bf527
-machine-$(CONFIG_BF531) := bf533
-machine-$(CONFIG_BF532) := bf533
-machine-$(CONFIG_BF533) := bf533
-machine-$(CONFIG_BF534) := bf537
-machine-$(CONFIG_BF536) := bf537
-machine-$(CONFIG_BF537) := bf537
-machine-$(CONFIG_BF538) := bf538
-machine-$(CONFIG_BF539) := bf538
-machine-$(CONFIG_BF542) := bf548
-machine-$(CONFIG_BF544) := bf548
-machine-$(CONFIG_BF547) := bf548
-machine-$(CONFIG_BF548) := bf548
-machine-$(CONFIG_BF549) := bf548
-machine-$(CONFIG_BF561) := bf561
+machine-$(CONFIG_BF512)  := bf518
+machine-$(CONFIG_BF514)  := bf518
+machine-$(CONFIG_BF516)  := bf518
+machine-$(CONFIG_BF518)  := bf518
+machine-$(CONFIG_BF522)  := bf527
+machine-$(CONFIG_BF523)  := bf527
+machine-$(CONFIG_BF524)  := bf527
+machine-$(CONFIG_BF525)  := bf527
+machine-$(CONFIG_BF526)  := bf527
+machine-$(CONFIG_BF527)  := bf527
+machine-$(CONFIG_BF531)  := bf533
+machine-$(CONFIG_BF532)  := bf533
+machine-$(CONFIG_BF533)  := bf533
+machine-$(CONFIG_BF534)  := bf537
+machine-$(CONFIG_BF536)  := bf537
+machine-$(CONFIG_BF537)  := bf537
+machine-$(CONFIG_BF538)  := bf538
+machine-$(CONFIG_BF539)  := bf538
+machine-$(CONFIG_BF542)  := bf548
+machine-$(CONFIG_BF542M) := bf548
+machine-$(CONFIG_BF544)  := bf548
+machine-$(CONFIG_BF544M) := bf548
+machine-$(CONFIG_BF547)  := bf548
+machine-$(CONFIG_BF547M) := bf548
+machine-$(CONFIG_BF548)  := bf548
+machine-$(CONFIG_BF548M) := bf548
+machine-$(CONFIG_BF549)  := bf548
+machine-$(CONFIG_BF549M) := bf548
+machine-$(CONFIG_BF561)  := bf561
 MACHINE := $(machine-y)
 export MACHINE
 
-cpu-$(CONFIG_BF512) := bf512
-cpu-$(CONFIG_BF514) := bf514
-cpu-$(CONFIG_BF516) := bf516
-cpu-$(CONFIG_BF518) := bf518
-cpu-$(CONFIG_BF522) := bf522
-cpu-$(CONFIG_BF523) := bf523
-cpu-$(CONFIG_BF524) := bf524
-cpu-$(CONFIG_BF525) := bf525
-cpu-$(CONFIG_BF526) := bf526
-cpu-$(CONFIG_BF527) := bf527
-cpu-$(CONFIG_BF531) := bf531
-cpu-$(CONFIG_BF532) := bf532
-cpu-$(CONFIG_BF533) := bf533
-cpu-$(CONFIG_BF534) := bf534
-cpu-$(CONFIG_BF536) := bf536
-cpu-$(CONFIG_BF537) := bf537
-cpu-$(CONFIG_BF538) := bf538
-cpu-$(CONFIG_BF539) := bf539
-cpu-$(CONFIG_BF542) := bf542
-cpu-$(CONFIG_BF544) := bf544
-cpu-$(CONFIG_BF547) := bf547
-cpu-$(CONFIG_BF548) := bf548
-cpu-$(CONFIG_BF549) := bf549
-cpu-$(CONFIG_BF561) := bf561
+cpu-$(CONFIG_BF512)  := bf512
+cpu-$(CONFIG_BF514)  := bf514
+cpu-$(CONFIG_BF516)  := bf516
+cpu-$(CONFIG_BF518)  := bf518
+cpu-$(CONFIG_BF522)  := bf522
+cpu-$(CONFIG_BF523)  := bf523
+cpu-$(CONFIG_BF524)  := bf524
+cpu-$(CONFIG_BF525)  := bf525
+cpu-$(CONFIG_BF526)  := bf526
+cpu-$(CONFIG_BF527)  := bf527
+cpu-$(CONFIG_BF531)  := bf531
+cpu-$(CONFIG_BF532)  := bf532
+cpu-$(CONFIG_BF533)  := bf533
+cpu-$(CONFIG_BF534)  := bf534
+cpu-$(CONFIG_BF536)  := bf536
+cpu-$(CONFIG_BF537)  := bf537
+cpu-$(CONFIG_BF538)  := bf538
+cpu-$(CONFIG_BF539)  := bf539
+cpu-$(CONFIG_BF542)  := bf542
+cpu-$(CONFIG_BF542M) := bf542m
+cpu-$(CONFIG_BF544)  := bf544
+cpu-$(CONFIG_BF544M) := bf544m
+cpu-$(CONFIG_BF547)  := bf547
+cpu-$(CONFIG_BF547M) := bf547m
+cpu-$(CONFIG_BF548)  := bf548
+cpu-$(CONFIG_BF548M) := bf548m
+cpu-$(CONFIG_BF549)  := bf549
+cpu-$(CONFIG_BF549M) := bf549m
+cpu-$(CONFIG_BF561)  := bf561
 
 rev-$(CONFIG_BF_REV_0_0)  := 0.0
 rev-$(CONFIG_BF_REV_0_1)  := 0.1
diff --git a/arch/blackfin/configs/BF518F-EZBRD_defconfig b/arch/blackfin/configs/BF518F-EZBRD_defconfig
index defb9785c65b..4fdb9e04759f 100644
--- a/arch/blackfin/configs/BF518F-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF518F-EZBRD_defconfig
@@ -1,6 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.28-rc2
+# Fri Jan  9 17:58:41 2009
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -149,6 +150,7 @@ CONFIG_BF_REV_0_0=y
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
 CONFIG_BF51x=y
+CONFIG_MEM_MT48LC32M8A2_75=y
 CONFIG_BFIN518F_EZBRD=y
 
 #
@@ -598,7 +600,10 @@ CONFIG_PHYLIB=y
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
-# CONFIG_BFIN_MAC is not set
+CONFIG_BFIN_MAC=y
+CONFIG_BFIN_TX_DESC_NUM=10
+CONFIG_BFIN_RX_DESC_NUM=20
+# CONFIG_BFIN_MAC_RMII is not set
 # CONFIG_SMC91X is not set
 # CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
@@ -679,7 +684,7 @@ CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_DEVKMEM is not set
-# CONFIG_BFIN_JTAG_COMM is not set
+CONFIG_BFIN_JTAG_COMM=m
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
diff --git a/arch/blackfin/configs/BF526-EZBRD_defconfig b/arch/blackfin/configs/BF526-EZBRD_defconfig
index 992424ff3153..8e2b855b8db7 100644
--- a/arch/blackfin/configs/BF526-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF526-EZBRD_defconfig
@@ -723,7 +723,7 @@ CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_DEVKMEM is not set
-# CONFIG_BFIN_JTAG_COMM is not set
+CONFIG_BFIN_JTAG_COMM=m
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
index 21e3c1af55ba..833128b39724 100644
--- a/arch/blackfin/configs/BF527-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -767,7 +767,7 @@ CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_DEVKMEM is not set
-# CONFIG_BFIN_JTAG_COMM is not set
+CONFIG_BFIN_JTAG_COMM=m
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig
index 0bdf20a1af61..334c94b51c40 100644
--- a/arch/blackfin/configs/BF533-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF533-EZKIT_defconfig
@@ -672,7 +672,7 @@ CONFIG_BFIN_DMA_INTERFACE=m
 CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
-# CONFIG_BFIN_JTAG_COMM is not set
+CONFIG_BFIN_JTAG_COMM=m
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig
index 2f747d6e97e2..9d733436e300 100644
--- a/arch/blackfin/configs/BF533-STAMP_defconfig
+++ b/arch/blackfin/configs/BF533-STAMP_defconfig
@@ -679,7 +679,7 @@ CONFIG_BFIN_DMA_INTERFACE=m
 CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
-# CONFIG_BFIN_JTAG_COMM is not set
+CONFIG_BFIN_JTAG_COMM=m
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig
index 8b0a81294e65..4fb4108d3103 100644
--- a/arch/blackfin/configs/BF537-STAMP_defconfig
+++ b/arch/blackfin/configs/BF537-STAMP_defconfig
@@ -722,7 +722,7 @@ CONFIG_BFIN_DMA_INTERFACE=m
 CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
-# CONFIG_BFIN_JTAG_COMM is not set
+CONFIG_BFIN_JTAG_COMM=m
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
diff --git a/arch/blackfin/configs/BF538-EZKIT_defconfig b/arch/blackfin/configs/BF538-EZKIT_defconfig
index a1f766bf7d9b..cb32f5624a1b 100644
--- a/arch/blackfin/configs/BF538-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF538-EZKIT_defconfig
@@ -726,7 +726,7 @@ CONFIG_BFIN_DMA_INTERFACE=m
 CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
-# CONFIG_BFIN_JTAG_COMM is not set
+CONFIG_BFIN_JTAG_COMM=m
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
index cd2da6b7692c..0f8697618aa5 100644
--- a/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -856,7 +856,7 @@ CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_DEVKMEM is not set
-# CONFIG_BFIN_JTAG_COMM is not set
+CONFIG_BFIN_JTAG_COMM=m
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig
index b398ca202dbd..042c7adfccfa 100644
--- a/arch/blackfin/configs/BF561-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF561-EZKIT_defconfig
@@ -709,7 +709,7 @@ CONFIG_BFIN_DMA_INTERFACE=m
 CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
-# CONFIG_BFIN_JTAG_COMM is not set
+CONFIG_BFIN_JTAG_COMM=m
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
diff --git a/arch/blackfin/configs/CM-BF527_defconfig b/arch/blackfin/configs/CM-BF527_defconfig
index 95146948166f..865ed85a5760 100644
--- a/arch/blackfin/configs/CM-BF527_defconfig
+++ b/arch/blackfin/configs/CM-BF527_defconfig
@@ -1,7 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24.7
-# Fri Jul 18 18:00:41 2008
+# Linux kernel version: 2.6.28
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -9,7 +8,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BLACKFIN=y
 CONFIG_ZONE_DMA=y
-CONFIG_SEMAPHORE_SLEEPERS=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -32,18 +30,16 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
-# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_GROUP_SCHED 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
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -52,26 +48,35 @@ CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE 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_AIO=y
 CONFIG_VM_EVENT_COUNTERS=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_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=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
@@ -82,6 +87,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -95,9 +101,11 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
 # CONFIG_PREEMPT_NONE is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
+# CONFIG_FREEZER is not set
 
 #
 # Blackfin Processor Options
@@ -106,6 +114,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
 #
 # Processor and Board Settings
 #
+# CONFIG_BF512 is not set
+# CONFIG_BF514 is not set
+# CONFIG_BF516 is not set
+# CONFIG_BF518 is not set
 # CONFIG_BF522 is not set
 # CONFIG_BF523 is not set
 # CONFIG_BF524 is not set
@@ -118,48 +130,32 @@ CONFIG_BF527=y
 # CONFIG_BF534 is not set
 # CONFIG_BF536 is not set
 # CONFIG_BF537 is not set
+# CONFIG_BF538 is not set
+# CONFIG_BF539 is not set
 # CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
 # CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
 # CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
 # CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
 # CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
 # CONFIG_BF561 is not set
+CONFIG_BF_REV_MIN=0
+CONFIG_BF_REV_MAX=2
 # CONFIG_BF_REV_0_0 is not set
 CONFIG_BF_REV_0_1=y
 # CONFIG_BF_REV_0_2 is not set
 # CONFIG_BF_REV_0_3 is not set
 # CONFIG_BF_REV_0_4 is not set
 # CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_0_6 is not set
 # CONFIG_BF_REV_ANY is not set
 # CONFIG_BF_REV_NONE is not set
 CONFIG_BF52x=y
 CONFIG_MEM_MT48LC16M16A2TG_75=y
-# CONFIG_BFIN527_EZKIT is not set
-CONFIG_BFIN527_BLUETECHNIX_CM=y
-
-#
-# BF527 Specific Configuration
-#
-
-#
-# Alternative Multiplexing Scheme
-#
-# CONFIG_BF527_SPORT0_PORTF is not set
-CONFIG_BF527_SPORT0_PORTG=y
-CONFIG_BF527_SPORT0_TSCLK_PG10=y
-# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set
-CONFIG_BF527_UART1_PORTF=y
-# CONFIG_BF527_UART1_PORTG is not set
-# CONFIG_BF527_NAND_D_PORTF is not set
-CONFIG_BF527_NAND_D_PORTH=y
-
-#
-# Interrupt Priority Assignment
-#
-
-#
-# Priority
-#
 CONFIG_IRQ_PLL_WAKEUP=7
 CONFIG_IRQ_DMA0_ERROR=7
 CONFIG_IRQ_DMAR0_BLK=7
@@ -179,7 +175,6 @@ CONFIG_IRQ_SPORT0_TX=9
 CONFIG_IRQ_SPORT1_RX=9
 CONFIG_IRQ_SPORT1_TX=9
 CONFIG_IRQ_TWI=10
-CONFIG_IRQ_SPI=10
 CONFIG_IRQ_UART0_RX=10
 CONFIG_IRQ_UART0_TX=10
 CONFIG_IRQ_UART1_RX=10
@@ -205,6 +200,34 @@ CONFIG_IRQ_MEM_DMA1=13
 CONFIG_IRQ_WATCH=13
 CONFIG_IRQ_PORTF_INTA=13
 CONFIG_IRQ_PORTF_INTB=13
+# CONFIG_BFIN527_EZKIT is not set
+CONFIG_BFIN527_BLUETECHNIX_CM=y
+# CONFIG_BFIN526_EZBRD is not set
+
+#
+# BF527 Specific Configuration
+#
+
+#
+# Alternative Multiplexing Scheme
+#
+# CONFIG_BF527_SPORT0_PORTF is not set
+CONFIG_BF527_SPORT0_PORTG=y
+CONFIG_BF527_SPORT0_TSCLK_PG10=y
+# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set
+CONFIG_BF527_UART1_PORTF=y
+# CONFIG_BF527_UART1_PORTG is not set
+# CONFIG_BF527_NAND_D_PORTF is not set
+CONFIG_BF527_NAND_D_PORTH=y
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_SPI=10
 CONFIG_IRQ_SPI_ERROR=7
 CONFIG_IRQ_NFC_ERROR=7
 CONFIG_IRQ_HDMA_ERROR=7
@@ -226,7 +249,6 @@ CONFIG_BOOT_LOAD=0x1000
 #
 CONFIG_CLKIN_HZ=25000000
 # CONFIG_BFIN_KERNEL_CLOCK is not set
-CONFIG_MAX_MEM_SIZE=512
 CONFIG_MAX_VCO_HZ=600000000
 CONFIG_MIN_VCO_HZ=50000000
 CONFIG_MAX_SCLK_HZ=133333333
@@ -240,10 +262,10 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_CYCLES_CLOCKSOURCE is not set
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -277,6 +299,12 @@ CONFIG_ACCESS_OK_L1=y
 CONFIG_CACHELINE_ALIGNED_L1=y
 # CONFIG_SYSCALL_TAB_L1 is not set
 # CONFIG_CPLB_SWITCH_TAB_L1 is not set
+CONFIG_APP_STACK_L1=y
+
+#
+# Speed Optimizations
+#
+CONFIG_BFIN_INS_LOWOVERHEAD=y
 CONFIG_RAMKERNEL=y
 # CONFIG_ROMKERNEL is not set
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -285,10 +313,10 @@ 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 is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_VIRT_TO_BUS=y
 CONFIG_BFIN_GPTIMERS=y
@@ -334,7 +362,6 @@ CONFIG_BANK_3=0xFFC0
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
-# CONFIG_PCI is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCCARD is not set
 
@@ -345,25 +372,20 @@ CONFIG_BINFMT_ELF_FDPIC=y
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
 # CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 
 #
 # Power management options
 #
 # CONFIG_PM is not set
-CONFIG_SUSPEND_UP_POSSIBLE=y
-# CONFIG_PM_BFIN_SLEEP_DEEPER is not set
-# CONFIG_PM_BFIN_SLEEP is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PM_WAKEUP_BY_GPIO is not set
 
 #
 # CPU Frequency scaling
 #
 # CONFIG_CPU_FREQ is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -376,6 +398,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -405,8 +428,6 @@ CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETLABEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
@@ -415,6 +436,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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
@@ -431,14 +453,14 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # 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
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -456,6 +478,8 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
@@ -464,6 +488,7 @@ CONFIG_MTD=y
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -507,6 +532,7 @@ CONFIG_MTD_ROM=m
 #
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 # CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_GPIO_ADDR is not set
 # CONFIG_MTD_UCLINUX is not set
 # CONFIG_MTD_PLATRAM is not set
 
@@ -542,10 +568,12 @@ CONFIG_BLK_DEV=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP 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 is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -558,7 +586,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_ATA is not set
 # CONFIG_MD 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
@@ -579,6 +606,7 @@ CONFIG_PHYLIB=y
 # 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_FIXED_PHY is not set
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
@@ -591,11 +619,14 @@ CONFIG_BFIN_MAC_RMII=y
 # CONFIG_SMC91X is not set
 # CONFIG_SMSC911X is not set
 # CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 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_B44 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_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 
@@ -604,6 +635,7 @@ CONFIG_BFIN_MAC_RMII=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # USB Network Adapters
@@ -616,7 +648,6 @@ CONFIG_BFIN_MAC_RMII=y
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -642,14 +673,15 @@ CONFIG_BFIN_MAC_RMII=y
 # CONFIG_BF5xx_PPIFCD is not set
 # CONFIG_BFIN_SIMPLE_TIMER is not set
 # CONFIG_BF5xx_PPI is not set
-CONFIG_BFIN_OTP=y
-# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
+# CONFIG_BF5xx_EPPI is not set
 # CONFIG_BFIN_SPORT is not set
 # CONFIG_BFIN_TIMER_LATENCY is not set
 # CONFIG_TWI_LCD is not set
+CONFIG_BFIN_DMA_INTERFACE=m
 CONFIG_SIMPLE_GPIO=m
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
+# CONFIG_BFIN_JTAG_COMM is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -673,6 +705,8 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_BFIN_SPORT is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
+CONFIG_BFIN_OTP=y
+# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
 
 #
 # CAN, the car bus and industrial fieldbus
@@ -680,44 +714,49 @@ CONFIG_UNIX98_PTYS=y
 # CONFIG_CAN4LINUX is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
-# CONFIG_GEN_RTC 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_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
 
 #
-# I2C Algorithms
+# I2C Hardware Bus support
 #
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
 
 #
-# I2C Hardware Bus support
+# I2C system bus drivers (mostly embedded / system-on-chip)
 #
 CONFIG_I2C_BLACKFIN_TWI=m
 CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB 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_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_AD5252 is not set
-# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8575 is not set
+# CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
@@ -726,37 +765,41 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# SPI support
-#
 CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
 
 #
 # SPI Master Controller Drivers
 #
 CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BFIN_LOCK is not set
 # CONFIG_SPI_BITBANG is not set
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
+# CONFIG_SPI_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 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=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_F71805F is not set
@@ -777,6 +820,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1111 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
@@ -785,6 +829,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
@@ -792,9 +837,12 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83792D is not set
 # CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -810,21 +858,31 @@ CONFIG_BFIN_WDT=y
 # CONFIG_USBPCWATCHDOG is not set
 
 #
-# Sonics Silicon Backplane
-#
-CONFIG_SSB_POSSIBLE=y
-# 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_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C 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
 
 #
@@ -839,10 +897,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
@@ -850,6 +904,7 @@ CONFIG_USB_ARCH_HAS_HCD=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
@@ -860,40 +915,48 @@ CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 CONFIG_USB_OTG_BLACKLIST_HUB=y
+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_ISP116X_HCD is not set
-# CONFIG_USB_ISP1362_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 # 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=y
 CONFIG_USB_MUSB_SOC=y
 
 #
-# Blackfin high speed USB support
+# Blackfin high speed USB Support
 #
 CONFIG_USB_MUSB_HOST=y
 # CONFIG_USB_MUSB_PERIPHERAL is not set
 # CONFIG_USB_MUSB_OTG is not set
 CONFIG_USB_MUSB_HDRC_HCD=y
 CONFIG_MUSB_PIO_ONLY=y
-CONFIG_USB_MUSB_LOGLEVEL=0
+CONFIG_MUSB_DMA_POLL=y
+# CONFIG_USB_MUSB_DEBUG 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 enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
 #
 # CONFIG_USB_LIBUSUAL is not set
 
@@ -901,15 +964,10 @@ CONFIG_USB_MUSB_LOGLEVEL=0
 # USB Imaging devices
 #
 # CONFIG_USB_MDC800 is not set
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
 #
-
-#
-# USB Serial Converter support
-#
 # CONFIG_USB_SERIAL is not set
 
 #
@@ -918,7 +976,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD 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
@@ -934,17 +992,13 @@ CONFIG_USB_MON=y
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET 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=y
 CONFIG_RTC_HCTOSYS=y
@@ -973,51 +1027,59 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
 
 #
 # SPI RTC drivers
 #
-# CONFIG_RTC_DRV_RS5C348 is not set
+# 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
 
 #
 # Platform RTC drivers
 #
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
 # CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_STK17TA8 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_BQ4802 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
 # on-CPU RTC drivers
 #
 CONFIG_RTC_DRV_BFIN=y
-
-#
-# Userspace I/O
-#
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
 #
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-# CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -1059,8 +1121,11 @@ CONFIG_SYSFS=y
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS 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
@@ -1068,13 +1133,12 @@ CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1130,7 +1194,6 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
-# CONFIG_INSTRUMENTATION is not set
 
 #
 # Kernel hacking
@@ -1138,14 +1201,61 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # 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_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL 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_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_BOOT_PRINTK_DELAY 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_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_KGDB_TESTCASE is not set
+CONFIG_DEBUG_VERBOSE=y
 CONFIG_DEBUG_MMRS=y
+# CONFIG_DEBUG_HWERR is not set
+# CONFIG_DEBUG_DOUBLEFAULT is not set
 CONFIG_DEBUG_HUNT_FOR_ZERO=y
 CONFIG_DEBUG_BFIN_HWTRACE_ON=y
 CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
@@ -1154,7 +1264,7 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
 CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
 # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
-CONFIG_EARLY_PRINTK=y
+# CONFIG_EARLY_PRINTK is not set
 # CONFIG_CPLB_INFO is not set
 CONFIG_ACCESS_CHECK=y
 
@@ -1163,10 +1273,96 @@ CONFIG_ACCESS_CHECK=y
 #
 # CONFIG_KEYS is not set
 CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_NETWORK is not set
-# CONFIG_SECURITY_CAPABILITIES is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 # CONFIG_SECURITY_ROOTPLUG is not set
-# CONFIG_CRYPTO is not set
+CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST 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 is not set
+# 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
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C 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 is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# 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_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
@@ -1174,6 +1370,7 @@ CONFIG_SECURITY=y
 CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # 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
diff --git a/arch/blackfin/include/asm/checksum.h b/arch/blackfin/include/asm/checksum.h
index f67289a0d8d2..793581fc9556 100644
--- a/arch/blackfin/include/asm/checksum.h
+++ b/arch/blackfin/include/asm/checksum.h
@@ -63,23 +63,23 @@ static inline __wsum
 csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
 		   unsigned short proto, __wsum sum)
 {
-
-	__asm__ ("%0 = %0 + %1;\n\t"
-		 "CC = AC0;\n\t"
-		 "if !CC jump 4;\n\t"
-		 "%0 = %0 + %4;\n\t"
-		 "%0 = %0 + %2;\n\t"
-		 "CC = AC0;\n\t"
-                 "if !CC jump 4;\n\t"
-                 "%0 = %0 + %4;\n\t"
- 		 "%0 = %0 + %3;\n\t"
-		 "CC = AC0;\n\t"
-                 "if !CC jump 4;\n\t"
-                 "%0 = %0 + %4;\n\t"
-                 "NOP;\n\t"
- 		 : "=d" (sum)
-		 : "d" (daddr), "d" (saddr), "d" ((ntohs(len)<<16)+proto*256), "d" (1), "0"(sum)
-		 : "CC");
+	unsigned int carry;
+
+	__asm__ ("%0 = %0 + %2;\n\t"
+		"CC = AC0;\n\t"
+		"%1 = CC;\n\t"
+		"%0 = %0 + %1;\n\t"
+		"%0 = %0 + %3;\n\t"
+		"CC = AC0;\n\t"
+		"%1 = CC;\n\t"
+		"%0 = %0 + %1;\n\t"
+		"%0 = %0 + %4;\n\t"
+		"CC = AC0;\n\t"
+		"%1 = CC;\n\t"
+		"%0 = %0 + %1;\n\t"
+		: "=d" (sum), "=&d" (carry)
+		: "d" (daddr), "d" (saddr), "d" ((len + proto) << 8), "0"(sum)
+		: "CC");
 
 	return (sum);
 }
diff --git a/arch/blackfin/include/asm/delay.h b/arch/blackfin/include/asm/delay.h
index 0889c3abb593..c31f91cc1d5d 100644
--- a/arch/blackfin/include/asm/delay.h
+++ b/arch/blackfin/include/asm/delay.h
@@ -13,29 +13,7 @@
 
 static inline void __delay(unsigned long loops)
 {
-	if (ANOMALY_05000312) {
-		/* Interrupted loads to loop registers -> bad */
-		unsigned long tmp;
-		__asm__ __volatile__(
-			"[--SP] = LC0;"
-			"[--SP] = LT0;"
-			"[--SP] = LB0;"
-			"LSETUP (1f,1f) LC0 = %1;"
-			"1: NOP;"
-			/* We take advantage of the fact that LC0 is 0 at
-			 * the end of the loop.  Otherwise we'd need some
-			 * NOPs after the CLI here.
-			 */
-			"CLI %0;"
-			"LB0 = [SP++];"
-			"LT0 = [SP++];"
-			"LC0 = [SP++];"
-			"STI %0;"
-			: "=d" (tmp)
-			: "a" (loops)
-		);
-	} else
-		__asm__ __volatile__ (
+__asm__ __volatile__ (
 			"LSETUP(1f, 1f) LC0 = %0;"
 			"1: NOP;"
 			:
@@ -47,16 +25,15 @@ static inline void __delay(unsigned long loops)
 #include <linux/param.h>	/* needed for HZ */
 
 /*
- * Use only for very small delays ( < 1 msec).  Should probably use a
- * lookup table, really, as the multiplications take much too long with
- * short delays.  This is a "reasonable" implementation, though (and the
- * first constant multiplications gets optimized away if the delay is
- * a constant)
+ * close approximation borrowed from m68knommu to avoid 64-bit math
  */
+
+#define	HZSCALE		(268435456 / (1000000/HZ))
+
 static inline void udelay(unsigned long usecs)
 {
 	extern unsigned long loops_per_jiffy;
-	__delay(usecs * loops_per_jiffy / (1000000 / HZ));
+	__delay((((usecs * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6);
 }
 
 #endif
diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h
index 9477d82fcad2..d4a082ef75b4 100644
--- a/arch/blackfin/include/asm/gpio.h
+++ b/arch/blackfin/include/asm/gpio.h
@@ -27,60 +27,6 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-/*
-*  Number     BF537/6/4    BF561    BF533/2/1
-*             BF527/5/2
-*
-*  GPIO_0       PF0         PF0        PF0
-*  GPIO_1       PF1         PF1        PF1
-*  GPIO_2       PF2         PF2        PF2
-*  GPIO_3       PF3         PF3        PF3
-*  GPIO_4       PF4         PF4        PF4
-*  GPIO_5       PF5         PF5        PF5
-*  GPIO_6       PF6         PF6        PF6
-*  GPIO_7       PF7         PF7        PF7
-*  GPIO_8       PF8         PF8        PF8
-*  GPIO_9       PF9         PF9        PF9
-*  GPIO_10      PF10        PF10       PF10
-*  GPIO_11      PF11        PF11       PF11
-*  GPIO_12      PF12        PF12       PF12
-*  GPIO_13      PF13        PF13       PF13
-*  GPIO_14      PF14        PF14       PF14
-*  GPIO_15      PF15        PF15       PF15
-*  GPIO_16      PG0         PF16
-*  GPIO_17      PG1         PF17
-*  GPIO_18      PG2         PF18
-*  GPIO_19      PG3         PF19
-*  GPIO_20      PG4         PF20
-*  GPIO_21      PG5         PF21
-*  GPIO_22      PG6         PF22
-*  GPIO_23      PG7         PF23
-*  GPIO_24      PG8         PF24
-*  GPIO_25      PG9         PF25
-*  GPIO_26      PG10        PF26
-*  GPIO_27      PG11        PF27
-*  GPIO_28      PG12        PF28
-*  GPIO_29      PG13        PF29
-*  GPIO_30      PG14        PF30
-*  GPIO_31      PG15        PF31
-*  GPIO_32      PH0         PF32
-*  GPIO_33      PH1         PF33
-*  GPIO_34      PH2         PF34
-*  GPIO_35      PH3         PF35
-*  GPIO_36      PH4         PF36
-*  GPIO_37      PH5         PF37
-*  GPIO_38      PH6         PF38
-*  GPIO_39      PH7         PF39
-*  GPIO_40      PH8         PF40
-*  GPIO_41      PH9         PF41
-*  GPIO_42      PH10        PF42
-*  GPIO_43      PH11        PF43
-*  GPIO_44      PH12        PF44
-*  GPIO_45      PH13        PF45
-*  GPIO_46      PH14        PF46
-*  GPIO_47      PH15        PF47
-*/
-
 #ifndef __ARCH_BLACKFIN_GPIO_H__
 #define __ARCH_BLACKFIN_GPIO_H__
 
@@ -295,10 +241,6 @@ int bfin_gpio_direction_output(unsigned gpio, int value);
 int bfin_gpio_get_value(unsigned gpio);
 void bfin_gpio_set_value(unsigned gpio, int value);
 
-#ifndef BF548_FAMILY
-#define bfin_gpio_set_value(gpio, value)    set_gpio_data(gpio, value)
-#endif
-
 #ifdef CONFIG_GPIOLIB
 #include <asm-generic/gpio.h>		/* cansleep wrappers */
 
diff --git a/arch/blackfin/include/asm/kgdb.h b/arch/blackfin/include/asm/kgdb.h
index 26ebac6646d8..c8b256d2ea30 100644
--- a/arch/blackfin/include/asm/kgdb.h
+++ b/arch/blackfin/include/asm/kgdb.h
@@ -1,32 +1,8 @@
-/*
- * File:         include/asm-blackfin/kgdb.h
- * Based on:
- * Author:       Sonic Zhang
- *
- * Created:
- * Description:
- *
- * Rev:          $Id: kgdb_bfin_linux-2.6.x.patch 4934 2007-02-13 09:32:11Z sonicz $
- *
- * Modified:
- *               Copyright 2005-2006 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+/* Blackfin KGDB header
  *
- * 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.
+ * Copyright 2005-2009 Analog Devices Inc.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ * Licensed under the GPL-2 or later.
  */
 
 #ifndef __ASM_BLACKFIN_KGDB_H__
@@ -37,17 +13,18 @@
 /* gdb locks */
 #define KGDB_MAX_NO_CPUS 8
 
-/************************************************************************/
-/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
-/* at least NUMREGBYTES*2 are needed for register packets */
-/* Longer buffer is needed to list all threads */
+/*
+ * BUFMAX defines the maximum number of characters in inbound/outbound buffers.
+ * At least NUMREGBYTES*2 are needed for register packets.
+ * Longer buffer is needed to list all threads.
+ */
 #define BUFMAX 2048
 
 /*
- *  Note that this register image is different from
- *  the register image that Linux produces at interrupt time.
- *  
- *  Linux's register image is defined by struct pt_regs in ptrace.h.
+ * Note that this register image is different from
+ * the register image that Linux produces at interrupt time.
+ *
+ * Linux's register image is defined by struct pt_regs in ptrace.h.
  */
 enum regnames {
   /* Core Registers */
@@ -104,14 +81,14 @@ enum regnames {
   BFIN_RETX,
   BFIN_RETN,
   BFIN_RETE,
-  
+
   /* Pseudo Registers */
   BFIN_PC,
   BFIN_CC,
   BFIN_EXTRA1,		/* Address of .text section.  */
   BFIN_EXTRA2,		/* Address of .data section.  */
   BFIN_EXTRA3,		/* Address of .bss section.  */
-  BFIN_FDPIC_EXEC, 
+  BFIN_FDPIC_EXEC,
   BFIN_FDPIC_INTERP,
 
   /* MMRs */
@@ -126,7 +103,7 @@ enum regnames {
 
 static inline void arch_kgdb_breakpoint(void)
 {
-	asm("   EXCPT 2;");
+	asm("EXCPT 2;");
 }
 #define BREAK_INSTR_SIZE	2
 #define CACHE_FLUSH_IS_SAFE	1
diff --git a/arch/blackfin/include/asm/mem_init.h b/arch/blackfin/include/asm/mem_init.h
index 255a9316ad36..61f7487fbf12 100644
--- a/arch/blackfin/include/asm/mem_init.h
+++ b/arch/blackfin/include/asm/mem_init.h
@@ -115,7 +115,7 @@
 #define mem_SDRRC       (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num)
 
 /* Enable SCLK Out */
-#define mem_SDGCTL        (0x80000000 | SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS)
+#define mem_SDGCTL        (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS)
 #else
 #define mem_SDRRC 	CONFIG_MEM_SDRRC
 #define mem_SDGCTL	CONFIG_MEM_SDGCTL
diff --git a/arch/blackfin/include/asm/pda.h b/arch/blackfin/include/asm/pda.h
index bd8d4a7efeb2..a67142740df0 100644
--- a/arch/blackfin/include/asm/pda.h
+++ b/arch/blackfin/include/asm/pda.h
@@ -59,6 +59,7 @@ struct blackfin_pda {			/* Per-processor Data Area */
 	unsigned long icplb_fault_addr;
 	unsigned long retx;
 	unsigned long seqstat;
+	unsigned int __nmi_count;	/* number of times NMI asserted on this CPU */
 };
 
 extern struct blackfin_pda cpu_pda[];
diff --git a/arch/blackfin/include/asm/reboot.h b/arch/blackfin/include/asm/reboot.h
index 4856d62b7467..ae1e36329bec 100644
--- a/arch/blackfin/include/asm/reboot.h
+++ b/arch/blackfin/include/asm/reboot.h
@@ -15,6 +15,6 @@ extern void native_machine_halt(void);
 extern void native_machine_power_off(void);
 
 /* common reboot workarounds */
-extern void bfin_gpio_reset_spi0_ssel1(void);
+extern void bfin_reset_boot_spi_cs(unsigned short pin);
 
 #endif
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
index 38a233374f07..4a92a86824b7 100644
--- a/arch/blackfin/kernel/Makefile
+++ b/arch/blackfin/kernel/Makefile
@@ -15,6 +15,8 @@ else
     obj-y += time.o
 endif
 
+CFLAGS_kgdb_test.o := -mlong-calls -O0
+
 obj-$(CONFIG_IPIPE)                  += ipipe.o
 obj-$(CONFIG_IPIPE_TRACE_MCOUNT)     += mcount.o
 obj-$(CONFIG_BFIN_GPTIMERS)          += gptimers.o
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 07e02c0d1c07..8531693fb48d 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -249,6 +249,13 @@ static void __dma_memcpy(u32 daddr, s16 dmod, u32 saddr, s16 smod, size_t cnt, u
 
 	spin_lock_irqsave(&mdma_lock, flags);
 
+	/* Force a sync in case a previous config reset on this channel
+	 * occurred.  This is needed so subsequent writes to DMA registers
+	 * are not spuriously lost/corrupted.  Do it under irq lock and
+	 * without the anomaly version (because we are atomic already).
+	 */
+	__builtin_bfin_ssync();
+
 	if (bfin_read_MDMA_S0_CONFIG())
 		while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE))
 			continue;
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index 4c14331978f6..51dac55c524a 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -27,59 +27,6 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-/*
-*  Number     BF537/6/4    BF561    BF533/2/1	   BF549/8/4/2
-*
-*  GPIO_0       PF0         PF0        PF0	   PA0...PJ13
-*  GPIO_1       PF1         PF1        PF1
-*  GPIO_2       PF2         PF2        PF2
-*  GPIO_3       PF3         PF3        PF3
-*  GPIO_4       PF4         PF4        PF4
-*  GPIO_5       PF5         PF5        PF5
-*  GPIO_6       PF6         PF6        PF6
-*  GPIO_7       PF7         PF7        PF7
-*  GPIO_8       PF8         PF8        PF8
-*  GPIO_9       PF9         PF9        PF9
-*  GPIO_10      PF10        PF10       PF10
-*  GPIO_11      PF11        PF11       PF11
-*  GPIO_12      PF12        PF12       PF12
-*  GPIO_13      PF13        PF13       PF13
-*  GPIO_14      PF14        PF14       PF14
-*  GPIO_15      PF15        PF15       PF15
-*  GPIO_16      PG0         PF16
-*  GPIO_17      PG1         PF17
-*  GPIO_18      PG2         PF18
-*  GPIO_19      PG3         PF19
-*  GPIO_20      PG4         PF20
-*  GPIO_21      PG5         PF21
-*  GPIO_22      PG6         PF22
-*  GPIO_23      PG7         PF23
-*  GPIO_24      PG8         PF24
-*  GPIO_25      PG9         PF25
-*  GPIO_26      PG10        PF26
-*  GPIO_27      PG11        PF27
-*  GPIO_28      PG12        PF28
-*  GPIO_29      PG13        PF29
-*  GPIO_30      PG14        PF30
-*  GPIO_31      PG15        PF31
-*  GPIO_32      PH0         PF32
-*  GPIO_33      PH1         PF33
-*  GPIO_34      PH2         PF34
-*  GPIO_35      PH3         PF35
-*  GPIO_36      PH4         PF36
-*  GPIO_37      PH5         PF37
-*  GPIO_38      PH6         PF38
-*  GPIO_39      PH7         PF39
-*  GPIO_40      PH8         PF40
-*  GPIO_41      PH9         PF41
-*  GPIO_42      PH10        PF42
-*  GPIO_43      PH11        PF43
-*  GPIO_44      PH12        PF44
-*  GPIO_45      PH13        PF45
-*  GPIO_46      PH14        PF46
-*  GPIO_47      PH15        PF47
-*/
-
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/err.h>
@@ -119,62 +66,61 @@ enum {
 #define AWA_DUMMY_READ(...)  do { } while (0)
 #endif
 
+static struct gpio_port_t * const gpio_array[] = {
 #if defined(BF533_FAMILY) || defined(BF538_FAMILY)
-static struct gpio_port_t *gpio_bankb[] = {
 	(struct gpio_port_t *) FIO_FLAG_D,
-};
-#endif
-
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
-static struct gpio_port_t *gpio_bankb[] = {
+#elif defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
 	(struct gpio_port_t *) PORTFIO,
 	(struct gpio_port_t *) PORTGIO,
 	(struct gpio_port_t *) PORTHIO,
+#elif defined(BF561_FAMILY)
+	(struct gpio_port_t *) FIO0_FLAG_D,
+	(struct gpio_port_t *) FIO1_FLAG_D,
+	(struct gpio_port_t *) FIO2_FLAG_D,
+#elif defined(BF548_FAMILY)
+	(struct gpio_port_t *)PORTA_FER,
+	(struct gpio_port_t *)PORTB_FER,
+	(struct gpio_port_t *)PORTC_FER,
+	(struct gpio_port_t *)PORTD_FER,
+	(struct gpio_port_t *)PORTE_FER,
+	(struct gpio_port_t *)PORTF_FER,
+	(struct gpio_port_t *)PORTG_FER,
+	(struct gpio_port_t *)PORTH_FER,
+	(struct gpio_port_t *)PORTI_FER,
+	(struct gpio_port_t *)PORTJ_FER,
+#else
+# error no gpio arrays defined
+#endif
 };
 
-static unsigned short *port_fer[] = {
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+static unsigned short * const port_fer[] = {
 	(unsigned short *) PORTF_FER,
 	(unsigned short *) PORTG_FER,
 	(unsigned short *) PORTH_FER,
 };
-#endif
 
-#if defined(BF527_FAMILY) || defined(BF518_FAMILY)
-static unsigned short *port_mux[] = {
+# if !defined(BF537_FAMILY)
+static unsigned short * const port_mux[] = {
 	(unsigned short *) PORTF_MUX,
 	(unsigned short *) PORTG_MUX,
 	(unsigned short *) PORTH_MUX,
 };
 
 static const
-u8 pmux_offset[][16] =
-	{{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */
-	 { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */
-	 { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */
-	};
-#endif
-
-#ifdef BF561_FAMILY
-static struct gpio_port_t *gpio_bankb[] = {
-	(struct gpio_port_t *) FIO0_FLAG_D,
-	(struct gpio_port_t *) FIO1_FLAG_D,
-	(struct gpio_port_t *) FIO2_FLAG_D,
+u8 pmux_offset[][16] = {
+#  if defined(BF527_FAMILY)
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */
+	{ 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */
+#  elif defined(BF518_FAMILY)
+	{ 0, 2, 2, 2, 2, 2, 2, 4, 6, 6, 6, 8, 8, 8, 8, 10 }, /* PORTF */
+	{ 0, 0, 0, 2, 4, 6, 6, 6, 8, 10, 10, 12, 14, 14, 14, 14 }, /* PORTG */
+	{ 0, 0, 0, 0, 2, 2, 4, 6, 10, 10, 10, 10, 10, 10, 10, 10 }, /* PORTH */
+#  endif
 };
-#endif
+# endif
 
-#ifdef BF548_FAMILY
-static struct gpio_port_t *gpio_array[] = {
-	(struct gpio_port_t *)PORTA_FER,
-	(struct gpio_port_t *)PORTB_FER,
-	(struct gpio_port_t *)PORTC_FER,
-	(struct gpio_port_t *)PORTD_FER,
-	(struct gpio_port_t *)PORTE_FER,
-	(struct gpio_port_t *)PORTF_FER,
-	(struct gpio_port_t *)PORTG_FER,
-	(struct gpio_port_t *)PORTH_FER,
-	(struct gpio_port_t *)PORTI_FER,
-	(struct gpio_port_t *)PORTJ_FER,
-};
 #endif
 
 static unsigned short reserved_gpio_map[GPIO_BANK_NUM];
@@ -188,35 +134,9 @@ static struct str_ident {
 } str_ident[MAX_RESOURCES];
 
 #if defined(CONFIG_PM)
-#if defined(CONFIG_BF54x)
-static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM];
-#else
-static unsigned short wakeup_map[GPIO_BANK_NUM];
-static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS];
 static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM];
-
-#ifdef BF533_FAMILY
-static unsigned int sic_iwr_irqs[] = {IRQ_PROG_INTB};
-#endif
-
-#ifdef BF537_FAMILY
-static unsigned int sic_iwr_irqs[] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX};
-#endif
-
-#ifdef BF538_FAMILY
-static unsigned int sic_iwr_irqs[] = {IRQ_PORTF_INTB};
 #endif
 
-#if defined(BF527_FAMILY) || defined(BF518_FAMILY)
-static unsigned int sic_iwr_irqs[] = {IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB};
-#endif
-
-#ifdef BF561_FAMILY
-static unsigned int sic_iwr_irqs[] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB};
-#endif
-#endif
-#endif /* CONFIG_PM */
-
 inline int check_gpio(unsigned gpio)
 {
 #if defined(BF548_FAMILY)
@@ -330,9 +250,10 @@ static struct {
 	{.res = P_SPI0_SSEL3, .offset = 0},
 };
 
-static void portmux_setup(unsigned short per, unsigned short function)
+static void portmux_setup(unsigned short per)
 {
 	u16 y, offset, muxreg;
+	u16 function = P_FUNCT2MUX(per);
 
 	for (y = 0; y < ARRAY_SIZE(port_mux_lut); y++) {
 		if (port_mux_lut[y].res == per) {
@@ -353,30 +274,33 @@ static void portmux_setup(unsigned short per, unsigned short function)
 	}
 }
 #elif defined(BF548_FAMILY)
-inline void portmux_setup(unsigned short portno, unsigned short function)
+inline void portmux_setup(unsigned short per)
 {
 	u32 pmux;
+	u16 ident = P_IDENT(per);
+	u16 function = P_FUNCT2MUX(per);
 
-	pmux = gpio_array[gpio_bank(portno)]->port_mux;
+	pmux = gpio_array[gpio_bank(ident)]->port_mux;
 
-	pmux &= ~(0x3 << (2 * gpio_sub_n(portno)));
-	pmux |= (function & 0x3) << (2 * gpio_sub_n(portno));
+	pmux &= ~(0x3 << (2 * gpio_sub_n(ident)));
+	pmux |= (function & 0x3) << (2 * gpio_sub_n(ident));
 
-	gpio_array[gpio_bank(portno)]->port_mux = pmux;
+	gpio_array[gpio_bank(ident)]->port_mux = pmux;
 }
 
-inline u16 get_portmux(unsigned short portno)
+inline u16 get_portmux(unsigned short per)
 {
 	u32 pmux;
+	u16 ident = P_IDENT(per);
 
-	pmux = gpio_array[gpio_bank(portno)]->port_mux;
+	pmux = gpio_array[gpio_bank(ident)]->port_mux;
 
-	return (pmux >> (2 * gpio_sub_n(portno)) & 0x3);
+	return (pmux >> (2 * gpio_sub_n(ident)) & 0x3);
 }
 #elif defined(BF527_FAMILY) || defined(BF518_FAMILY)
-inline void portmux_setup(unsigned short portno, unsigned short function)
+inline void portmux_setup(unsigned short per)
 {
-	u16 pmux, ident = P_IDENT(portno);
+	u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per);
 	u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)];
 
 	pmux = *port_mux[gpio_bank(ident)];
@@ -424,90 +348,71 @@ void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
 	unsigned long flags; \
 	local_irq_save_hw(flags); \
 	if (arg) \
-		gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
+		gpio_array[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
 	else \
-		gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \
+		gpio_array[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \
 	AWA_DUMMY_READ(name); \
 	local_irq_restore_hw(flags); \
 } \
 EXPORT_SYMBOL(set_gpio_ ## name);
 
-SET_GPIO(dir)
-SET_GPIO(inen)
-SET_GPIO(polar)
-SET_GPIO(edge)
-SET_GPIO(both)
+SET_GPIO(dir)   /* set_gpio_dir() */
+SET_GPIO(inen)  /* set_gpio_inen() */
+SET_GPIO(polar) /* set_gpio_polar() */
+SET_GPIO(edge)  /* set_gpio_edge() */
+SET_GPIO(both)  /* set_gpio_both() */
 
 
-#if ANOMALY_05000311 || ANOMALY_05000323
 #define SET_GPIO_SC(name) \
 void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
 { \
 	unsigned long flags; \
-	local_irq_save_hw(flags); \
-	if (arg) \
-		gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
-	else \
-		gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
-	AWA_DUMMY_READ(name); \
-	local_irq_restore_hw(flags); \
-} \
-EXPORT_SYMBOL(set_gpio_ ## name);
-#else
-#define SET_GPIO_SC(name) \
-void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
-{ \
+	if (ANOMALY_05000311 || ANOMALY_05000323) \
+		local_irq_save_hw(flags); \
 	if (arg) \
-		gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
+		gpio_array[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
 	else \
-		gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
+		gpio_array[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
+	if (ANOMALY_05000311 || ANOMALY_05000323) { \
+		AWA_DUMMY_READ(name); \
+		local_irq_restore_hw(flags); \
+	} \
 } \
 EXPORT_SYMBOL(set_gpio_ ## name);
-#endif
 
 SET_GPIO_SC(maska)
 SET_GPIO_SC(maskb)
 SET_GPIO_SC(data)
 
-#if ANOMALY_05000311 || ANOMALY_05000323
 void set_gpio_toggle(unsigned gpio)
 {
 	unsigned long flags;
-	local_irq_save_hw(flags);
-	gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
-	AWA_DUMMY_READ(toggle);
-	local_irq_restore_hw(flags);
-}
-#else
-void set_gpio_toggle(unsigned gpio)
-{
-	gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
+	if (ANOMALY_05000311 || ANOMALY_05000323)
+		local_irq_save_hw(flags);
+	gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
+	if (ANOMALY_05000311 || ANOMALY_05000323) {
+		AWA_DUMMY_READ(toggle);
+		local_irq_restore_hw(flags);
+	}
 }
-#endif
 EXPORT_SYMBOL(set_gpio_toggle);
 
 
 /*Set current PORT date (16-bit word)*/
 
-#if ANOMALY_05000311 || ANOMALY_05000323
 #define SET_GPIO_P(name) \
 void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \
 { \
 	unsigned long flags; \
-	local_irq_save_hw(flags); \
-	gpio_bankb[gpio_bank(gpio)]->name = arg; \
-	AWA_DUMMY_READ(name); \
-	local_irq_restore_hw(flags); \
+	if (ANOMALY_05000311 || ANOMALY_05000323) \
+		local_irq_save_hw(flags); \
+	gpio_array[gpio_bank(gpio)]->name = arg; \
+	if (ANOMALY_05000311 || ANOMALY_05000323) { \
+		AWA_DUMMY_READ(name); \
+		local_irq_restore_hw(flags); \
+	} \
 } \
 EXPORT_SYMBOL(set_gpiop_ ## name);
-#else
-#define SET_GPIO_P(name) \
-void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \
-{ \
-	gpio_bankb[gpio_bank(gpio)]->name = arg; \
-} \
-EXPORT_SYMBOL(set_gpiop_ ## name);
-#endif
 
 SET_GPIO_P(data)
 SET_GPIO_P(dir)
@@ -519,27 +424,21 @@ SET_GPIO_P(maska)
 SET_GPIO_P(maskb)
 
 /* Get a specific bit */
-#if ANOMALY_05000311 || ANOMALY_05000323
 #define GET_GPIO(name) \
 unsigned short get_gpio_ ## name(unsigned gpio) \
 { \
 	unsigned long flags; \
 	unsigned short ret; \
-	local_irq_save_hw(flags); \
-	ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \
-	AWA_DUMMY_READ(name); \
-	local_irq_restore_hw(flags); \
+	if (ANOMALY_05000311 || ANOMALY_05000323) \
+		local_irq_save_hw(flags); \
+	ret = 0x01 & (gpio_array[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \
+	if (ANOMALY_05000311 || ANOMALY_05000323) { \
+		AWA_DUMMY_READ(name); \
+		local_irq_restore_hw(flags); \
+	} \
 	return ret; \
 } \
 EXPORT_SYMBOL(get_gpio_ ## name);
-#else
-#define GET_GPIO(name) \
-unsigned short get_gpio_ ## name(unsigned gpio) \
-{ \
-	return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \
-} \
-EXPORT_SYMBOL(get_gpio_ ## name);
-#endif
 
 GET_GPIO(data)
 GET_GPIO(dir)
@@ -552,27 +451,21 @@ GET_GPIO(maskb)
 
 /*Get current PORT date (16-bit word)*/
 
-#if ANOMALY_05000311 || ANOMALY_05000323
 #define GET_GPIO_P(name) \
 unsigned short get_gpiop_ ## name(unsigned gpio) \
 { \
 	unsigned long flags; \
 	unsigned short ret; \
-	local_irq_save_hw(flags); \
-	ret = (gpio_bankb[gpio_bank(gpio)]->name); \
-	AWA_DUMMY_READ(name); \
-	local_irq_restore_hw(flags); \
+	if (ANOMALY_05000311 || ANOMALY_05000323) \
+		local_irq_save_hw(flags); \
+	ret = (gpio_array[gpio_bank(gpio)]->name); \
+	if (ANOMALY_05000311 || ANOMALY_05000323) { \
+		AWA_DUMMY_READ(name); \
+		local_irq_restore_hw(flags); \
+	} \
 	return ret; \
 } \
 EXPORT_SYMBOL(get_gpiop_ ## name);
-#else
-#define GET_GPIO_P(name) \
-unsigned short get_gpiop_ ## name(unsigned gpio) \
-{ \
-	return (gpio_bankb[gpio_bank(gpio)]->name);\
-} \
-EXPORT_SYMBOL(get_gpiop_ ## name);
-#endif
 
 GET_GPIO_P(data)
 GET_GPIO_P(dir)
@@ -585,6 +478,26 @@ GET_GPIO_P(maskb)
 
 
 #ifdef CONFIG_PM
+
+static unsigned short wakeup_map[GPIO_BANK_NUM];
+static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS];
+
+static const unsigned int sic_iwr_irqs[] = {
+#if defined(BF533_FAMILY)
+	IRQ_PROG_INTB
+#elif defined(BF537_FAMILY)
+	IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX
+#elif defined(BF538_FAMILY)
+	IRQ_PORTF_INTB
+#elif defined(BF527_FAMILY) || defined(BF518_FAMILY)
+	IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB
+#elif defined(BF561_FAMILY)
+	IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB
+#else
+# error no SIC_IWR defined
+#endif
+};
+
 /***********************************************************
 *
 * FUNCTIONS: Blackfin PM Setup API
@@ -669,18 +582,18 @@ u32 bfin_pm_standby_setup(void)
 		mask = wakeup_map[gpio_bank(i)];
 		bank = gpio_bank(i);
 
-		gpio_bank_saved[bank].maskb = gpio_bankb[bank]->maskb;
-		gpio_bankb[bank]->maskb = 0;
+		gpio_bank_saved[bank].maskb = gpio_array[bank]->maskb;
+		gpio_array[bank]->maskb = 0;
 
 		if (mask) {
 #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
 			gpio_bank_saved[bank].fer   = *port_fer[bank];
 #endif
-			gpio_bank_saved[bank].inen  = gpio_bankb[bank]->inen;
-			gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar;
-			gpio_bank_saved[bank].dir   = gpio_bankb[bank]->dir;
-			gpio_bank_saved[bank].edge  = gpio_bankb[bank]->edge;
-			gpio_bank_saved[bank].both  = gpio_bankb[bank]->both;
+			gpio_bank_saved[bank].inen  = gpio_array[bank]->inen;
+			gpio_bank_saved[bank].polar = gpio_array[bank]->polar;
+			gpio_bank_saved[bank].dir   = gpio_array[bank]->dir;
+			gpio_bank_saved[bank].edge  = gpio_array[bank]->edge;
+			gpio_bank_saved[bank].both  = gpio_array[bank]->both;
 			gpio_bank_saved[bank].reserved =
 						reserved_gpio_map[bank];
 
@@ -700,7 +613,7 @@ u32 bfin_pm_standby_setup(void)
 			}
 
 			bfin_internal_set_wake(sic_iwr_irqs[bank], 1);
-			gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)];
+			gpio_array[bank]->maskb_set = wakeup_map[gpio_bank(i)];
 		}
 	}
 
@@ -721,18 +634,18 @@ void bfin_pm_standby_restore(void)
 #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
 			*port_fer[bank]   	= gpio_bank_saved[bank].fer;
 #endif
-			gpio_bankb[bank]->inen  = gpio_bank_saved[bank].inen;
-			gpio_bankb[bank]->dir   = gpio_bank_saved[bank].dir;
-			gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar;
-			gpio_bankb[bank]->edge  = gpio_bank_saved[bank].edge;
-			gpio_bankb[bank]->both  = gpio_bank_saved[bank].both;
+			gpio_array[bank]->inen  = gpio_bank_saved[bank].inen;
+			gpio_array[bank]->dir   = gpio_bank_saved[bank].dir;
+			gpio_array[bank]->polar = gpio_bank_saved[bank].polar;
+			gpio_array[bank]->edge  = gpio_bank_saved[bank].edge;
+			gpio_array[bank]->both  = gpio_bank_saved[bank].both;
 
 			reserved_gpio_map[bank] =
 					gpio_bank_saved[bank].reserved;
 			bfin_internal_set_wake(sic_iwr_irqs[bank], 0);
 		}
 
-		gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb;
+		gpio_array[bank]->maskb = gpio_bank_saved[bank].maskb;
 	}
 	AWA_DUMMY_READ(maskb);
 }
@@ -745,21 +658,21 @@ void bfin_gpio_pm_hibernate_suspend(void)
 		bank = gpio_bank(i);
 
 #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
-			gpio_bank_saved[bank].fer   = *port_fer[bank];
+		gpio_bank_saved[bank].fer = *port_fer[bank];
 #if defined(BF527_FAMILY) || defined(BF518_FAMILY)
-			gpio_bank_saved[bank].mux   = *port_mux[bank];
+		gpio_bank_saved[bank].mux = *port_mux[bank];
 #else
-			if (bank == 0)
-				gpio_bank_saved[bank].mux   = bfin_read_PORT_MUX();
+		if (bank == 0)
+			gpio_bank_saved[bank].mux = bfin_read_PORT_MUX();
 #endif
 #endif
-			gpio_bank_saved[bank].data  = gpio_bankb[bank]->data;
-			gpio_bank_saved[bank].inen  = gpio_bankb[bank]->inen;
-			gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar;
-			gpio_bank_saved[bank].dir   = gpio_bankb[bank]->dir;
-			gpio_bank_saved[bank].edge  = gpio_bankb[bank]->edge;
-			gpio_bank_saved[bank].both  = gpio_bankb[bank]->both;
-			gpio_bank_saved[bank].maska  = gpio_bankb[bank]->maska;
+		gpio_bank_saved[bank].data  = gpio_array[bank]->data;
+		gpio_bank_saved[bank].inen  = gpio_array[bank]->inen;
+		gpio_bank_saved[bank].polar = gpio_array[bank]->polar;
+		gpio_bank_saved[bank].dir   = gpio_array[bank]->dir;
+		gpio_bank_saved[bank].edge  = gpio_array[bank]->edge;
+		gpio_bank_saved[bank].both  = gpio_array[bank]->both;
+		gpio_bank_saved[bank].maska = gpio_array[bank]->maska;
 	}
 
 	AWA_DUMMY_READ(maska);
@@ -770,27 +683,27 @@ void bfin_gpio_pm_hibernate_restore(void)
 	int i, bank;
 
 	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
-			bank = gpio_bank(i);
+		bank = gpio_bank(i);
 
 #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
 #if defined(BF527_FAMILY) || defined(BF518_FAMILY)
-			*port_mux[bank] = gpio_bank_saved[bank].mux;
+		*port_mux[bank] = gpio_bank_saved[bank].mux;
 #else
-			if (bank == 0)
-				bfin_write_PORT_MUX(gpio_bank_saved[bank].mux);
+		if (bank == 0)
+			bfin_write_PORT_MUX(gpio_bank_saved[bank].mux);
 #endif
-			*port_fer[bank]   	= gpio_bank_saved[bank].fer;
+		*port_fer[bank] = gpio_bank_saved[bank].fer;
 #endif
-			gpio_bankb[bank]->inen  = gpio_bank_saved[bank].inen;
-			gpio_bankb[bank]->dir   = gpio_bank_saved[bank].dir;
-			gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar;
-			gpio_bankb[bank]->edge  = gpio_bank_saved[bank].edge;
-			gpio_bankb[bank]->both  = gpio_bank_saved[bank].both;
+		gpio_array[bank]->inen  = gpio_bank_saved[bank].inen;
+		gpio_array[bank]->dir   = gpio_bank_saved[bank].dir;
+		gpio_array[bank]->polar = gpio_bank_saved[bank].polar;
+		gpio_array[bank]->edge  = gpio_bank_saved[bank].edge;
+		gpio_array[bank]->both  = gpio_bank_saved[bank].both;
 
-			gpio_bankb[bank]->data_set = gpio_bank_saved[bank].data
-							| gpio_bank_saved[bank].dir;
+		gpio_array[bank]->data_set = gpio_bank_saved[bank].data
+						| gpio_bank_saved[bank].dir;
 
-			gpio_bankb[bank]->maska = gpio_bank_saved[bank].maska;
+		gpio_array[bank]->maska = gpio_bank_saved[bank].maska;
 	}
 	AWA_DUMMY_READ(maska);
 }
@@ -817,12 +730,12 @@ void bfin_gpio_pm_hibernate_suspend(void)
 	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
 		bank = gpio_bank(i);
 
-			gpio_bank_saved[bank].fer  = gpio_array[bank]->port_fer;
-			gpio_bank_saved[bank].mux  = gpio_array[bank]->port_mux;
-			gpio_bank_saved[bank].data  = gpio_array[bank]->port_data;
-			gpio_bank_saved[bank].data  = gpio_array[bank]->port_data;
-			gpio_bank_saved[bank].inen  = gpio_array[bank]->port_inen;
-			gpio_bank_saved[bank].dir   = gpio_array[bank]->port_dir_set;
+		gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer;
+		gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux;
+		gpio_bank_saved[bank].data = gpio_array[bank]->data;
+		gpio_bank_saved[bank].data = gpio_array[bank]->data;
+		gpio_bank_saved[bank].inen = gpio_array[bank]->inen;
+		gpio_bank_saved[bank].dir = gpio_array[bank]->dir_set;
 	}
 }
 
@@ -831,21 +744,21 @@ void bfin_gpio_pm_hibernate_restore(void)
 	int i, bank;
 
 	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
-			bank = gpio_bank(i);
-
-			gpio_array[bank]->port_mux  = gpio_bank_saved[bank].mux;
-			gpio_array[bank]->port_fer  = gpio_bank_saved[bank].fer;
-			gpio_array[bank]->port_inen  = gpio_bank_saved[bank].inen;
-			gpio_array[bank]->port_dir_set   = gpio_bank_saved[bank].dir;
-			gpio_array[bank]->port_set = gpio_bank_saved[bank].data
-							| gpio_bank_saved[bank].dir;
+		bank = gpio_bank(i);
+
+		gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux;
+		gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer;
+		gpio_array[bank]->inen = gpio_bank_saved[bank].inen;
+		gpio_array[bank]->dir_set = gpio_bank_saved[bank].dir;
+		gpio_array[bank]->data_set = gpio_bank_saved[bank].data
+						| gpio_bank_saved[bank].dir;
 	}
 }
 #endif
 
 unsigned short get_gpio_dir(unsigned gpio)
 {
-	return (0x01 & (gpio_array[gpio_bank(gpio)]->port_dir_clear >> gpio_sub_n(gpio)));
+	return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio)));
 }
 EXPORT_SYMBOL(get_gpio_dir);
 
@@ -905,9 +818,7 @@ int peripheral_request(unsigned short per, const char *label)
 		 */
 
 #ifdef BF548_FAMILY
-		u16 funct = get_portmux(ident);
-
-		if (!((per & P_MAYSHARE) && (funct == P_FUNCT2MUX(per)))) {
+		if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) {
 #else
 		if (!(per & P_MAYSHARE)) {
 #endif
@@ -931,11 +842,7 @@ int peripheral_request(unsigned short per, const char *label)
  anyway:
 	reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident);
 
-#ifdef BF548_FAMILY
-	portmux_setup(ident, P_FUNCT2MUX(per));
-#else
-	portmux_setup(per, P_FUNCT2MUX(per));
-#endif
+	portmux_setup(per);
 	port_setup(ident, PERIPHERAL_USAGE);
 
 	local_irq_restore_hw(flags);
@@ -977,9 +884,6 @@ void peripheral_free(unsigned short per)
 	if (!(per & P_DEFINED))
 		return;
 
-	if (check_gpio(ident) < 0)
-		return;
-
 	local_irq_save_hw(flags);
 
 	if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) {
@@ -1056,9 +960,15 @@ int bfin_gpio_request(unsigned gpio, const char *label)
 		local_irq_restore_hw(flags);
 		return -EBUSY;
 	}
-	if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio)))
+	if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
 		printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!"
 		       " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio);
+	}
+#ifndef BF548_FAMILY
+	else {	/* Reset POLAR setting when acquiring a gpio for the first time */
+		set_gpio_polar(gpio, 0);
+	}
+#endif
 
 	reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
 	set_label(gpio, label);
@@ -1078,6 +988,8 @@ void bfin_gpio_free(unsigned gpio)
 	if (check_gpio(gpio) < 0)
 		return;
 
+	might_sleep();
+
 	local_irq_save_hw(flags);
 
 	if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
@@ -1158,8 +1070,16 @@ void bfin_gpio_irq_free(unsigned gpio)
 	local_irq_restore_hw(flags);
 }
 
-
+static inline void __bfin_gpio_direction_input(unsigned gpio)
+{
 #ifdef BF548_FAMILY
+	gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio);
+#else
+	gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
+#endif
+	gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
+}
+
 int bfin_gpio_direction_input(unsigned gpio)
 {
 	unsigned long flags;
@@ -1170,125 +1090,85 @@ int bfin_gpio_direction_input(unsigned gpio)
 	}
 
 	local_irq_save_hw(flags);
-	gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
-	gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
+	__bfin_gpio_direction_input(gpio);
+	AWA_DUMMY_READ(inen);
 	local_irq_restore_hw(flags);
 
 	return 0;
 }
 EXPORT_SYMBOL(bfin_gpio_direction_input);
 
-int bfin_gpio_direction_output(unsigned gpio, int value)
+void bfin_gpio_irq_prepare(unsigned gpio)
 {
+#ifdef BF548_FAMILY
 	unsigned long flags;
+#endif
 
-	if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-		gpio_error(gpio);
-		return -EINVAL;
-	}
+	port_setup(gpio, GPIO_USAGE);
 
+#ifdef BF548_FAMILY
 	local_irq_save_hw(flags);
-	gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio);
-	gpio_set_value(gpio, value);
-	gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio);
+	__bfin_gpio_direction_input(gpio);
 	local_irq_restore_hw(flags);
-
-	return 0;
+#endif
 }
-EXPORT_SYMBOL(bfin_gpio_direction_output);
 
 void bfin_gpio_set_value(unsigned gpio, int arg)
 {
 	if (arg)
-		gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio);
+		gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
 	else
-		gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio);
+		gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
 }
 EXPORT_SYMBOL(bfin_gpio_set_value);
 
-int bfin_gpio_get_value(unsigned gpio)
-{
-	return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio)));
-}
-EXPORT_SYMBOL(bfin_gpio_get_value);
-
-void bfin_gpio_irq_prepare(unsigned gpio)
+int bfin_gpio_direction_output(unsigned gpio, int value)
 {
 	unsigned long flags;
 
-	port_setup(gpio, GPIO_USAGE);
+	if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
+		gpio_error(gpio);
+		return -EINVAL;
+	}
 
 	local_irq_save_hw(flags);
-	gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
-	gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
-	local_irq_restore_hw(flags);
-}
 
+	gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
+	gpio_set_value(gpio, value);
+#ifdef BF548_FAMILY
+	gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio);
 #else
+	gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
+#endif
+
+	AWA_DUMMY_READ(dir);
+	local_irq_restore_hw(flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(bfin_gpio_direction_output);
 
 int bfin_gpio_get_value(unsigned gpio)
 {
+#ifdef BF548_FAMILY
+	return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)));
+#else
 	unsigned long flags;
-	int ret;
 
 	if (unlikely(get_gpio_edge(gpio))) {
+		int ret;
 		local_irq_save_hw(flags);
 		set_gpio_edge(gpio, 0);
 		ret = get_gpio_data(gpio);
 		set_gpio_edge(gpio, 1);
 		local_irq_restore_hw(flags);
-
 		return ret;
 	} else
 		return get_gpio_data(gpio);
+#endif
 }
 EXPORT_SYMBOL(bfin_gpio_get_value);
 
-
-int bfin_gpio_direction_input(unsigned gpio)
-{
-	unsigned long flags;
-
-	if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-		gpio_error(gpio);
-		return -EINVAL;
-	}
-
-	local_irq_save_hw(flags);
-	gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
-	gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
-	AWA_DUMMY_READ(inen);
-	local_irq_restore_hw(flags);
-
-	return 0;
-}
-EXPORT_SYMBOL(bfin_gpio_direction_input);
-
-int bfin_gpio_direction_output(unsigned gpio, int value)
-{
-	unsigned long flags;
-
-	if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-		gpio_error(gpio);
-		return -EINVAL;
-	}
-
-	local_irq_save_hw(flags);
-	gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
-
-	if (value)
-		gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
-	else
-		gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
-
-	gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
-	AWA_DUMMY_READ(dir);
-	local_irq_restore_hw(flags);
-
-	return 0;
-}
-EXPORT_SYMBOL(bfin_gpio_direction_output);
-
 /* If we are booting from SPI and our board lacks a strong enough pull up,
  * the core can reset and execute the bootrom faster than the resistor can
  * pull the signal logically high.  To work around this (common) error in
@@ -1299,23 +1179,15 @@ EXPORT_SYMBOL(bfin_gpio_direction_output);
  * lives here as we need to force all the GPIO states w/out going through
  * BUG() checks and such.
  */
-void bfin_gpio_reset_spi0_ssel1(void)
+void bfin_reset_boot_spi_cs(unsigned short pin)
 {
-	u16 gpio = P_IDENT(P_SPI0_SSEL1);
-
+	unsigned short gpio = P_IDENT(pin);
 	port_setup(gpio, GPIO_USAGE);
-	gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
+	gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
 	AWA_DUMMY_READ(data_set);
 	udelay(1);
 }
 
-void bfin_gpio_irq_prepare(unsigned gpio)
-{
-	port_setup(gpio, GPIO_USAGE);
-}
-
-#endif /*BF548_FAMILY */
-
 #if defined(CONFIG_PROC_FS)
 static int gpio_proc_read(char *buf, char **start, off_t offset,
 			  int len, int *unused_i, void *unused_v)
@@ -1369,11 +1241,7 @@ int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio)
 
 void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value)
 {
-#ifdef BF548_FAMILY
 	return bfin_gpio_set_value(gpio, value);
-#else
-	return set_gpio_data(gpio, value);
-#endif
 }
 
 int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio)
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
index bdb958486e76..3e329a6ce041 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
@@ -63,10 +63,8 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)
 	dcplb_tbl[cpu][i_d].addr = 0;
 	dcplb_tbl[cpu][i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB;
 
-#if 0
 	icplb_tbl[cpu][i_i].addr = 0;
-	icplb_tbl[cpu][i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_4KB;
-#endif
+	icplb_tbl[cpu][i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_1KB;
 
 	/* Cover kernel memory with 4M pages.  */
 	addr = 0;
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
index 376249ab2694..8cbb47c7b663 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
@@ -163,12 +163,14 @@ MGR_ATTR static int icplb_miss(int cpu)
 		nr_icplb_supv_miss[cpu]++;
 
 	base = 0;
-	for (idx = 0; idx < icplb_nr_bounds; idx++) {
+	idx = 0;
+	do {
 		eaddr = icplb_bounds[idx].eaddr;
 		if (addr < eaddr)
 			break;
 		base = eaddr;
-	}
+	} while (++idx < icplb_nr_bounds);
+
 	if (unlikely(idx == icplb_nr_bounds))
 		return CPLB_NO_ADDR_MATCH;
 
@@ -208,12 +210,14 @@ MGR_ATTR static int dcplb_miss(int cpu)
 		nr_dcplb_supv_miss[cpu]++;
 
 	base = 0;
-	for (idx = 0; idx < dcplb_nr_bounds; idx++) {
+	idx = 0;
+	do {
 		eaddr = dcplb_bounds[idx].eaddr;
 		if (addr < eaddr)
 			break;
 		base = eaddr;
-	}
+	} while (++idx < dcplb_nr_bounds);
+
 	if (unlikely(idx == dcplb_nr_bounds))
 		return CPLB_NO_ADDR_MATCH;
 
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 5780d6df1542..23e9aa080710 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -35,6 +35,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <asm/trace.h>
+#include <asm/pda.h>
 
 static atomic_t irq_err_count;
 static spinlock_t irq_controller_lock;
@@ -96,8 +97,13 @@ int show_interrupts(struct seq_file *p, void *v)
 		seq_putc(p, '\n');
  skip:
 		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
-	} else if (i == NR_IRQS)
+	} else if (i == NR_IRQS) {
+		seq_printf(p, "NMI: ");
+		for_each_online_cpu(j)
+			seq_printf(p, "%10u ", cpu_pda[j].__nmi_count);
+		seq_printf(p, "     CORE  Non Maskable Interrupt\n");
 		seq_printf(p, "Err: %10u\n",  atomic_read(&irq_err_count));
+	}
 	return 0;
 }
 
diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c
index eeee8cb43360..53d08dee8531 100644
--- a/arch/blackfin/kernel/reboot.c
+++ b/arch/blackfin/kernel/reboot.c
@@ -20,8 +20,8 @@
  * reset while the Core B bit (on dual core parts) is cleared by
  * the core reset.
  */
-__attribute__((l1_text))
-static void _bfin_reset(void)
+__attribute__ ((__l1_text__, __noreturn__))
+static void bfin_reset(void)
 {
 	/* Wait for completion of "system" events such as cache line
 	 * line fills so that we avoid infinite stalls later on as
@@ -30,7 +30,11 @@ static void _bfin_reset(void)
 	 */
 	__builtin_bfin_ssync();
 
-	while (1) {
+	/* The bootrom checks to see how it was reset and will
+	 * automatically perform a software reset for us when
+	 * it starts executing after the core reset.
+	 */
+	if (ANOMALY_05000353 || ANOMALY_05000386) {
 		/* Initiate System software reset. */
 		bfin_write_SWRST(0x7);
 
@@ -50,6 +54,11 @@ static void _bfin_reset(void)
 		/* Clear System software reset */
 		bfin_write_SWRST(0);
 
+		/* The BF526 ROM will crash during reset */
+#if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__)
+		bfin_read_SWRST();
+#endif
+
 		/* Wait for the SWRST write to complete.  Cannot rely on SSYNC
 		 * though as the System state is all reset now.
 		 */
@@ -60,22 +69,11 @@ static void _bfin_reset(void)
 			: "a" (15 * 1)
 			: "LC1", "LB1", "LT1"
 		);
+	}
 
+	while (1)
 		/* Issue core reset */
 		asm("raise 1");
-	}
-}
-
-static void bfin_reset(void)
-{
-	if (ANOMALY_05000353 || ANOMALY_05000386)
-		_bfin_reset();
-	else
-		/* the bootrom checks to see how it was reset and will
-		 * automatically perform a software reset for us when
-		 * it starts executing boot
-		 */
-		asm("raise 1;");
 }
 
 __attribute__((weak))
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index b2a811347b65..e5c116230800 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -60,7 +60,7 @@ void __initdata *init_retx, *init_saved_retx, *init_saved_seqstat,
 #define BFIN_MEMMAP_MAX		128 /* number of entries in bfin_memmap */
 #define BFIN_MEMMAP_RAM		1
 #define BFIN_MEMMAP_RESERVED	2
-struct bfin_memmap {
+static struct bfin_memmap {
 	int nr_map;
 	struct bfin_memmap_entry {
 		unsigned long long addr; /* start of memory segment */
@@ -824,7 +824,15 @@ void __init setup_arch(char **cmdline_p)
 	flash_probe();
 #endif
 
+	printk(KERN_INFO "Boot Mode: %i\n", bfin_read_SYSCR() & 0xF);
+
+	/* Newer parts mirror SWRST bits in SYSCR */
+#if defined(CONFIG_BF53x) || defined(CONFIG_BF561) || \
+    defined(CONFIG_BF538) || defined(CONFIG_BF539)
 	_bfin_swrst = bfin_read_SWRST();
+#else
+	_bfin_swrst = bfin_read_SYSCR();
+#endif
 
 #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT
 	bfin_write_SWRST(_bfin_swrst & ~DOUBLE_FAULT);
@@ -853,7 +861,7 @@ void __init setup_arch(char **cmdline_p)
 	else if (_bfin_swrst & RESET_SOFTWARE)
 		printk(KERN_NOTICE "Reset caused by Software reset\n");
 
-	printk(KERN_INFO "Blackfin support (C) 2004-2008 Analog Devices, Inc.\n");
+	printk(KERN_INFO "Blackfin support (C) 2004-2009 Analog Devices, Inc.\n");
 	if (bfin_compiled_revid() == 0xffff)
 		printk(KERN_INFO "Compiled for ADSP-%s Rev any\n", CPU);
 	else if (bfin_compiled_revid() == -1)
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 5b0667da8d05..ffe7fb53eccb 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -673,6 +673,14 @@ static void decode_instruction(unsigned short *address)
 			verbose_printk("RTI");
 		else if (opcode == 0x0012)
 			verbose_printk("RTX");
+		else if (opcode == 0x0013)
+			verbose_printk("RTN");
+		else if (opcode == 0x0014)
+			verbose_printk("RTE");
+		else if (opcode == 0x0025)
+			verbose_printk("EMUEXCPT");
+		else if (opcode == 0x0040 && opcode <= 0x0047)
+			verbose_printk("STI R%i", opcode & 7);
 		else if (opcode >= 0x0050 && opcode <= 0x0057)
 			verbose_printk("JUMP (P%i)", opcode & 7);
 		else if (opcode >= 0x0060 && opcode <= 0x0067)
@@ -681,6 +689,10 @@ static void decode_instruction(unsigned short *address)
 			verbose_printk("CALL (PC+P%i)", opcode & 7);
 		else if (opcode >= 0x0080 && opcode <= 0x0087)
 			verbose_printk("JUMP (PC+P%i)", opcode & 7);
+		else if (opcode >= 0x0090 && opcode <= 0x009F)
+			verbose_printk("RAISE 0x%x", opcode & 0xF);
+		else if (opcode >= 0x00A0 && opcode <= 0x00AF)
+			verbose_printk("EXCPT 0x%x", opcode & 0xF);
 		else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF))
 			verbose_printk("IF !CC JUMP");
 		else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff))
@@ -820,11 +832,8 @@ void show_stack(struct task_struct *task, unsigned long *stack)
 	decode_address(buf, (unsigned int)stack);
 	printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf);
 
-	addr = (unsigned int *)((unsigned int)stack & ~0x3F);
-
 	/* First thing is to look for a frame pointer */
-	for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0;
-		addr < endstack; addr++, i++) {
+	for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) {
 		if (*addr & 0x1)
 			continue;
 		ins_addr = (unsigned short *)*addr;
@@ -834,7 +843,8 @@ void show_stack(struct task_struct *task, unsigned long *stack)
 
 		if (fp) {
 			/* Let's check to see if it is a frame pointer */
-			while (fp >= (addr - 1) && fp < endstack && fp)
+			while (fp >= (addr - 1) && fp < endstack
+			       && fp && ((unsigned int) fp & 0x3) == 0)
 				fp = (unsigned int *)*fp;
 			if (fp == 0 || fp == endstack) {
 				fp = addr - 1;
@@ -1052,8 +1062,9 @@ void show_regs(struct pt_regs *fp)
 	char buf [150];
 	struct irqaction *action;
 	unsigned int i;
-	unsigned long flags;
+	unsigned long flags = 0;
 	unsigned int cpu = smp_processor_id();
+	unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic();
 
 	verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted());
 	verbose_printk(KERN_NOTICE " SEQSTAT: %08lx  IPEND: %04lx  SYSCFG: %04lx\n",
@@ -1073,17 +1084,22 @@ void show_regs(struct pt_regs *fp)
 	}
 	verbose_printk(KERN_NOTICE "  EXCAUSE   : 0x%lx\n",
 		fp->seqstat & SEQSTAT_EXCAUSE);
-	for (i = 6; i <= 15 ; i++) {
+	for (i = 2; i <= 15 ; i++) {
 		if (fp->ipend & (1 << i)) {
-			decode_address(buf, bfin_read32(EVT0 + 4*i));
-			verbose_printk(KERN_NOTICE "  physical IVG%i asserted : %s\n", i, buf);
+			if (i != 4) {
+				decode_address(buf, bfin_read32(EVT0 + 4*i));
+				verbose_printk(KERN_NOTICE "  physical IVG%i asserted : %s\n", i, buf);
+			} else
+				verbose_printk(KERN_NOTICE "  interrupts disabled\n");
 		}
 	}
 
 	/* if no interrupts are going off, don't print this out */
 	if (fp->ipend & ~0x3F) {
 		for (i = 0; i < (NR_IRQS - 1); i++) {
-			spin_lock_irqsave(&irq_desc[i].lock, flags);
+			if (!in_atomic)
+				spin_lock_irqsave(&irq_desc[i].lock, flags);
+
 			action = irq_desc[i].action;
 			if (!action)
 				goto unlock;
@@ -1096,7 +1112,8 @@ void show_regs(struct pt_regs *fp)
 			}
 			verbose_printk("\n");
 unlock:
-			spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+			if (!in_atomic)
+				spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 		}
 	}
 
diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c
index 15f1351c8645..0e175342112e 100644
--- a/arch/blackfin/mach-bf518/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf518/boards/ezbrd.c
@@ -46,6 +46,7 @@
 #include <asm/dpmc.h>
 #include <asm/bfin_sdh.h>
 #include <linux/spi/ad7877.h>
+#include <net/dsa.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -104,8 +105,31 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+	.name = "bfin_mii_bus",
+};
+
 static struct platform_device bfin_mac_device = {
 	.name = "bfin_mac",
+	.dev.platform_data = &bfin_mii_bus,
+};
+#endif
+
+#if defined(CONFIG_NET_DSA_KSZ8893M) || defined(CONFIG_NET_DSA_KSZ8893M_MODULE)
+static struct dsa_platform_data ksz8893m_switch_data = {
+	.mii_bus = &bfin_mii_bus.dev,
+	.netdev = &bfin_mac_device.dev,
+	.port_names[0]	= NULL,
+	.port_names[1]	= "eth%d",
+	.port_names[2]	= "eth%d",
+	.port_names[3]	= "cpu",
+};
+
+static struct platform_device ksz8893m_switch_device = {
+	.name		= "dsa",
+	.id		= 0,
+	.num_resources	= 0,
+	.dev.platform_data = &ksz8893m_switch_data,
 };
 #endif
 
@@ -147,6 +171,15 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
+#if defined(CONFIG_NET_DSA_KSZ8893M) \
+	|| defined(CONFIG_NET_DSA_KSZ8893M_MODULE)
+/* SPI SWITCH CHIP */
+static struct bfin5xx_spi_chip spi_switch_info = {
+	.enable_dma = 0,
+	.bits_per_word = 8,
+};
+#endif
+
 #if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
 static struct bfin5xx_spi_chip spi_mmc_chip_info = {
 	.enable_dma = 1,
@@ -226,6 +259,19 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 	},
 #endif
 
+#if defined(CONFIG_NET_DSA_KSZ8893M) \
+	|| defined(CONFIG_NET_DSA_KSZ8893M_MODULE)
+	{
+		.modalias = "ksz8893m",
+		.max_speed_hz = 5000000,
+		.bus_num = 0,
+		.chip_select = 1,
+		.platform_data = NULL,
+		.controller_data = &spi_switch_info,
+		.mode = SPI_MODE_3,
+	},
+#endif
+
 #if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
 	{
 		.modalias = "spi_mmc_dummy",
@@ -473,7 +519,6 @@ static struct platform_device i2c_bfin_twi_device = {
 };
 #endif
 
-#ifdef CONFIG_I2C_BOARDINFO
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE)
 	{
@@ -487,7 +532,6 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 	},
 #endif
 };
-#endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
 static struct platform_device bfin_sport0_uart_device = {
@@ -584,9 +628,14 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	&bfin_mii_bus,
 	&bfin_mac_device,
 #endif
 
+#if defined(CONFIG_NET_DSA_KSZ8893M) || defined(CONFIG_NET_DSA_KSZ8893M_MODULE)
+	&ksz8893m_switch_device,
+#endif
+
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
 	&bfin_spi0_device,
 	&bfin_spi1_device,
@@ -632,12 +681,8 @@ static struct platform_device *stamp_devices[] __initdata = {
 static int __init ezbrd_init(void)
 {
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
-
-#ifdef CONFIG_I2C_BOARDINFO
 	i2c_register_board_info(0, bfin_i2c_board_info,
 				ARRAY_SIZE(bfin_i2c_board_info));
-#endif
-
 	platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
 	spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
 	return 0;
@@ -649,7 +694,7 @@ void native_machine_restart(char *cmd)
 {
 	/* workaround reboot hang when booting from SPI */
 	if ((bfin_read_SYSCR() & 0x7) == 0x3)
-		bfin_gpio_reset_spi0_ssel1();
+		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
 
 void bfin_get_ether_addr(char *addr)
diff --git a/arch/blackfin/mach-bf518/include/mach/portmux.h b/arch/blackfin/mach-bf518/include/mach/portmux.h
index ac16d54734d4..f618b487b2b0 100644
--- a/arch/blackfin/mach-bf518/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf518/include/mach/portmux.h
@@ -103,6 +103,8 @@
 #define P_SPI1_SSEL4	(P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(2))
 #define P_SPI1_SSEL5	(P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(2))
 
+#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL2
+
 /* SPORT Port Mux */
 #define P_SPORT0_DRPRI	(P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(0))
 #define P_SPORT0_RSCLK	(P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(0))
diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c
index a2c3578f4b6c..856c097b5317 100644
--- a/arch/blackfin/mach-bf527/boards/cm_bf527.c
+++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c
@@ -403,8 +403,13 @@ static struct platform_device isp1362_hcd_device = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+	.name = "bfin_mii_bus",
+};
+
 static struct platform_device bfin_mac_device = {
 	.name = "bfin_mac",
+	.dev.platform_data = &bfin_mii_bus,
 };
 #endif
 
@@ -793,7 +798,6 @@ static struct platform_device i2c_bfin_twi_device = {
 };
 #endif
 
-#ifdef CONFIG_I2C_BOARDINFO
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE)
 	{
@@ -809,7 +813,6 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 	},
 #endif
 };
-#endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
 static struct platform_device bfin_sport0_uart_device = {
@@ -920,6 +923,7 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	&bfin_mii_bus,
 	&bfin_mac_device,
 #endif
 
@@ -968,27 +972,23 @@ static struct platform_device *stamp_devices[] __initdata = {
 	&bfin_gpios_device,
 };
 
-static int __init stamp_init(void)
+static int __init cm_init(void)
 {
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
-
-#ifdef CONFIG_I2C_BOARDINFO
 	i2c_register_board_info(0, bfin_i2c_board_info,
 				ARRAY_SIZE(bfin_i2c_board_info));
-#endif
-
 	platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
 	spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
 	return 0;
 }
 
-arch_initcall(stamp_init);
+arch_initcall(cm_init);
 
 void native_machine_restart(char *cmd)
 {
 	/* workaround reboot hang when booting from SPI */
 	if ((bfin_read_SYSCR() & 0x7) == 0x3)
-		bfin_gpio_reset_spi0_ssel1();
+		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
 
 void bfin_get_ether_addr(char *addr)
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c
index 0314bd3355eb..83606fcdde27 100644
--- a/arch/blackfin/mach-bf527/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf527/boards/ezbrd.c
@@ -208,8 +208,13 @@ static struct platform_device rtc_device = {
 
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+	.name = "bfin_mii_bus",
+};
+
 static struct platform_device bfin_mac_device = {
 	.name = "bfin_mac",
+	.dev.platform_data = &bfin_mii_bus,
 };
 #endif
 
@@ -590,7 +595,6 @@ static struct platform_device i2c_bfin_twi_device = {
 };
 #endif
 
-#ifdef CONFIG_I2C_BOARDINFO
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE)
 	{
@@ -604,7 +608,6 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 	},
 #endif
 };
-#endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
 static struct platform_device bfin_sport0_uart_device = {
@@ -720,6 +723,7 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	&bfin_mii_bus,
 	&bfin_mac_device,
 #endif
 
@@ -764,27 +768,23 @@ static struct platform_device *stamp_devices[] __initdata = {
 	&bfin_gpios_device,
 };
 
-static int __init stamp_init(void)
+static int __init ezbrd_init(void)
 {
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
-
-#ifdef CONFIG_I2C_BOARDINFO
 	i2c_register_board_info(0, bfin_i2c_board_info,
 				ARRAY_SIZE(bfin_i2c_board_info));
-#endif
-
 	platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
 	spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
 	return 0;
 }
 
-arch_initcall(stamp_init);
+arch_initcall(ezbrd_init);
 
 void native_machine_restart(char *cmd)
 {
 	/* workaround reboot hang when booting from SPI */
 	if ((bfin_read_SYSCR() & 0x7) == 0x3)
-		bfin_gpio_reset_spi0_ssel1();
+		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
 
 void bfin_get_ether_addr(char *addr)
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 9454fb7b18c3..d0864111ef59 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -425,8 +425,13 @@ static struct platform_device isp1362_hcd_device = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+	.name = "bfin_mii_bus",
+};
+
 static struct platform_device bfin_mac_device = {
 	.name = "bfin_mac",
+	.dev.platform_data = &bfin_mii_bus,
 };
 #endif
 
@@ -830,7 +835,6 @@ static struct platform_device i2c_bfin_twi_device = {
 };
 #endif
 
-#ifdef CONFIG_I2C_BOARDINFO
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE)
 	{
@@ -844,7 +848,6 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 	},
 #endif
 };
-#endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
 static struct platform_device bfin_sport0_uart_device = {
@@ -988,6 +991,7 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	&bfin_mii_bus,
 	&bfin_mac_device,
 #endif
 
@@ -1048,27 +1052,23 @@ static struct platform_device *stamp_devices[] __initdata = {
 	&bfin_gpios_device,
 };
 
-static int __init stamp_init(void)
+static int __init ezkit_init(void)
 {
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
-
-#ifdef CONFIG_I2C_BOARDINFO
 	i2c_register_board_info(0, bfin_i2c_board_info,
 				ARRAY_SIZE(bfin_i2c_board_info));
-#endif
-
 	platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
 	spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
 	return 0;
 }
 
-arch_initcall(stamp_init);
+arch_initcall(ezkit_init);
 
 void native_machine_restart(char *cmd)
 {
 	/* workaround reboot hang when booting from SPI */
 	if ((bfin_read_SYSCR() & 0x7) == 0x3)
-		bfin_gpio_reset_spi0_ssel1();
+		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
 
 void bfin_get_ether_addr(char *addr)
diff --git a/arch/blackfin/mach-bf527/include/mach/portmux.h b/arch/blackfin/mach-bf527/include/mach/portmux.h
index 7f6da2c386bb..72b1652be4da 100644
--- a/arch/blackfin/mach-bf527/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf527/include/mach/portmux.h
@@ -73,6 +73,8 @@
 
 #define P_HWAIT		(P_DONTCARE)
 
+#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL1
+
 #define P_SPI0_SS	(P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0))
 #define P_SPI0_SSEL1	(P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(2))
 #define P_SPI0_SCK	(P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(2))
diff --git a/arch/blackfin/mach-bf533/boards/blackstamp.c b/arch/blackfin/mach-bf533/boards/blackstamp.c
index 6ee607c259ac..015c18f85e7f 100644
--- a/arch/blackfin/mach-bf533/boards/blackstamp.c
+++ b/arch/blackfin/mach-bf533/boards/blackstamp.c
@@ -309,10 +309,8 @@ static struct platform_device i2c_gpio_device = {
 };
 #endif
 
-#ifdef CONFIG_I2C_BOARDINFO
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 };
-#endif
 
 static const unsigned int cclk_vlev_datasheet[] =
 {
@@ -390,10 +388,8 @@ static int __init blackstamp_init(void)
 
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
 
-#ifdef CONFIG_I2C_BOARDINFO
 	i2c_register_board_info(0, bfin_i2c_board_info,
 				ARRAY_SIZE(bfin_i2c_board_info));
-#endif
 
 	ret = platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
 	if (ret < 0)
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index 07f9ad1e189c..db96f33f72e2 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -441,7 +441,6 @@ static struct platform_device i2c_gpio_device = {
 };
 #endif
 
-#ifdef CONFIG_I2C_BOARDINFO
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE)
 	{
@@ -461,7 +460,6 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 	},
 #endif
 };
-#endif
 
 static const unsigned int cclk_vlev_datasheet[] =
 {
@@ -550,10 +548,8 @@ static int __init stamp_init(void)
 
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
 
-#ifdef CONFIG_I2C_BOARDINFO
 	i2c_register_board_info(0, bfin_i2c_board_info,
 				ARRAY_SIZE(bfin_i2c_board_info));
-#endif
 
 	ret = platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
 	if (ret < 0)
diff --git a/arch/blackfin/mach-bf533/include/mach/portmux.h b/arch/blackfin/mach-bf533/include/mach/portmux.h
index 685a2651dcda..2f59ce0b0cb5 100644
--- a/arch/blackfin/mach-bf533/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf533/include/mach/portmux.h
@@ -54,14 +54,11 @@
 #define P_SPI0_SSEL2	(P_DEFINED | P_IDENT(GPIO_PF2))
 #define P_SPI0_SSEL1	(P_DEFINED | P_IDENT(GPIO_PF1))
 #define P_SPI0_SS	(P_DEFINED | P_IDENT(GPIO_PF0))
+#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL2
 
 #define P_TMR2		(P_DONTCARE)
 #define P_TMR1		(P_DONTCARE)
 #define P_TMR0		(P_DONTCARE)
 #define P_TMRCLK	(P_DEFINED | P_IDENT(GPIO_PF1))
 
-
-
-
-
 #endif /* _MACH_PORTMUX_H_ */
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c
index 6ac8e4d5bd38..9cd8fb2a30d3 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537.c
@@ -479,8 +479,13 @@ static struct platform_device bfin_sport1_uart_device = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+	.name = "bfin_mii_bus",
+};
+
 static struct platform_device bfin_mac_device = {
 	.name = "bfin_mac",
+	.dev.platform_data = &bfin_mii_bus,
 };
 #endif
 
@@ -591,6 +596,7 @@ static struct platform_device *cm_bf537_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	&bfin_mii_bus,
 	&bfin_mac_device,
 #endif
 
diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c
index dd6e6bfb98ea..da710fdc4569 100644
--- a/arch/blackfin/mach-bf537/boards/generic_board.c
+++ b/arch/blackfin/mach-bf537/boards/generic_board.c
@@ -262,8 +262,13 @@ static struct platform_device isp1362_hcd_device = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+	.name = "bfin_mii_bus",
+};
+
 static struct platform_device bfin_mac_device = {
 	.name = "bfin_mac",
+	.dev.platform_data = &bfin_mii_bus,
 };
 #endif
 
@@ -662,6 +667,7 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	&bfin_mii_bus,
 	&bfin_mac_device,
 #endif
 
@@ -708,7 +714,7 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 };
 
-static int __init stamp_init(void)
+static int __init generic_init(void)
 {
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
 	platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
@@ -720,13 +726,13 @@ static int __init stamp_init(void)
 	return 0;
 }
 
-arch_initcall(stamp_init);
+arch_initcall(generic_init);
 
 void native_machine_restart(char *cmd)
 {
 	/* workaround reboot hang when booting from SPI */
 	if ((bfin_read_SYSCR() & 0x7) == 0x3)
-		bfin_gpio_reset_spi0_ssel1();
+		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c
index bb795341cb17..db7d3a385e4b 100644
--- a/arch/blackfin/mach-bf537/boards/minotaur.c
+++ b/arch/blackfin/mach-bf537/boards/minotaur.c
@@ -61,8 +61,13 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+	.name = "bfin_mii_bus",
+};
+
 static struct platform_device bfin_mac_device = {
 	.name = "bfin_mac",
+	.dev.platform_data = &bfin_mii_bus,
 };
 #endif
 
@@ -324,6 +329,7 @@ static struct platform_device *minotaur_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	&bfin_mii_bus,
 	&bfin_mac_device,
 #endif
 
@@ -377,5 +383,5 @@ void native_machine_restart(char *cmd)
 {
 	/* workaround reboot hang when booting from SPI */
 	if ((bfin_read_SYSCR() & 0x7) == 0x3)
-		bfin_gpio_reset_spi0_ssel1();
+		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index 89de94f4545d..590eb3a139b7 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -198,8 +198,13 @@ static struct platform_device isp1362_hcd_device = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+	.name = "bfin_mii_bus",
+};
+
 static struct platform_device bfin_mac_device = {
 	.name = "bfin_mac",
+	.dev.platform_data = &bfin_mii_bus,
 };
 #endif
 
@@ -529,6 +534,7 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	&bfin_mii_bus,
 	&bfin_mac_device,
 #endif
 
@@ -558,7 +564,7 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 };
 
-static int __init stamp_init(void)
+static int __init pnav_init(void)
 {
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
 	platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
@@ -569,7 +575,7 @@ static int __init stamp_init(void)
 	return 0;
 }
 
-arch_initcall(stamp_init);
+arch_initcall(pnav_init);
 
 void bfin_get_ether_addr(char *addr)
 {
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index d812e2514a2f..cd04c5e44878 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -321,8 +321,13 @@ static struct platform_device isp1362_hcd_device = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+	.name = "bfin_mii_bus",
+};
+
 static struct platform_device bfin_mac_device = {
 	.name = "bfin_mac",
+	.dev.platform_data = &bfin_mii_bus,
 };
 #endif
 
@@ -1068,7 +1073,6 @@ static struct adp5588_kpad_platform_data adp5588_kpad_data = {
 };
 #endif
 
-#ifdef CONFIG_I2C_BOARDINFO
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE)
 	{
@@ -1102,7 +1106,6 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 	},
 #endif
 };
-#endif
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
 static struct platform_device bfin_sport0_uart_device = {
@@ -1217,6 +1220,7 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	&bfin_mii_bus,
 	&bfin_mac_device,
 #endif
 
@@ -1284,12 +1288,8 @@ static struct platform_device *stamp_devices[] __initdata = {
 static int __init stamp_init(void)
 {
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
-
-#ifdef CONFIG_I2C_BOARDINFO
 	i2c_register_board_info(0, bfin_i2c_board_info,
 				ARRAY_SIZE(bfin_i2c_board_info));
-#endif
-
 	bfin_plat_nand_init();
 	platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
 	spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
@@ -1307,7 +1307,7 @@ void native_machine_restart(char *cmd)
 {
 	/* workaround reboot hang when booting from SPI */
 	if ((bfin_read_SYSCR() & 0x7) == 0x3)
-		bfin_gpio_reset_spi0_ssel1();
+		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
 
 /*
diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
index 2f4b066153c5..3f4f203a06ec 100644
--- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
@@ -481,8 +481,13 @@ static struct platform_device bfin_sport1_uart_device = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+	.name = "bfin_mii_bus",
+};
+
 static struct platform_device bfin_mac_device = {
 	.name = "bfin_mac",
+	.dev.platform_data = &bfin_mii_bus,
 };
 #endif
 
@@ -593,6 +598,7 @@ static struct platform_device *cm_bf537_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	&bfin_mii_bus,
 	&bfin_mac_device,
 #endif
 
@@ -615,7 +621,7 @@ static struct platform_device *cm_bf537_devices[] __initdata = {
 	&bfin_gpios_device,
 };
 
-static int __init cm_bf537_init(void)
+static int __init tcm_bf537_init(void)
 {
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
 	platform_add_devices(cm_bf537_devices, ARRAY_SIZE(cm_bf537_devices));
@@ -629,7 +635,7 @@ static int __init cm_bf537_init(void)
 	return 0;
 }
 
-arch_initcall(cm_bf537_init);
+arch_initcall(tcm_bf537_init);
 
 void bfin_get_ether_addr(char *addr)
 {
diff --git a/arch/blackfin/mach-bf537/include/mach/portmux.h b/arch/blackfin/mach-bf537/include/mach/portmux.h
index 78fee6e0f237..87285e75e903 100644
--- a/arch/blackfin/mach-bf537/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf537/include/mach/portmux.h
@@ -31,6 +31,7 @@
 #define P_PPI0_FS1	(P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(1))
 #define P_TACLK0	(P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(1))
 #define P_TMRCLK	(P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(1))
+#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL1
 
 #define P_PPI0_D0	(P_DEFINED | P_IDENT(GPIO_PG0) | P_FUNCT(0))
 #define P_PPI0_D1	(P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0))
diff --git a/arch/blackfin/mach-bf538/include/mach/portmux.h b/arch/blackfin/mach-bf538/include/mach/portmux.h
index 1e031b588b47..c8db264e3e4d 100644
--- a/arch/blackfin/mach-bf538/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf538/include/mach/portmux.h
@@ -102,5 +102,6 @@
 #define P_SPI0_SSEL2	(P_DEFINED | P_IDENT(GPIO_PF2))
 #define P_SPI0_SSEL1	(P_DEFINED | P_IDENT(GPIO_PF1))
 #define P_SPI0_SS	(P_DEFINED | P_IDENT(GPIO_PF0))
+#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL2
 
 #endif /* _MACH_PORTMUX_H_ */
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index 309c16014cae..096e661700a7 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -781,7 +781,6 @@ static struct platform_device i2c_bfin_twi1_device = {
 #endif
 #endif
 
-#ifdef CONFIG_I2C_BOARDINFO
 static struct i2c_board_info __initdata bfin_i2c_board_info0[] = {
 };
 
@@ -800,7 +799,6 @@ static struct i2c_board_info __initdata bfin_i2c_board_info1[] = {
 #endif
 };
 #endif
-#endif
 
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 #include <linux/gpio_keys.h>
@@ -956,14 +954,12 @@ static int __init ezkit_init(void)
 {
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
 
-#ifdef CONFIG_I2C_BOARDINFO
 	i2c_register_board_info(0, bfin_i2c_board_info0,
 				ARRAY_SIZE(bfin_i2c_board_info0));
 #if !defined(CONFIG_BF542)	/* The BF542 only has 1 TWI */
 	i2c_register_board_info(1, bfin_i2c_board_info1,
 				ARRAY_SIZE(bfin_i2c_board_info1));
 #endif
-#endif
 
 	platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices));
 
diff --git a/arch/blackfin/mach-bf548/include/mach/anomaly.h b/arch/blackfin/mach-bf548/include/mach/anomaly.h
index 3b5430999f4f..23d03c52f4b4 100644
--- a/arch/blackfin/mach-bf548/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf548/include/mach/anomaly.h
@@ -175,6 +175,7 @@
 #define ANOMALY_05000311 (0)
 #define ANOMALY_05000323 (0)
 #define ANOMALY_05000363 (0)
+#define ANOMALY_05000380 (0)
 #define ANOMALY_05000412 (0)
 #define ANOMALY_05000432 (0)
 #define ANOMALY_05000435 (0)
diff --git a/arch/blackfin/mach-bf548/include/mach/bf548.h b/arch/blackfin/mach-bf548/include/mach/bf548.h
index f0e569984810..cd31f72bdd82 100644
--- a/arch/blackfin/mach-bf548/include/mach/bf548.h
+++ b/arch/blackfin/mach-bf548/include/mach/bf548.h
@@ -104,6 +104,18 @@
 
 #define AMGCTLVAL	(V_AMBEN | V_AMCKEN)
 
+#if defined(CONFIG_BF542M)
+# define CONFIG_BF542
+#elif defined(CONFIG_BF544M)
+# define CONFIG_BF544
+#elif defined(CONFIG_BF547M)
+# define CONFIG_BF547
+#elif defined(CONFIG_BF548M)
+# define CONFIG_BF548
+#elif defined(CONFIG_BF549M)
+# define CONFIG_BF549
+#endif
+
 #if defined(CONFIG_BF542)
 # define CPU   "BF542"
 # define CPUID 0x27de
diff --git a/arch/blackfin/mach-bf548/include/mach/gpio.h b/arch/blackfin/mach-bf548/include/mach/gpio.h
index bba82dc75f16..3a2051709787 100644
--- a/arch/blackfin/mach-bf548/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf548/include/mach/gpio.h
@@ -195,17 +195,17 @@
 struct gpio_port_t {
 	unsigned short port_fer;
 	unsigned short dummy1;
-	unsigned short port_data;
+	unsigned short data;
 	unsigned short dummy2;
-	unsigned short port_set;
+	unsigned short data_set;
 	unsigned short dummy3;
-	unsigned short port_clear;
+	unsigned short data_clear;
 	unsigned short dummy4;
-	unsigned short port_dir_set;
+	unsigned short dir_set;
 	unsigned short dummy5;
-	unsigned short port_dir_clear;
+	unsigned short dir_clear;
 	unsigned short dummy6;
-	unsigned short port_inen;
+	unsigned short inen;
 	unsigned short dummy7;
 	unsigned int port_mux;
 };
diff --git a/arch/blackfin/mach-bf548/include/mach/portmux.h b/arch/blackfin/mach-bf548/include/mach/portmux.h
index 8177a567dcdb..ffb1d0a44b4d 100644
--- a/arch/blackfin/mach-bf548/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf548/include/mach/portmux.h
@@ -125,6 +125,7 @@
 #define P_KEY_COL2	(P_DEFINED | P_IDENT(GPIO_PD14) | P_FUNCT(3))
 #define P_KEY_COL3	(P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(3))
 
+#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL1
 #define P_SPI0_SCK	(P_DEFINED | P_IDENT(GPIO_PE0) | P_FUNCT(0))
 #define P_SPI0_MISO	(P_DEFINED | P_IDENT(GPIO_PE1) | P_FUNCT(0))
 #define P_SPI0_MOSI	(P_DEFINED | P_IDENT(GPIO_PE2) | P_FUNCT(0))
diff --git a/arch/blackfin/mach-bf561/include/mach/defBF561.h b/arch/blackfin/mach-bf561/include/mach/defBF561.h
index d7c509759659..cf922295f4ce 100644
--- a/arch/blackfin/mach-bf561/include/mach/defBF561.h
+++ b/arch/blackfin/mach-bf561/include/mach/defBF561.h
@@ -1106,6 +1106,8 @@
 #define DLEN_8		     0x0	/* PPI Data Length mask for DLEN=8 */
 #define DLEN(x)	(((x-9) & 0x07) << 11)	/* PPI Data Length (only works for x=10-->x=16) */
 #define POL                  0x0000C000	/* PPI Signal Polarities       */
+#define	POLC		0x4000		/* PPI Clock Polarity */
+#define	POLS		0x8000		/* PPI Frame Sync Polarity */
 
 /* PPI_STATUS Masks */
 #define FLD	             0x00000400	/* Field Indicator   */
diff --git a/arch/blackfin/mach-bf561/include/mach/portmux.h b/arch/blackfin/mach-bf561/include/mach/portmux.h
index a6ee8206efb6..2e5ad6347dea 100644
--- a/arch/blackfin/mach-bf561/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf561/include/mach/portmux.h
@@ -85,5 +85,6 @@
 #define P_SPI0_MOSI	(P_DONTCARE)
 #define P_SPI0_MISO	(P_DONTCARE)
 #define P_SPI0_SCK	(P_DONTCARE)
+#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL2
 
 #endif /* _MACH_PORTMUX_H_ */
diff --git a/arch/blackfin/mach-common/clocks-init.c b/arch/blackfin/mach-common/clocks-init.c
index 5d182abefc7b..9dddb6f8cc85 100644
--- a/arch/blackfin/mach-common/clocks-init.c
+++ b/arch/blackfin/mach-common/clocks-init.c
@@ -14,6 +14,7 @@
 #include <asm/clocks.h>
 #include <asm/mem_init.h>
 
+#define SDGCTL_WIDTH (1 << 31)	/* SDRAM external data path width */
 #define PLL_CTL_VAL \
 	(((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \
 	 (PLL_BYPASS << 8) | (ANOMALY_05000265 ? 0x8000 : 0))
@@ -76,7 +77,7 @@ void init_clocks(void)
 	bfin_write_PLL_DIV(CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
 #ifdef EBIU_SDGCTL
 	bfin_write_EBIU_SDRRC(mem_SDRRC);
-	bfin_write_EBIU_SDGCTL(mem_SDGCTL);
+	bfin_write_EBIU_SDGCTL((bfin_read_EBIU_SDGCTL() & SDGCTL_WIDTH) | mem_SDGCTL);
 #else
 	bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() & ~(SRREQ));
 	do_sync();
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index fae774651374..88de053bbe8e 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -151,13 +151,6 @@ ENTRY(_ex_syscall)
 	jump.s _bfin_return_from_exception;
 ENDPROC(_ex_syscall)
 
-ENTRY(_ex_soft_bp)
-	r7 = retx;
-	r7 += -2;
-	retx = r7;
-	jump.s _ex_trap_c;
-ENDPROC(_ex_soft_bp)
-
 ENTRY(_ex_single_step)
 	/* If we just returned from an interrupt, the single step event is
 	   for the RTI instruction.  */
@@ -1087,7 +1080,7 @@ ENTRY(_ex_table)
 	 * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined
 	 */
 	.long _ex_syscall       /* 0x00 - User Defined - Linux Syscall */
-	.long _ex_soft_bp       /* 0x01 - User Defined - Software breakpoint */
+	.long _ex_trap_c        /* 0x01 - User Defined - Software breakpoint */
 #ifdef	CONFIG_KGDB
 	.long _ex_trap_c	/* 0x02 - User Defined - KGDB initial connection
 							 and break signal trap */
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S
index e1e42c029e15..698d4c05947e 100644
--- a/arch/blackfin/mach-common/head.S
+++ b/arch/blackfin/mach-common/head.S
@@ -17,6 +17,19 @@
 
 __INIT
 
+ENTRY(__init_clear_bss)
+	r2 = r2 - r1;
+	cc = r2 == 0;
+	if cc jump .L_bss_done;
+	r2 >>= 2;
+	p1 = r1;
+	p2 = r2;
+	lsetup (1f, 1f) lc0 = p2;
+1:	[p1++] = r0;
+.L_bss_done:
+	rts;
+ENDPROC(__init_clear_bss)
+
 #define INITIAL_STACK	(L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
 
 ENTRY(__start)
@@ -144,6 +157,35 @@ ENTRY(__start)
 	call _init_early_exception_vectors;
 #endif
 
+	r0 = 0 (x);
+	/* Zero out all of the fun bss regions */
+#if L1_DATA_A_LENGTH > 0
+	r1.l = __sbss_l1;
+	r1.h = __sbss_l1;
+	r2.l = __ebss_l1;
+	r2.h = __ebss_l1;
+	call __init_clear_bss
+#endif
+#if L1_DATA_B_LENGTH > 0
+	r1.l = __sbss_b_l1;
+	r1.h = __sbss_b_l1;
+	r2.l = __ebss_b_l1;
+	r2.h = __ebss_b_l1;
+	call __init_clear_bss
+#endif
+#if L2_LENGTH > 0
+	r1.l = __sbss_l2;
+	r1.h = __sbss_l2;
+	r2.l = __ebss_l2;
+	r2.h = __ebss_l2;
+	call __init_clear_bss
+#endif
+	r1.l = ___bss_start;
+	r1.h = ___bss_start;
+	r2.l = ___bss_stop;
+	r2.h = ___bss_stop;
+	call __init_clear_bss
+
 	/* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
 	call _bfin_relocate_l1_mem;
 #ifdef CONFIG_BFIN_KERNEL_CLOCK
@@ -185,19 +227,6 @@ ENDPROC(__start)
 # define WDOG_CTL WDOGA_CTL
 #endif
 
-ENTRY(__init_clear_bss)
-	r2 = r2 - r1;
-	cc = r2 == 0;
-	if cc jump .L_bss_done;
-	r2 >>= 2;
-	p1 = r1;
-	p2 = r2;
-	lsetup (1f, 1f) lc0 = p2;
-1:	[p1++] = r0;
-.L_bss_done:
-	rts;
-ENDPROC(__init_clear_bss)
-
 ENTRY(_real_start)
 	/* Enable nested interrupts */
 	[--sp] = reti;
@@ -209,35 +238,6 @@ ENTRY(_real_start)
 	w[p0] = r0;
 	ssync;
 
-	r0 = 0 (x);
-	/* Zero out all of the fun bss regions */
-#if L1_DATA_A_LENGTH > 0
-	r1.l = __sbss_l1;
-	r1.h = __sbss_l1;
-	r2.l = __ebss_l1;
-	r2.h = __ebss_l1;
-	call __init_clear_bss
-#endif
-#if L1_DATA_B_LENGTH > 0
-	r1.l = __sbss_b_l1;
-	r1.h = __sbss_b_l1;
-	r2.l = __ebss_b_l1;
-	r2.h = __ebss_b_l1;
-	call __init_clear_bss
-#endif
-#if L2_LENGTH > 0
-	r1.l = __sbss_l2;
-	r1.h = __sbss_l2;
-	r2.l = __ebss_l2;
-	r2.h = __ebss_l2;
-	call __init_clear_bss
-#endif
-	r1.l = ___bss_start;
-	r1.h = ___bss_start;
-	r2.l = ___bss_stop;
-	r2.h = ___bss_stop;
-	call __init_clear_bss
-
 	/* Pass the u-boot arguments to the global value command line */
 	R0 = R7;
 	call _cmdline_init;
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S
index 473df0f7fa78..43c4eb9acb65 100644
--- a/arch/blackfin/mach-common/interrupt.S
+++ b/arch/blackfin/mach-common/interrupt.S
@@ -195,7 +195,7 @@ ENDPROC(_evt_ivhw)
 /* Interrupt routine for evt2 (NMI).
  * We don't actually use this, so just return.
  * For inner circle type details, please see:
- * http://docs.blackfin.uclinux.org/doku.php?id=linux:nmi
+ * http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:nmi
  */
 ENTRY(_evt_nmi)
 .weak _evt_nmi
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 1bba6030dce9..202494568c6c 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -1101,10 +1101,9 @@ int __init init_arch_irq(void)
 	    IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
 	    IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
 
-#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) \
-	|| defined(BF538_FAMILY) || defined(CONFIG_BF51x)
+#ifdef SIC_IWR0
 	bfin_write_SIC_IWR0(IWR_DISABLE_ALL);
-#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
+# ifdef SIC_IWR1
 	/* BF52x/BF51x system reset does not properly reset SIC_IWR1 which
 	 * will screw up the bootrom as it relies on MDMA0/1 waking it
 	 * up from IDLE instructions.  See this report for more info:
@@ -1114,10 +1113,8 @@ int __init init_arch_irq(void)
 		bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11));
 	else
 		bfin_write_SIC_IWR1(IWR_DISABLE_ALL);
-#else
-	bfin_write_SIC_IWR1(IWR_DISABLE_ALL);
-#endif
-# ifdef CONFIG_BF54x
+# endif
+# ifdef SIC_IWR2
 	bfin_write_SIC_IWR2(IWR_DISABLE_ALL);
 # endif
 #else
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index d3d70fd67c16..f48a6aebb49b 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -82,10 +82,9 @@ void bfin_pm_suspend_standby_enter(void)
 
 	bfin_pm_standby_restore();
 
-#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)  || defined(CONFIG_BF561) || \
-	defined(CONFIG_BF538) || defined(CONFIG_BF539) || defined(CONFIG_BF51x)
+#ifdef SIC_IWR0
 	bfin_write_SIC_IWR0(IWR_DISABLE_ALL);
-#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
+# ifdef SIC_IWR1
 	/* BF52x system reset does not properly reset SIC_IWR1 which
 	 * will screw up the bootrom as it relies on MDMA0/1 waking it
 	 * up from IDLE instructions.  See this report for more info:
@@ -95,10 +94,8 @@ void bfin_pm_suspend_standby_enter(void)
 		bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11));
 	else
 		bfin_write_SIC_IWR1(IWR_DISABLE_ALL);
-#else
-	bfin_write_SIC_IWR1(IWR_DISABLE_ALL);
-#endif
-# ifdef CONFIG_BF54x
+# endif
+# ifdef SIC_IWR2
 	bfin_write_SIC_IWR2(IWR_DISABLE_ALL);
 # endif
 #else
diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c
index c5a214026a77..d0223abbbbd4 100644
--- a/arch/ia64/sn/kernel/io_acpi_init.c
+++ b/arch/ia64/sn/kernel/io_acpi_init.c
@@ -443,7 +443,7 @@ sn_acpi_slot_fixup(struct pci_dev *dev)
 		size = pci_resource_len(dev, PCI_ROM_RESOURCE);
 		addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE],
 			       size);
-		image_size = pci_get_rom_size(addr, size);
+		image_size = pci_get_rom_size(dev, addr, size);
 		dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr;
 		dev->resource[PCI_ROM_RESOURCE].end =
 					(unsigned long) addr + image_size - 1;
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 4e1801bad83a..e2eb2da60f96 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -269,7 +269,7 @@ sn_io_slot_fixup(struct pci_dev *dev)
 
 			rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE),
 				      size + 1);
-			image_size = pci_get_rom_size(rom, size + 1);
+			image_size = pci_get_rom_size(dev, rom, size + 1);
 			dev->resource[PCI_ROM_RESOURCE].end =
 				dev->resource[PCI_ROM_RESOURCE].start +
 				image_size - 1;
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 52c80c2a57f2..600eef3f3ac7 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -351,7 +351,7 @@ config SGI_IP27
 	select ARC64
 	select BOOT_ELF64
 	select DEFAULT_SGI_PARTITION
-	select DMA_IP27
+	select DMA_COHERENT
 	select SYS_HAS_EARLY_PRINTK
 	select HW_HAS_PCI
 	select NR_CPUS_DEFAULT_64
@@ -761,9 +761,6 @@ config CFE
 config DMA_COHERENT
 	bool
 
-config DMA_IP27
-	bool
-
 config DMA_NONCOHERENT
 	bool
 	select DMA_NEED_PCI_MAP_STATE
@@ -1368,7 +1365,7 @@ config CPU_SUPPORTS_64BIT_KERNEL
 #
 config HARDWARE_WATCHPOINTS
        bool
-       default y if CPU_MIPS32 || CPU_MIPS64
+       default y if CPU_MIPSR1 || CPU_MIPSR2
 
 menu "Kernel type"
 
diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c
index 32880146cbc1..6fd441d16af5 100644
--- a/arch/mips/alchemy/common/time.c
+++ b/arch/mips/alchemy/common/time.c
@@ -89,7 +89,7 @@ static struct clock_event_device au1x_rtcmatch2_clockdev = {
 	.irq		= AU1000_RTC_MATCH2_INT,
 	.set_next_event	= au1x_rtcmatch2_set_next_event,
 	.set_mode	= au1x_rtcmatch2_set_mode,
-	.cpumask	= CPU_MASK_ALL,
+	.cpumask	= CPU_MASK_ALL_PTR,
 };
 
 static struct irqaction au1x_rtcmatch2_irqaction = {
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index e085feddb4a4..5f4e49ba4713 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -15,13 +15,11 @@
 #include <linux/serial.h>
 #include <linux/types.h>
 #include <linux/string.h>	/* for memset */
-#include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/time.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
-#include <linux/string.h>
 
 #include <asm/processor.h>
 #include <asm/reboot.h>
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 34ea319be94c..f2baea3039bb 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -53,7 +53,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_ARC=y
-CONFIG_DMA_IP27=y
+CONFIG_DMA_COHERENT=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_SYS_HAS_EARLY_PRINTK=y
 # CONFIG_NO_IOPORT is not set
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
index c996c3b4d074..1b332e15ab52 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -50,7 +50,7 @@
 static __inline__ void atomic_add(int i, atomic_t * v)
 {
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
-		unsigned long temp;
+		int temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -62,7 +62,7 @@ static __inline__ void atomic_add(int i, atomic_t * v)
 		: "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter));
 	} else if (cpu_has_llsc) {
-		unsigned long temp;
+		int temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -95,7 +95,7 @@ static __inline__ void atomic_add(int i, atomic_t * v)
 static __inline__ void atomic_sub(int i, atomic_t * v)
 {
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
-		unsigned long temp;
+		int temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -107,7 +107,7 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
 		: "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter));
 	} else if (cpu_has_llsc) {
-		unsigned long temp;
+		int temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -135,12 +135,12 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
  */
 static __inline__ int atomic_add_return(int i, atomic_t * v)
 {
-	unsigned long result;
+	int result;
 
 	smp_llsc_mb();
 
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
-		unsigned long temp;
+		int temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -154,7 +154,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
 		: "Ir" (i), "m" (v->counter)
 		: "memory");
 	} else if (cpu_has_llsc) {
-		unsigned long temp;
+		int temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -187,12 +187,12 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
 
 static __inline__ int atomic_sub_return(int i, atomic_t * v)
 {
-	unsigned long result;
+	int result;
 
 	smp_llsc_mb();
 
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
-		unsigned long temp;
+		int temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -206,7 +206,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
 		: "Ir" (i), "m" (v->counter)
 		: "memory");
 	} else if (cpu_has_llsc) {
-		unsigned long temp;
+		int temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -247,12 +247,12 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
  */
 static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
 {
-	unsigned long result;
+	int result;
 
 	smp_llsc_mb();
 
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
-		unsigned long temp;
+		int temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -270,7 +270,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
 		: "Ir" (i), "m" (v->counter)
 		: "memory");
 	} else if (cpu_has_llsc) {
-		unsigned long temp;
+		int temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -429,7 +429,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
 static __inline__ void atomic64_add(long i, atomic64_t * v)
 {
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
-		unsigned long temp;
+		long temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -441,7 +441,7 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
 		: "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter));
 	} else if (cpu_has_llsc) {
-		unsigned long temp;
+		long temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -474,7 +474,7 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
 static __inline__ void atomic64_sub(long i, atomic64_t * v)
 {
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
-		unsigned long temp;
+		long temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -486,7 +486,7 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
 		: "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter));
 	} else if (cpu_has_llsc) {
-		unsigned long temp;
+		long temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -514,12 +514,12 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
  */
 static __inline__ long atomic64_add_return(long i, atomic64_t * v)
 {
-	unsigned long result;
+	long result;
 
 	smp_llsc_mb();
 
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
-		unsigned long temp;
+		long temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -533,7 +533,7 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
 		: "Ir" (i), "m" (v->counter)
 		: "memory");
 	} else if (cpu_has_llsc) {
-		unsigned long temp;
+		long temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -566,12 +566,12 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
 
 static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
 {
-	unsigned long result;
+	long result;
 
 	smp_llsc_mb();
 
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
-		unsigned long temp;
+		long temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -585,7 +585,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
 		: "Ir" (i), "m" (v->counter)
 		: "memory");
 	} else if (cpu_has_llsc) {
-		unsigned long temp;
+		long temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -626,12 +626,12 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
  */
 static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
 {
-	unsigned long result;
+	long result;
 
 	smp_llsc_mb();
 
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
-		unsigned long temp;
+		long temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
@@ -649,7 +649,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
 		: "Ir" (i), "m" (v->counter)
 		: "memory");
 	} else if (cpu_has_llsc) {
-		unsigned long temp;
+		long temp;
 
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
diff --git a/arch/mips/include/asm/mach-rc32434/gpio.h b/arch/mips/include/asm/mach-rc32434/gpio.h
index b5cf6457305a..3cb50d17b62d 100644
--- a/arch/mips/include/asm/mach-rc32434/gpio.h
+++ b/arch/mips/include/asm/mach-rc32434/gpio.h
@@ -80,11 +80,8 @@ struct rb532_gpio_reg {
 /* Compact Flash GPIO pin */
 #define CF_GPIO_NUM		13
 
-extern void set_434_reg(unsigned reg_offs, unsigned bit, unsigned len, unsigned val);
-extern unsigned get_434_reg(unsigned reg_offs);
-extern void set_latch_u5(unsigned char or_mask, unsigned char nand_mask);
-extern unsigned char get_latch_u5(void);
 extern void rb532_gpio_set_ilevel(int bit, unsigned gpio);
 extern void rb532_gpio_set_istat(int bit, unsigned gpio);
+extern void rb532_gpio_set_func(unsigned gpio);
 
 #endif /* _RC32434_GPIO_H_ */
diff --git a/arch/mips/include/asm/mach-rc32434/irq.h b/arch/mips/include/asm/mach-rc32434/irq.h
index 56738d8ec4e2..023a5b100ed0 100644
--- a/arch/mips/include/asm/mach-rc32434/irq.h
+++ b/arch/mips/include/asm/mach-rc32434/irq.h
@@ -30,4 +30,7 @@
 #define ETH0_RX_OVR_IRQ   	(GROUP3_IRQ_BASE + 9)
 #define ETH0_TX_UND_IRQ   	(GROUP3_IRQ_BASE + 10)
 
+#define GPIO_MAPPED_IRQ_BASE	GROUP4_IRQ_BASE
+#define GPIO_MAPPED_IRQ_GROUP	4
+
 #endif  /* __ASM_RC32434_IRQ_H */
diff --git a/arch/mips/include/asm/mach-rc32434/rb.h b/arch/mips/include/asm/mach-rc32434/rb.h
index f25a84916703..6dc5f8df1f3e 100644
--- a/arch/mips/include/asm/mach-rc32434/rb.h
+++ b/arch/mips/include/asm/mach-rc32434/rb.h
@@ -83,4 +83,7 @@ struct mpmc_device {
 	void __iomem 	*base;
 };
 
+extern void set_latch_u5(unsigned char or_mask, unsigned char nand_mask);
+extern unsigned char get_latch_u5(void);
+
 #endif  /* __ASM_RC32434_RB_H */
diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h
index 1f30d16d4669..ce47118e52b7 100644
--- a/arch/mips/include/asm/ptrace.h
+++ b/arch/mips/include/asm/ptrace.h
@@ -105,7 +105,7 @@ struct pt_watch_regs {
 	enum pt_watch_style style;
 	union {
 		struct mips32_watch_regs mips32;
-		struct mips32_watch_regs mips64;
+		struct mips64_watch_regs mips64;
 	};
 };
 
diff --git a/arch/mips/include/asm/termios.h b/arch/mips/include/asm/termios.h
index a275661fa7e1..8f77f774a2a0 100644
--- a/arch/mips/include/asm/termios.h
+++ b/arch/mips/include/asm/termios.h
@@ -9,6 +9,7 @@
 #ifndef _ASM_TERMIOS_H
 #define _ASM_TERMIOS_H
 
+#include <linux/errno.h>
 #include <asm/termbits.h>
 #include <asm/ioctls.h>
 
@@ -94,38 +95,81 @@ struct termio {
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-#define user_termio_to_kernel_termios(termios, termio) \
-({ \
-	unsigned short tmp; \
-	get_user(tmp, &(termio)->c_iflag); \
-	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
-	get_user(tmp, &(termio)->c_oflag); \
-	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
-	get_user(tmp, &(termio)->c_cflag); \
-	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
-	get_user(tmp, &(termio)->c_lflag); \
-	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
-	get_user((termios)->c_line, &(termio)->c_line); \
-	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
-})
+static inline int user_termio_to_kernel_termios(struct ktermios *termios,
+	struct termio __user *termio)
+{
+	unsigned short iflag, oflag, cflag, lflag;
+	unsigned int err;
+
+	if (!access_ok(VERIFY_READ, termio, sizeof(struct termio)))
+		return -EFAULT;
+
+	err = __get_user(iflag, &termio->c_iflag);
+	termios->c_iflag = (termios->c_iflag & 0xffff0000) | iflag;
+	err |=__get_user(oflag, &termio->c_oflag);
+	termios->c_oflag = (termios->c_oflag & 0xffff0000) | oflag;
+	err |=__get_user(cflag, &termio->c_cflag);
+	termios->c_cflag = (termios->c_cflag & 0xffff0000) | cflag;
+	err |=__get_user(lflag, &termio->c_lflag);
+	termios->c_lflag = (termios->c_lflag & 0xffff0000) | lflag;
+	err |=__get_user(termios->c_line, &termio->c_line);
+	if (err)
+		return -EFAULT;
+
+	if (__copy_from_user(termios->c_cc, termio->c_cc, NCC))
+		return -EFAULT;
+
+	return 0;
+}
 
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  */
-#define kernel_termios_to_user_termio(termio, termios) \
-({ \
-	put_user((termios)->c_iflag, &(termio)->c_iflag); \
-	put_user((termios)->c_oflag, &(termio)->c_oflag); \
-	put_user((termios)->c_cflag, &(termio)->c_cflag); \
-	put_user((termios)->c_lflag, &(termio)->c_lflag); \
-	put_user((termios)->c_line, &(termio)->c_line); \
-	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
-})
-
-#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
-#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
-#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
+static inline int kernel_termios_to_user_termio(struct termio __user *termio,
+	struct ktermios *termios)
+{
+	int err;
+
+	if (!access_ok(VERIFY_WRITE, termio, sizeof(struct termio)))
+		return -EFAULT;
+
+	err = __put_user(termios->c_iflag, &termio->c_iflag);
+	err |= __put_user(termios->c_oflag, &termio->c_oflag);
+	err |= __put_user(termios->c_cflag, &termio->c_cflag);
+	err |= __put_user(termios->c_lflag, &termio->c_lflag);
+	err |= __put_user(termios->c_line, &termio->c_line);
+	if (err)
+		return -EFAULT;
+
+	if (__copy_to_user(termio->c_cc, termios->c_cc, NCC))
+		return -EFAULT;
+
+	return 0;
+}
+
+static inline int user_termios_to_kernel_termios(struct ktermios __user *k,
+	struct termios2 *u)
+{
+	return copy_from_user(k, u, sizeof(struct termios2)) ? -EFAULT : 0;
+}
+
+static inline int kernel_termios_to_user_termios(struct termios2 __user *u,
+	struct ktermios *k)
+{
+	return copy_to_user(u, k, sizeof(struct termios2)) ? -EFAULT : 0;
+}
+
+static inline int user_termios_to_kernel_termios_1(struct ktermios *k,
+	struct termios __user *u)
+{
+	return copy_from_user(k, u, sizeof(struct termios)) ? -EFAULT : 0;
+}
+
+static inline int kernel_termios_to_user_termios_1(struct termios __user *u,
+	struct ktermios *k)
+{
+	return copy_to_user(u, k, sizeof(struct termios)) ? -EFAULT : 0;
+}
 
 #endif /* defined(__KERNEL__) */
 
diff --git a/arch/mips/include/asm/txx9/tx4939.h b/arch/mips/include/asm/txx9/tx4939.h
index 88badb423010..964ef7ede268 100644
--- a/arch/mips/include/asm/txx9/tx4939.h
+++ b/arch/mips/include/asm/txx9/tx4939.h
@@ -541,5 +541,6 @@ void tx4939_irq_init(void);
 int tx4939_irq(void);
 void tx4939_mtd_init(int ch);
 void tx4939_ata_init(void);
+void tx4939_rtc_init(void);
 
 #endif /* __ASM_TXX9_TX4939_H */
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index fb6f73148df2..8882e5766f27 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -458,7 +458,11 @@ NESTED(nmi_handler, PT_SIZE, sp)
 	BUILD_HANDLER fpe fpe fpe silent		/* #15 */
 	BUILD_HANDLER mdmx mdmx sti silent		/* #22 */
 #ifdef 	CONFIG_HARDWARE_WATCHPOINTS
-	BUILD_HANDLER watch watch sti silent		/* #23 */
+	/*
+	 * For watch, interrupts will be enabled after the watch
+	 * registers are read.
+	 */
+	BUILD_HANDLER watch watch cli silent		/* #23 */
 #else
 	BUILD_HANDLER watch watch sti verbose		/* #23 */
 #endif
diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
index 5e77a3a21f98..42461310b185 100644
--- a/arch/mips/kernel/mips-mt-fpaff.c
+++ b/arch/mips/kernel/mips-mt-fpaff.c
@@ -79,7 +79,8 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
 
 	euid = current_euid();
 	retval = -EPERM;
-	if (euid != p->euid && euid != p->uid && !capable(CAP_SYS_NICE)) {
+	if (euid != p->cred->euid && euid != p->cred->uid &&
+	    !capable(CAP_SYS_NICE)) {
 		read_unlock(&tasklist_lock);
 		goto out_unlock;
 	}
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index f6083c6bfaa4..b2d7041341b8 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -944,6 +944,9 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
 	force_sig(SIGILL, current);
 }
 
+/*
+ * Called with interrupts disabled.
+ */
 asmlinkage void do_watch(struct pt_regs *regs)
 {
 	u32 cause;
@@ -963,9 +966,12 @@ asmlinkage void do_watch(struct pt_regs *regs)
 	 */
 	if (test_tsk_thread_flag(current, TIF_LOAD_WATCH)) {
 		mips_read_watch_registers();
+		local_irq_enable();
 		force_sig(SIGTRAP, current);
-	} else
+	} else {
 		mips_clear_watch_registers();
+		local_irq_enable();
+	}
 }
 
 asmlinkage void do_mcheck(struct pt_regs *regs)
@@ -1582,7 +1588,11 @@ void __init set_handler(unsigned long offset, void *addr, unsigned long size)
 static char panic_null_cerr[] __cpuinitdata =
 	"Trying to set NULL cache error exception handler";
 
-/* Install uncached CPU exception handler */
+/*
+ * Install uncached CPU exception handler.
+ * This is suitable only for the cache error exception which is the only
+ * exception handler that is being run uncached.
+ */
 void __cpuinit set_uncached_handler(unsigned long offset, void *addr,
 	unsigned long size)
 {
@@ -1593,7 +1603,7 @@ void __cpuinit set_uncached_handler(unsigned long offset, void *addr,
 	unsigned long uncached_ebase = TO_UNCAC(ebase);
 #endif
 	if (cpu_has_mips_r2)
-		ebase += (read_c0_ebase() & 0x3ffff000);
+		uncached_ebase += (read_c0_ebase() & 0x3ffff000);
 
 	if (!addr)
 		panic(panic_null_cerr);
diff --git a/arch/mips/lib/memcpy-inatomic.S b/arch/mips/lib/memcpy-inatomic.S
index 736d0fb56a94..68853a038d3f 100644
--- a/arch/mips/lib/memcpy-inatomic.S
+++ b/arch/mips/lib/memcpy-inatomic.S
@@ -21,7 +21,7 @@
  * end of memory on some systems.  It's also a seriously bad idea on non
  * dma-coherent systems.
  */
-#if !defined(CONFIG_DMA_COHERENT) || !defined(CONFIG_DMA_IP27)
+#ifdef CONFIG_DMA_NONCOHERENT
 #undef CONFIG_CPU_HAS_PREFETCH
 #endif
 #ifdef CONFIG_MIPS_MALTA
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
index c06cccf60bec..56a1f85a1ce8 100644
--- a/arch/mips/lib/memcpy.S
+++ b/arch/mips/lib/memcpy.S
@@ -21,7 +21,7 @@
  * end of memory on some systems.  It's also a seriously bad idea on non
  * dma-coherent systems.
  */
-#if !defined(CONFIG_DMA_COHERENT) || !defined(CONFIG_DMA_IP27)
+#ifdef CONFIG_DMA_NONCOHERENT
 #undef CONFIG_CPU_HAS_PREFETCH
 #endif
 #ifdef CONFIG_MIPS_MALTA
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 6e99665ae860..c43f4b26a690 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -618,15 +618,35 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
 	if (cpu_has_inclusive_pcaches) {
 		if (size >= scache_size)
 			r4k_blast_scache();
-		else
+		else {
+			unsigned long lsize = cpu_scache_line_size();
+			unsigned long almask = ~(lsize - 1);
+
+			/*
+			 * There is no clearly documented alignment requirement
+			 * for the cache instruction on MIPS processors and
+			 * some processors, among them the RM5200 and RM7000
+			 * QED processors will throw an address error for cache
+			 * hit ops with insufficient alignment.  Solved by
+			 * aligning the address to cache line size.
+			 */
+			cache_op(Hit_Writeback_Inv_SD, addr & almask);
+			cache_op(Hit_Writeback_Inv_SD,
+				 (addr + size - 1) & almask);
 			blast_inv_scache_range(addr, addr + size);
+		}
 		return;
 	}
 
 	if (cpu_has_safe_index_cacheops && size >= dcache_size) {
 		r4k_blast_dcache();
 	} else {
+		unsigned long lsize = cpu_dcache_line_size();
+		unsigned long almask = ~(lsize - 1);
+
 		R4600_HIT_CACHEOP_WAR_IMPL;
+		cache_op(Hit_Writeback_Inv_D, addr & almask);
+		cache_op(Hit_Writeback_Inv_D, (addr + size - 1)  & almask);
 		blast_inv_dcache_range(addr, addr + size);
 	}
 
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index fa636fc6b7b9..55767ad9f00e 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -97,7 +97,6 @@ good_area:
 			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
@@ -167,21 +166,13 @@ no_context:
 	       field,  regs->regs[31]);
 	die("Oops", regs);
 
-/*
- * We ran out of memory, or some other thing happened to us that made
- * us unable to handle the page fault gracefully.
- */
 out_of_memory:
-	up_read(&mm->mmap_sem);
-	if (is_global_init(tsk)) {
-		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;
+	/*
+	 * We ran out of memory, call the OOM killer, and return the userspace
+	 * (which will retry the fault, or kill us if we got oom-killed).
+	 */
+	pagefault_out_of_memory();
+	return;
 
 do_sigbus:
 	up_read(&mm->mmap_sem);
diff --git a/arch/mips/pci/pci-rc32434.c b/arch/mips/pci/pci-rc32434.c
index 1c2821e2f494..71f7d27b0d4c 100644
--- a/arch/mips/pci/pci-rc32434.c
+++ b/arch/mips/pci/pci-rc32434.c
@@ -205,6 +205,8 @@ static int __init rc32434_pcibridge_init(void)
 
 static int __init rc32434_pci_init(void)
 {
+	void __iomem *io_map_base;
+
 	pr_info("PCI: Initializing PCI\n");
 
 	ioport_resource.start = rc32434_res_pci_io1.start;
@@ -212,6 +214,15 @@ static int __init rc32434_pci_init(void)
 
 	rc32434_pcibridge_init();
 
+	io_map_base = ioremap(rc32434_res_pci_io1.start,
+		rc32434_res_pci_io1.end - rc32434_res_pci_io1.start + 1);
+
+	if (!io_map_base)
+		return -ENOMEM;
+
+	rc32434_controller.io_map_base =
+		(unsigned long)io_map_base - rc32434_res_pci_io1.start;
+
 	register_pci_controller(&rc32434_controller);
 	rc32434_sync();
 
diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index c1c29181bd46..4a5f05b662ae 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -24,6 +24,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/serial_8250.h>
 
 #include <asm/bootinfo.h>
 
@@ -39,6 +40,29 @@
 #define ETH0_RX_DMA_ADDR  (DMA0_BASE_ADDR + 0 * DMA_CHAN_OFFSET)
 #define ETH0_TX_DMA_ADDR  (DMA0_BASE_ADDR + 1 * DMA_CHAN_OFFSET)
 
+extern unsigned int idt_cpu_freq;
+
+static struct mpmc_device dev3;
+
+void set_latch_u5(unsigned char or_mask, unsigned char nand_mask)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev3.lock, flags);
+
+	dev3.state = (dev3.state | or_mask) & ~nand_mask;
+	writeb(dev3.state, dev3.base);
+
+	spin_unlock_irqrestore(&dev3.lock, flags);
+}
+EXPORT_SYMBOL(set_latch_u5);
+
+unsigned char get_latch_u5(void)
+{
+	return dev3.state;
+}
+EXPORT_SYMBOL(get_latch_u5);
+
 static struct resource korina_dev0_res[] = {
 	{
 		.name = "korina_regs",
@@ -86,7 +110,7 @@ static struct korina_device korina_dev0_data = {
 static struct platform_device korina_dev0 = {
 	.id = -1,
 	.name = "korina",
-	.dev.platform_data = &korina_dev0_data,
+	.dev.driver_data = &korina_dev0_data,
 	.resource = korina_dev0_res,
 	.num_resources = ARRAY_SIZE(korina_dev0_res),
 };
@@ -214,12 +238,32 @@ static struct platform_device rb532_wdt = {
 	.num_resources	= ARRAY_SIZE(rb532_wdt_res),
 };
 
+static struct plat_serial8250_port rb532_uart_res[] = {
+	{
+		.membase	= (char *)KSEG1ADDR(REGBASE + UART0BASE),
+		.irq		= UART0_IRQ,
+		.regshift	= 2,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_BOOT_AUTOCONF,
+	},
+	{
+		.flags		= 0,
+	}
+};
+
+static struct platform_device rb532_uart = {
+	.name              = "serial8250",
+	.id                = PLAT8250_DEV_PLATFORM,
+	.dev.platform_data = &rb532_uart_res,
+};
+
 static struct platform_device *rb532_devs[] = {
 	&korina_dev0,
 	&nand_slot0,
 	&cf_slot0,
 	&rb532_led,
 	&rb532_button,
+	&rb532_uart,
 	&rb532_wdt
 };
 
@@ -291,9 +335,20 @@ static int __init plat_setup_devices(void)
 	nand_slot0_res[0].start = readl(IDT434_REG_BASE + DEV2BASE);
 	nand_slot0_res[0].end = nand_slot0_res[0].start + 0x1000;
 
+	/* Read and map device controller 3 */
+	dev3.base = ioremap_nocache(readl(IDT434_REG_BASE + DEV3BASE), 1);
+
+	if (!dev3.base) {
+		printk(KERN_ERR "rb532: cannot remap device controller 3\n");
+		return -ENXIO;
+	}
+
 	/* Initialise the NAND device */
 	rb532_nand_setup();
 
+	/* set the uart clock to the current cpu frequency */
+	rb532_uart_res[0].uartclk = idt_cpu_freq;
+
 	return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
 }
 
diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c
index 0e84c8ab6a39..37de05d595e7 100644
--- a/arch/mips/rb532/gpio.c
+++ b/arch/mips/rb532/gpio.c
@@ -41,8 +41,6 @@ struct rb532_gpio_chip {
 	void __iomem	 *regbase;
 };
 
-struct mpmc_device dev3;
-
 static struct resource rb532_gpio_reg0_res[] = {
 	{
 		.name 	= "gpio_reg0",
@@ -52,61 +50,6 @@ static struct resource rb532_gpio_reg0_res[] = {
 	}
 };
 
-static struct resource rb532_dev3_ctl_res[] = {
-	{
-		.name	= "dev3_ctl",
-		.start	= REGBASE + DEV3BASE,
-		.end	= REGBASE + DEV3BASE + sizeof(struct dev_reg) - 1,
-		.flags	= IORESOURCE_MEM,
-	}
-};
-
-void set_434_reg(unsigned reg_offs, unsigned bit, unsigned len, unsigned val)
-{
-	unsigned long flags;
-	unsigned data;
-	unsigned i = 0;
-
-	spin_lock_irqsave(&dev3.lock, flags);
-
-	data = readl(IDT434_REG_BASE + reg_offs);
-	for (i = 0; i != len; ++i) {
-		if (val & (1 << i))
-			data |= (1 << (i + bit));
-		else
-			data &= ~(1 << (i + bit));
-	}
-	writel(data, (IDT434_REG_BASE + reg_offs));
-
-	spin_unlock_irqrestore(&dev3.lock, flags);
-}
-EXPORT_SYMBOL(set_434_reg);
-
-unsigned get_434_reg(unsigned reg_offs)
-{
-	return readl(IDT434_REG_BASE + reg_offs);
-}
-EXPORT_SYMBOL(get_434_reg);
-
-void set_latch_u5(unsigned char or_mask, unsigned char nand_mask)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&dev3.lock, flags);
-
-	dev3.state = (dev3.state | or_mask) & ~nand_mask;
-	writel(dev3.state, &dev3.base);
-
-	spin_unlock_irqrestore(&dev3.lock, flags);
-}
-EXPORT_SYMBOL(set_latch_u5);
-
-unsigned char get_latch_u5(void)
-{
-	return dev3.state;
-}
-EXPORT_SYMBOL(get_latch_u5);
-
 /* rb532_set_bit - sanely set a bit
  *
  * bitval: new value for the bit
@@ -119,13 +62,11 @@ static inline void rb532_set_bit(unsigned bitval,
 	unsigned long flags;
 	u32 val;
 
-	bitval = !!bitval;              /* map parameter to {0,1} */
-
 	local_irq_save(flags);
 
 	val = readl(ioaddr);
-	val &= ~( ~bitval << offset );   /* unset bit if bitval == 0 */
-	val |=  (  bitval << offset );   /* set bit if bitval == 1 */
+	val &= ~(!bitval << offset);   /* unset bit if bitval == 0 */
+	val |= (!!bitval << offset);   /* set bit if bitval == 1 */
 	writel(val, ioaddr);
 
 	local_irq_restore(flags);
@@ -171,8 +112,8 @@ static int rb532_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 
 	gpch = container_of(chip, struct rb532_gpio_chip, chip);
 
-	if (rb532_get_bit(offset, gpch->regbase + GPIOFUNC))
-		return 1;	/* alternate function, GPIOCFG is ignored */
+	/* disable alternate function in case it's set */
+	rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC);
 
 	rb532_set_bit(0, offset, gpch->regbase + GPIOCFG);
 	return 0;
@@ -188,8 +129,8 @@ static int rb532_gpio_direction_output(struct gpio_chip *chip,
 
 	gpch = container_of(chip, struct rb532_gpio_chip, chip);
 
-	if (rb532_get_bit(offset, gpch->regbase + GPIOFUNC))
-		return 1;	/* alternate function, GPIOCFG is ignored */
+	/* disable alternate function in case it's set */
+	rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC);
 
 	/* set the initial output value */
 	rb532_set_bit(value, offset, gpch->regbase + GPIOD);
@@ -233,10 +174,11 @@ EXPORT_SYMBOL(rb532_gpio_set_istat);
 /*
  * Configure GPIO alternate function
  */
-static void rb532_gpio_set_func(int bit, unsigned gpio)
+void rb532_gpio_set_func(unsigned gpio)
 {
-       rb532_set_bit(bit, gpio, rb532_gpio_chip->regbase + GPIOFUNC);
+       rb532_set_bit(1, gpio, rb532_gpio_chip->regbase + GPIOFUNC);
 }
+EXPORT_SYMBOL(rb532_gpio_set_func);
 
 int __init rb532_gpio_init(void)
 {
@@ -253,20 +195,6 @@ int __init rb532_gpio_init(void)
 	/* Register our GPIO chip */
 	gpiochip_add(&rb532_gpio_chip->chip);
 
-	r = rb532_dev3_ctl_res;
-	dev3.base = ioremap_nocache(r->start, r->end - r->start);
-
-	if (!dev3.base) {
-		printk(KERN_ERR "rb532: cannot remap device controller 3\n");
-		return -ENXIO;
-	}
-
-	/* configure CF_GPIO_NUM as CFRDY IRQ source */
-	rb532_gpio_set_func(0, CF_GPIO_NUM);
-	rb532_gpio_direction_input(&rb532_gpio_chip->chip, CF_GPIO_NUM);
-	rb532_gpio_set_ilevel(1, CF_GPIO_NUM);
-	rb532_gpio_set_istat(0, CF_GPIO_NUM);
-
 	return 0;
 }
 arch_initcall(rb532_gpio_init);
diff --git a/arch/mips/rb532/irq.c b/arch/mips/rb532/irq.c
index 549b46d2fcee..53eeb5e7bc5b 100644
--- a/arch/mips/rb532/irq.c
+++ b/arch/mips/rb532/irq.c
@@ -46,6 +46,7 @@
 #include <asm/system.h>
 
 #include <asm/mach-rc32434/irq.h>
+#include <asm/mach-rc32434/gpio.h>
 
 struct intr_group {
 	u32 mask;	/* mask of valid bits in pending/mask registers */
@@ -150,6 +151,9 @@ static void rb532_disable_irq(unsigned int irq_nr)
 		mask |= intr_bit;
 		WRITE_MASK(addr, mask);
 
+		if (group == GPIO_MAPPED_IRQ_GROUP)
+			rb532_gpio_set_istat(0, irq_nr - GPIO_MAPPED_IRQ_BASE);
+
 		/*
 		 * if there are no more interrupts enabled in this
 		 * group, disable corresponding IP
@@ -165,12 +169,35 @@ static void rb532_mask_and_ack_irq(unsigned int irq_nr)
 	ack_local_irq(group_to_ip(irq_to_group(irq_nr)));
 }
 
+static int rb532_set_type(unsigned int irq_nr, unsigned type)
+{
+	int gpio = irq_nr - GPIO_MAPPED_IRQ_BASE;
+	int group = irq_to_group(irq_nr);
+
+	if (group != GPIO_MAPPED_IRQ_GROUP)
+		return (type == IRQ_TYPE_LEVEL_HIGH) ? 0 : -EINVAL;
+
+	switch (type) {
+	case IRQ_TYPE_LEVEL_HIGH:
+		rb532_gpio_set_ilevel(1, gpio);
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		rb532_gpio_set_ilevel(0, gpio);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static struct irq_chip rc32434_irq_type = {
 	.name		= "RB532",
 	.ack		= rb532_disable_irq,
 	.mask		= rb532_disable_irq,
 	.mask_ack	= rb532_mask_and_ack_irq,
 	.unmask		= rb532_enable_irq,
+	.set_type	= rb532_set_type,
 };
 
 void __init arch_init_irq(void)
diff --git a/arch/mips/rb532/serial.c b/arch/mips/rb532/serial.c
index 3e0d7ec3a579..00ed19f0bdb5 100644
--- a/arch/mips/rb532/serial.c
+++ b/arch/mips/rb532/serial.c
@@ -36,7 +36,7 @@
 extern unsigned int idt_cpu_freq;
 
 static struct uart_port rb532_uart = {
-	.type = PORT_16550A,
+	.flags = UPF_BOOT_AUTOCONF,
 	.line = 0,
 	.irq = UART0_IRQ,
 	.iotype = UPIO_MEM,
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
index 6c0049a5bbc1..55440967b3a8 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -435,6 +435,28 @@ void __init tx4939_ata_init(void)
 		platform_device_register(&ata1_dev);
 }
 
+void __init tx4939_rtc_init(void)
+{
+	static struct resource res[] = {
+		{
+			.start = TX4939_RTC_REG & 0xfffffffffULL,
+			.end = (TX4939_RTC_REG & 0xfffffffffULL) + 0x100 - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = TXX9_IRQ_BASE + TX4939_IR_RTC,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+	static struct platform_device rtc_dev = {
+		.name = "tx4939rtc",
+		.id = -1,
+		.num_resources = ARRAY_SIZE(res),
+		.resource = res,
+	};
+
+	platform_device_register(&rtc_dev);
+}
+
 static void __init tx4939_stop_unused_modules(void)
 {
 	__u64 pcfg, rst = 0, ckd = 0;
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
index 98fbd9391bf8..656603b85b71 100644
--- a/arch/mips/txx9/rbtx4939/setup.c
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -336,6 +336,7 @@ static void __init rbtx4939_device_init(void)
 	rbtx4939_led_setup();
 	tx4939_wdt_init();
 	tx4939_ata_init();
+	tx4939_rtc_init();
 }
 
 static void __init rbtx4939_setup(void)
diff --git a/arch/powerpc/configs/52xx/cm5200_defconfig b/arch/powerpc/configs/52xx/cm5200_defconfig
index 99c495ad9c75..1239c6132b4a 100644
--- a/arch/powerpc/configs/52xx/cm5200_defconfig
+++ b/arch/powerpc/configs/52xx/cm5200_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc4
-# Thu Nov 13 02:12:40 2008
+# Linux kernel version: 2.6.29-rc2
+# Mon Jan 26 21:41:58 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -43,7 +43,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_GENERIC_NVRAM=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_PPC_OF=y
 CONFIG_OF=y
@@ -71,14 +71,23 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU 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=14
-# 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_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -110,7 +119,6 @@ CONFIG_SLUB_DEBUG=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -121,13 +129,11 @@ CONFIG_HAVE_CLK=y
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -143,7 +149,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -182,9 +187,8 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_TAU is not set
 # CONFIG_FSL_ULI1575 is not set
 CONFIG_PPC_BESTCOMM=y
-# CONFIG_PPC_BESTCOMM_ATA is not set
 CONFIG_PPC_BESTCOMM_FEC=y
-# CONFIG_PPC_BESTCOMM_GEN_BD is not set
+# CONFIG_SIMPLE_GPIO is not set
 
 #
 # Kernel options
@@ -211,6 +215,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -222,12 +227,14 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -268,6 +275,7 @@ CONFIG_NET=y
 #
 # Networking options
 #
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -324,6 +332,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -336,6 +345,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 # CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -427,6 +437,12 @@ CONFIG_MTD_PHYSMAP_OF=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -514,6 +530,9 @@ CONFIG_LXT_PHY=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
@@ -539,6 +558,10 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_IWLWIFI_LEDS is not set
 
 #
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
@@ -588,8 +611,10 @@ CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=57600
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_NVRAM is not set
@@ -629,8 +654,6 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
@@ -675,10 +698,12 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE 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_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -736,6 +761,7 @@ CONFIG_USB_DEVICEFS=y
 # 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_OHCI_HCD=y
@@ -760,18 +786,17 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
 #
 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_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -817,6 +842,10 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -826,7 +855,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -847,6 +875,7 @@ CONFIG_FS_MBCACHE=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -883,10 +912,7 @@ CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -906,6 +932,7 @@ CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1002,6 +1029,7 @@ CONFIG_NLS_ISO8859_1=y
 # 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
@@ -1053,6 +1081,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -1061,6 +1090,8 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 
 #
 # Tracers
@@ -1069,11 +1100,13 @@ CONFIG_HAVE_FUNCTION_TRACER=y
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
@@ -1100,11 +1133,15 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
 CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/powerpc/configs/52xx/lite5200b_defconfig b/arch/powerpc/configs/52xx/lite5200b_defconfig
index 9796220032fd..b7b880562906 100644
--- a/arch/powerpc/configs/52xx/lite5200b_defconfig
+++ b/arch/powerpc/configs/52xx/lite5200b_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc4
-# Thu Nov 13 02:10:16 2008
+# Linux kernel version: 2.6.29-rc2
+# Mon Jan 26 21:41:14 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -43,7 +43,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_GENERIC_NVRAM=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_PPC_OF=y
 CONFIG_OF=y
@@ -72,14 +72,23 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU 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=14
-# CONFIG_CGROUPS is not set
 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_RELAY is not set
@@ -112,7 +121,6 @@ CONFIG_SLUB_DEBUG=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -123,7 +131,6 @@ CONFIG_HAVE_CLK=y
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 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
@@ -131,11 +138,9 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -151,7 +156,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 CONFIG_FREEZER=y
 
 #
@@ -192,7 +196,7 @@ CONFIG_PPC_LITE5200=y
 CONFIG_PPC_BESTCOMM=y
 CONFIG_PPC_BESTCOMM_ATA=y
 CONFIG_PPC_BESTCOMM_FEC=y
-CONFIG_PPC_BESTCOMM_GEN_BD=y
+# CONFIG_SIMPLE_GPIO is not set
 
 #
 # Kernel options
@@ -220,6 +224,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -231,12 +236,14 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -264,6 +271,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
 CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -286,6 +294,7 @@ CONFIG_NET=y
 #
 # Networking options
 #
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -342,6 +351,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -354,6 +364,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 # CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -396,13 +407,19 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 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_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -445,6 +462,7 @@ 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_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -461,6 +479,8 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_MEGARAID_SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -580,6 +600,9 @@ CONFIG_LXT_PHY=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
@@ -626,6 +649,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
@@ -648,6 +672,10 @@ CONFIG_NETDEV_10000=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 # CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -695,8 +723,10 @@ CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_NVRAM is not set
@@ -762,8 +792,6 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
@@ -796,10 +824,12 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE 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_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -846,9 +876,13 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 #
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
 #
 # 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
@@ -860,7 +894,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -881,6 +914,7 @@ CONFIG_FS_MBCACHE=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -914,10 +948,7 @@ CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -926,6 +957,7 @@ CONFIG_TMPFS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS 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
@@ -967,6 +999,7 @@ CONFIG_MSDOS_PARTITION=y
 # 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
@@ -1016,6 +1049,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -1024,6 +1058,8 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 
 #
 # Tracers
@@ -1032,11 +1068,13 @@ CONFIG_HAVE_FUNCTION_TRACER=y
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
@@ -1063,11 +1101,15 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
 CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/powerpc/configs/52xx/motionpro_defconfig b/arch/powerpc/configs/52xx/motionpro_defconfig
index d081e0031057..fb10f22fd0d2 100644
--- a/arch/powerpc/configs/52xx/motionpro_defconfig
+++ b/arch/powerpc/configs/52xx/motionpro_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc4
-# Thu Nov 13 02:11:02 2008
+# Linux kernel version: 2.6.29-rc2
+# Mon Jan 26 21:42:29 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -43,7 +43,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_GENERIC_NVRAM=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_PPC_OF=y
 CONFIG_OF=y
@@ -71,14 +71,23 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU 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=14
-# 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_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -110,7 +119,6 @@ CONFIG_SLUB_DEBUG=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -121,13 +129,11 @@ CONFIG_HAVE_CLK=y
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -143,7 +149,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -182,9 +187,9 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_TAU is not set
 # CONFIG_FSL_ULI1575 is not set
 CONFIG_PPC_BESTCOMM=y
-# CONFIG_PPC_BESTCOMM_ATA is not set
+CONFIG_PPC_BESTCOMM_ATA=y
 CONFIG_PPC_BESTCOMM_FEC=y
-# CONFIG_PPC_BESTCOMM_GEN_BD is not set
+# CONFIG_SIMPLE_GPIO is not set
 
 #
 # Kernel options
@@ -211,6 +216,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -222,12 +228,14 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -268,6 +276,7 @@ CONFIG_NET=y
 #
 # Networking options
 #
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -324,6 +333,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -336,6 +346,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 # CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -427,6 +438,12 @@ CONFIG_MTD_ROM=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -447,10 +464,16 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_LEGACY=y
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -492,6 +515,7 @@ CONFIG_CHR_DEV_SG=y
 # CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DH is not set
 CONFIG_ATA=y
@@ -525,6 +549,9 @@ CONFIG_SMSC_PHY=y
 CONFIG_BROADCOM_PHY=y
 CONFIG_ICPLUS_PHY=y
 # 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=y
 CONFIG_NET_ETHERNET=y
@@ -548,6 +575,10 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 # CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -590,8 +621,10 @@ CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_NVRAM is not set
@@ -629,8 +662,6 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-CONFIG_EEPROM_LEGACY=y
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
@@ -659,6 +690,7 @@ CONFIG_HWMON=y
 # 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_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_F71805F is not set
@@ -678,6 +710,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4245 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
@@ -721,10 +754,12 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE 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_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -835,7 +870,6 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -856,6 +890,7 @@ CONFIG_FS_MBCACHE=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -892,10 +927,7 @@ CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -915,6 +947,7 @@ CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1011,6 +1044,7 @@ CONFIG_NLS_ISO8859_1=y
 # 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
@@ -1062,6 +1096,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -1070,6 +1105,8 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 
 #
 # Tracers
@@ -1078,11 +1115,13 @@ CONFIG_HAVE_FUNCTION_TRACER=y
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
@@ -1109,11 +1148,15 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
 CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/powerpc/configs/52xx/pcm030_defconfig b/arch/powerpc/configs/52xx/pcm030_defconfig
index b21b8e8c3a78..00944c09a0ae 100644
--- a/arch/powerpc/configs/52xx/pcm030_defconfig
+++ b/arch/powerpc/configs/52xx/pcm030_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc4
-# Thu Nov 13 02:13:16 2008
+# Linux kernel version: 2.6.29-rc2
+# Mon Jan 26 21:41:33 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -43,7 +43,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_GENERIC_NVRAM=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_PPC_OF=y
 CONFIG_OF=y
@@ -72,15 +72,24 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# 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_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -112,7 +121,6 @@ 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_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -124,7 +132,6 @@ CONFIG_HAVE_CLK=y
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 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
@@ -132,11 +139,9 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -152,7 +157,6 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -191,9 +195,9 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_TAU is not set
 # CONFIG_FSL_ULI1575 is not set
 CONFIG_PPC_BESTCOMM=y
-CONFIG_PPC_BESTCOMM_ATA=y
+CONFIG_PPC_BESTCOMM_ATA=m
 CONFIG_PPC_BESTCOMM_FEC=y
-CONFIG_PPC_BESTCOMM_GEN_BD=y
+# CONFIG_SIMPLE_GPIO is not set
 
 #
 # Kernel options
@@ -212,7 +216,6 @@ CONFIG_SCHED_HRTICK=y
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-# CONFIG_PREEMPT_RCU is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 # CONFIG_HAVE_AOUT is not set
@@ -222,6 +225,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -233,12 +237,14 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -261,6 +267,7 @@ CONFIG_PCI_SYSCALL=y
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
 CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -283,6 +290,7 @@ CONFIG_NET=y
 #
 # Networking options
 #
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -333,6 +341,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -345,6 +354,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 # CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -365,6 +375,7 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_OF_PARTS is not set
@@ -413,9 +424,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=1
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PHYSMAP_OF is not set
 # CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
@@ -439,6 +448,12 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -587,6 +602,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
@@ -621,6 +639,10 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_IWLWIFI_LEDS is not set
 
 #
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
@@ -675,7 +697,9 @@ CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=9600
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
+# CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_NVRAM is not set
@@ -740,8 +764,6 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-CONFIG_EEPROM_LEGACY=m
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
@@ -774,10 +796,12 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE 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_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -837,6 +861,7 @@ CONFIG_USB_DEVICEFS=y
 #
 # CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_EHCI_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_OHCI_HCD=m
@@ -864,18 +889,17 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
 #
 CONFIG_USB_STORAGE=m
 # 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_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -921,6 +945,10 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # 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
@@ -983,7 +1011,6 @@ CONFIG_RTC_DRV_PCF8563=m
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -1004,6 +1031,7 @@ CONFIG_FS_MBCACHE=m
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
@@ -1039,10 +1067,7 @@ CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1062,6 +1087,7 @@ CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN 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
@@ -1141,6 +1167,7 @@ CONFIG_NLS_ISO8859_1=y
 # 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
@@ -1173,6 +1200,8 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 
 #
 # Tracers
@@ -1180,6 +1209,7 @@ CONFIG_HAVE_FUNCTION_TRACER=y
 # CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_IRQSTACKS is not set
 # CONFIG_BOOTX_TEXT is not set
 # CONFIG_PPC_EARLY_DEBUG is not set
diff --git a/arch/powerpc/configs/52xx/tqm5200_defconfig b/arch/powerpc/configs/52xx/tqm5200_defconfig
index 79954579f5ec..65237ad6f07e 100644
--- a/arch/powerpc/configs/52xx/tqm5200_defconfig
+++ b/arch/powerpc/configs/52xx/tqm5200_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc4
-# Thu Nov 13 02:09:30 2008
+# Linux kernel version: 2.6.29-rc2
+# Mon Jan 26 21:42:58 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -43,7 +43,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_GENERIC_NVRAM=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_PPC_OF=y
 CONFIG_OF=y
@@ -71,14 +71,23 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU 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=14
-# 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_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -110,7 +119,6 @@ CONFIG_SLUB_DEBUG=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -121,7 +129,6 @@ CONFIG_HAVE_CLK=y
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 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
@@ -129,11 +136,9 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -149,7 +154,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -188,9 +192,9 @@ CONFIG_PPC_MPC5200_BUGFIX=y
 # CONFIG_TAU is not set
 # CONFIG_FSL_ULI1575 is not set
 CONFIG_PPC_BESTCOMM=y
-# CONFIG_PPC_BESTCOMM_ATA is not set
+CONFIG_PPC_BESTCOMM_ATA=y
 CONFIG_PPC_BESTCOMM_FEC=y
-# CONFIG_PPC_BESTCOMM_GEN_BD is not set
+# CONFIG_SIMPLE_GPIO is not set
 
 #
 # Kernel options
@@ -217,6 +221,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -228,12 +233,14 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -274,6 +281,7 @@ CONFIG_NET=y
 #
 # Networking options
 #
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -330,6 +338,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -342,6 +351,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 # CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -364,6 +374,7 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG 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_OF_PARTS is not set
@@ -433,6 +444,12 @@ CONFIG_MTD_PHYSMAP_OF=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -496,6 +513,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DH is not set
 CONFIG_ATA=y
@@ -530,6 +548,9 @@ CONFIG_LXT_PHY=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
@@ -555,6 +576,10 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_IWLWIFI_LEDS is not set
 
 #
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
@@ -604,8 +629,10 @@ CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_NVRAM is not set
@@ -645,8 +672,6 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
@@ -675,6 +700,7 @@ CONFIG_HWMON=y
 # 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_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_F71805F is not set
@@ -694,6 +720,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4245 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
@@ -742,10 +769,12 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE 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_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -803,6 +832,7 @@ CONFIG_USB_MON=y
 # 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_OHCI_HCD=y
@@ -827,18 +857,17 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
 #
 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_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -884,6 +913,10 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -947,7 +980,6 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -968,6 +1000,7 @@ CONFIG_FS_MBCACHE=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1004,10 +1037,7 @@ CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1027,6 +1057,7 @@ CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1123,6 +1154,7 @@ CONFIG_NLS_ISO8859_1=y
 # 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
@@ -1174,6 +1206,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -1182,6 +1215,8 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 
 #
 # Tracers
@@ -1190,11 +1225,13 @@ CONFIG_HAVE_FUNCTION_TRACER=y
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
@@ -1221,11 +1258,15 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
 CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig
index 5ff3de205d6a..81afc8b373d7 100644
--- a/arch/powerpc/configs/mpc5200_defconfig
+++ b/arch/powerpc/configs/mpc5200_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc4
-# Thu Nov 13 02:09:07 2008
+# Linux kernel version: 2.6.29-rc2
+# Mon Jan 26 21:40:44 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -43,7 +43,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_GENERIC_NVRAM=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_PPC_OF=y
 CONFIG_OF=y
@@ -72,10 +72,19 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU 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=14
-# CONFIG_CGROUPS is not set
 # 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
@@ -108,7 +117,6 @@ CONFIG_SLUB_DEBUG=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -119,7 +127,6 @@ CONFIG_HAVE_CLK=y
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 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
@@ -127,11 +134,9 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -147,7 +152,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
 CONFIG_FREEZER=y
 
 #
@@ -192,7 +196,7 @@ CONFIG_RTAS_PROC=y
 CONFIG_PPC_BESTCOMM=y
 CONFIG_PPC_BESTCOMM_ATA=y
 CONFIG_PPC_BESTCOMM_FEC=y
-CONFIG_PPC_BESTCOMM_GEN_BD=y
+# CONFIG_SIMPLE_GPIO is not set
 
 #
 # Kernel options
@@ -220,6 +224,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -231,12 +236,14 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
-# CONFIG_RESOURCES_64BIT is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -264,6 +271,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
 CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -286,6 +294,7 @@ CONFIG_NET=y
 #
 # Networking options
 #
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -342,6 +351,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -354,6 +364,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_AF_RXRPC is not set
 # CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -376,6 +387,7 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG 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_OF_PARTS is not set
@@ -447,6 +459,12 @@ CONFIG_MTD_PHYSMAP_OF=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -474,13 +492,19 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 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_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -539,6 +563,8 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_MEGARAID_SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -659,6 +685,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
@@ -693,6 +722,10 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_IWLWIFI_LEDS is not set
 
 #
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
@@ -774,9 +807,11 @@ CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_HVC_RTAS is not set
+# CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_NVRAM is not set
@@ -844,8 +879,6 @@ CONFIG_I2C_MPC=y
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
@@ -874,6 +907,7 @@ CONFIG_HWMON=y
 # 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_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -894,6 +928,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4245 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
@@ -953,10 +988,12 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE 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_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -1051,7 +1088,7 @@ CONFIG_LCD_CLASS_DEVICE=m
 # CONFIG_LCD_ILI9320 is not set
 # CONFIG_LCD_PLATFORM is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=y
 
 #
 # Display device support
@@ -1093,21 +1130,22 @@ CONFIG_HID_COMPAT=y
 CONFIG_HID_A4TECH=y
 # CONFIG_HID_APPLE is not set
 CONFIG_HID_BELKIN=y
-CONFIG_HID_BRIGHT=y
 CONFIG_HID_CHERRY=y
 # CONFIG_HID_CHICONY is not set
 CONFIG_HID_CYPRESS=y
-CONFIG_HID_DELL=y
 CONFIG_HID_EZKEY=y
 # CONFIG_HID_GYRATION is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
 # CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
 # CONFIG_HID_SUNPLUS is not set
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
 # CONFIG_THRUSTMASTER_FF is not set
 # CONFIG_ZEROPLUS_FF is not set
 CONFIG_USB_SUPPORT=y
@@ -1137,6 +1175,7 @@ CONFIG_USB_MON=y
 #
 # CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_EHCI_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_OHCI_HCD=y
@@ -1164,18 +1203,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
 #
 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_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1222,6 +1260,10 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # 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
@@ -1243,7 +1285,6 @@ CONFIG_NEW_LEDS=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -1264,6 +1305,7 @@ CONFIG_FS_MBCACHE=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1300,10 +1342,7 @@ CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1323,6 +1362,7 @@ CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1403,6 +1443,7 @@ CONFIG_NLS_ISO8859_1=y
 # 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
@@ -1454,6 +1495,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -1462,6 +1504,8 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 
 #
 # Tracers
@@ -1470,11 +1514,13 @@ CONFIG_HAVE_FUNCTION_TRACER=y
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
@@ -1501,11 +1547,15 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
 CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index da5a3855a0c4..19b12d2cbb4b 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -16,8 +16,6 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#define DEBUG
-
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/string.h>
@@ -258,7 +256,8 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
 	} else {
 		pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
 			 oirq.size, oirq.specifier[0], oirq.specifier[1],
-		    oirq.controller->full_name);
+			 oirq.controller ? oirq.controller->full_name :
+			 "<default>");
 
 		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
 					     oirq.size);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index c3f2c21024e3..87ff522f28b5 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -20,14 +20,6 @@
 
 
 /* ======================================================================== */
-/* PCI windows config                                                       */
-/* ======================================================================== */
-
-#define MPC52xx_PCI_TARGET_IO	0xf0000000
-#define MPC52xx_PCI_TARGET_MEM	0x00000000
-
-
-/* ======================================================================== */
 /* Structures mapping & Defines for PCI Unit                                */
 /* ======================================================================== */
 
@@ -244,7 +236,7 @@ static struct pci_ops mpc52xx_pci_ops = {
 
 static void __init
 mpc52xx_pci_setup(struct pci_controller *hose,
-                  struct mpc52xx_pci __iomem *pci_regs)
+                  struct mpc52xx_pci __iomem *pci_regs, phys_addr_t pci_phys)
 {
 	struct resource *res;
 	u32 tmp;
@@ -314,10 +306,14 @@ mpc52xx_pci_setup(struct pci_controller *hose,
 	/* Set all the IWCR fields at once; they're in the same reg */
 	out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2));
 
-	out_be32(&pci_regs->tbatr0,
-		MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO );
-	out_be32(&pci_regs->tbatr1,
-		MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
+	/* Map IMMR onto PCI bus */
+	pci_phys &= 0xfffc0000; /* bar0 has only 14 significant bits */
+	out_be32(&pci_regs->tbatr0, MPC52xx_PCI_TBATR_ENABLE | pci_phys);
+	out_be32(&pci_regs->bar0, PCI_BASE_ADDRESS_MEM_PREFETCH | pci_phys);
+
+	/* Map memory onto PCI bus */
+	out_be32(&pci_regs->tbatr1, MPC52xx_PCI_TBATR_ENABLE);
+	out_be32(&pci_regs->bar1, PCI_BASE_ADDRESS_MEM_PREFETCH);
 
 	out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD | MPC52xx_PCI_TCR_WCT8);
 
@@ -414,7 +410,7 @@ mpc52xx_add_bridge(struct device_node *node)
 
 	/* Finish setting up PCI using values obtained by
 	 * pci_proces_bridge_OF_ranges */
-	mpc52xx_pci_setup(hose, pci_regs);
+	mpc52xx_pci_setup(hose, pci_regs, rsrc.start);
 
 	return 0;
 }
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
index caf4c33f4e84..7c35787d29b4 100644
--- a/arch/sh/boards/board-ap325rxa.c
+++ b/arch/sh/boards/board-ap325rxa.c
@@ -22,6 +22,7 @@
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_gpio.h>
+#include <media/ov772x.h>
 #include <media/soc_camera_platform.h>
 #include <media/sh_mobile_ceu.h>
 #include <video/sh_mobile_lcdc.h>
@@ -216,7 +217,14 @@ static struct platform_device lcdc_device = {
 	},
 };
 
+static void camera_power(int val)
+{
+	gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */
+	mdelay(10);
+}
+
 #ifdef CONFIG_I2C
+/* support for the old ncm03j camera */
 static unsigned char camera_ncm03j_magic[] =
 {
 	0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
@@ -237,6 +245,23 @@ static unsigned char camera_ncm03j_magic[] =
 	0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
 };
 
+static int camera_probe(void)
+{
+	struct i2c_adapter *a = i2c_get_adapter(0);
+	struct i2c_msg msg;
+	int ret;
+
+	camera_power(1);
+	msg.addr = 0x6e;
+	msg.buf = camera_ncm03j_magic;
+	msg.len = 2;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	camera_power(0);
+
+	return ret;
+}
+
 static int camera_set_capture(struct soc_camera_platform_info *info,
 			      int enable)
 {
@@ -245,9 +270,11 @@ static int camera_set_capture(struct soc_camera_platform_info *info,
 	int ret = 0;
 	int i;
 
+	camera_power(0);
 	if (!enable)
 		return 0; /* no disable for now */
 
+	camera_power(1);
 	for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {
 		u_int8_t buf[8];
 
@@ -286,8 +313,35 @@ static struct platform_device camera_device = {
 		.platform_data	= &camera_info,
 	},
 };
+
+static int __init camera_setup(void)
+{
+	if (camera_probe() > 0)
+		platform_device_register(&camera_device);
+
+	return 0;
+}
+late_initcall(camera_setup);
+
 #endif /* CONFIG_I2C */
 
+static int ov7725_power(struct device *dev, int mode)
+{
+	camera_power(0);
+	if (mode)
+		camera_power(1);
+
+	return 0;
+}
+
+static struct ov772x_camera_info ov7725_info = {
+	.buswidth  = SOCAM_DATAWIDTH_8,
+	.flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
+	.link = {
+		.power  = ov7725_power,
+	},
+};
+
 static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
 	.flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
 	SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
@@ -338,9 +392,6 @@ static struct platform_device *ap325rxa_devices[] __initdata = {
 	&ap325rxa_nor_flash_device,
 	&lcdc_device,
 	&ceu_device,
-#ifdef CONFIG_I2C
-	&camera_device,
-#endif
 	&nand_flash_device,
 	&sdcard_cn3_device,
 };
@@ -349,6 +400,10 @@ static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
 	{
 		I2C_BOARD_INFO("pcf8563", 0x51),
 	},
+	{
+		I2C_BOARD_INFO("ov772x", 0x21),
+		.platform_data = &ov7725_info,
+	},
 };
 
 static struct spi_board_info ap325rxa_spi_devices[] = {
@@ -426,7 +481,7 @@ static int __init ap325rxa_devices_setup(void)
 	gpio_request(GPIO_PTZ6, NULL);
 	gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
 	gpio_request(GPIO_PTZ5, NULL);
-	gpio_direction_output(GPIO_PTZ5, 1); /* RST_CAM */
+	gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
 	gpio_request(GPIO_PTZ4, NULL);
 	gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
 
diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig
index 5c423fa8e6b8..352f87d50fdc 100644
--- a/arch/sh/configs/ap325rxa_defconfig
+++ b/arch/sh/configs/ap325rxa_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 16:54:19 2009
+# Linux kernel version: 2.6.29-rc2
+# Tue Jan 27 11:45:08 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -45,12 +45,12 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# 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_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -378,6 +378,7 @@ CONFIG_WIRELESS=y
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -400,6 +401,7 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG 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_AR7_PARTS is not set
@@ -447,9 +449,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xffffffff
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -480,6 +480,12 @@ CONFIG_MTD_NAND_SH_FLCTL=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
 # UBI - Unsorted block images
 #
 CONFIG_MTD_UBI=y
@@ -607,6 +613,10 @@ CONFIG_SMSC911X=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 # CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -790,6 +800,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -837,7 +848,7 @@ CONFIG_SOC_CAMERA=y
 # CONFIG_SOC_CAMERA_MT9V022 is not set
 # CONFIG_SOC_CAMERA_TW9910 is not set
 CONFIG_SOC_CAMERA_PLATFORM=y
-# CONFIG_SOC_CAMERA_OV772X is not set
+CONFIG_SOC_CAMERA_OV772X=y
 CONFIG_VIDEO_SH_MOBILE_CEU=y
 # CONFIG_RADIO_ADAPTERS is not set
 # CONFIG_DAB is not set
@@ -1012,6 +1023,7 @@ CONFIG_FS_POSIX_ACL=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1060,6 +1072,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_JFFS2_FS is not set
 # CONFIG_UBIFS_FS 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
diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig
index 7758263514bc..678576796bdf 100644
--- a/arch/sh/configs/migor_defconfig
+++ b/arch/sh/configs/migor_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:09:35 2009
+# Linux kernel version: 2.6.29-rc1
+# Thu Jan 22 09:16:16 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -45,8 +45,12 @@ CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+
+#
+# Control Group support
+#
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -389,6 +393,7 @@ CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -411,6 +416,7 @@ CONFIG_MTD=y
 # CONFIG_MTD_DEBUG 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_AR7_PARTS is not set
@@ -458,9 +464,7 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xffffffff
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -488,6 +492,12 @@ CONFIG_MTD_NAND_PLATFORM=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -587,6 +597,10 @@ CONFIG_SMC91X=y
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
 # CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -761,6 +775,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -806,9 +821,9 @@ CONFIG_SOC_CAMERA=y
 # CONFIG_SOC_CAMERA_MT9M111 is not set
 # CONFIG_SOC_CAMERA_MT9T031 is not set
 # CONFIG_SOC_CAMERA_MT9V022 is not set
-# CONFIG_SOC_CAMERA_TW9910 is not set
-CONFIG_SOC_CAMERA_PLATFORM=y
-# CONFIG_SOC_CAMERA_OV772X is not set
+CONFIG_SOC_CAMERA_TW9910=y
+# CONFIG_SOC_CAMERA_PLATFORM is not set
+CONFIG_SOC_CAMERA_OV772X=y
 CONFIG_VIDEO_SH_MOBILE_CEU=y
 # CONFIG_RADIO_ADAPTERS is not set
 # CONFIG_DAB is not set
@@ -866,11 +881,13 @@ CONFIG_USB_GADGET_SELECTED=y
 # CONFIG_USB_GADGET_PXA25X is not set
 # CONFIG_USB_GADGET_PXA27X is not set
 # CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
 CONFIG_USB_GADGET_M66592=y
 CONFIG_USB_M66592=y
 CONFIG_SUPERH_BUILT_IN_M66592=y
 # 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_DUMMY_HCD is not set
@@ -883,6 +900,11 @@ CONFIG_USB_G_SERIAL=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -961,6 +983,7 @@ CONFIG_UIO_PDRV_GENIRQ=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
@@ -1004,6 +1027,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS 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
diff --git a/arch/sh/include/asm/mutex-llsc.h b/arch/sh/include/asm/mutex-llsc.h
index ee839ee58ac8..090358a7e1bb 100644
--- a/arch/sh/include/asm/mutex-llsc.h
+++ b/arch/sh/include/asm/mutex-llsc.h
@@ -21,38 +21,36 @@
 static inline void
 __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
 {
-	int __ex_flag, __res;
+	int __done, __res;
 
 	__asm__ __volatile__ (
 		"movli.l	@%2, %0	\n"
 		"add		#-1, %0	\n"
 		"movco.l	%0, @%2	\n"
 		"movt		%1	\n"
-		: "=&z" (__res), "=&r" (__ex_flag)
+		: "=&z" (__res), "=&r" (__done)
 		: "r" (&(count)->counter)
 		: "t");
 
-	__res |= !__ex_flag;
-	if (unlikely(__res != 0))
+	if (unlikely(!__done || __res != 0))
 		fail_fn(count);
 }
 
 static inline int
 __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
 {
-	int __ex_flag, __res;
+	int __done, __res;
 
 	__asm__ __volatile__ (
 		"movli.l	@%2, %0	\n"
 		"add		#-1, %0	\n"
 		"movco.l	%0, @%2	\n"
 		"movt		%1	\n"
-		: "=&z" (__res), "=&r" (__ex_flag)
+		: "=&z" (__res), "=&r" (__done)
 		: "r" (&(count)->counter)
 		: "t");
 
-	__res |= !__ex_flag;
-	if (unlikely(__res != 0))
+	if (unlikely(!__done || __res != 0))
 		__res = fail_fn(count);
 
 	return __res;
@@ -61,19 +59,18 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
 static inline void
 __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
 {
-	int __ex_flag, __res;
+	int __done, __res;
 
 	__asm__ __volatile__ (
 		"movli.l	@%2, %0	\n\t"
 		"add		#1, %0	\n\t"
 		"movco.l	%0, @%2 \n\t"
 		"movt		%1	\n\t"
-		: "=&z" (__res), "=&r" (__ex_flag)
+		: "=&z" (__res), "=&r" (__done)
 		: "r" (&(count)->counter)
 		: "t");
 
-	__res |= !__ex_flag;
-	if (unlikely(__res <= 0))
+	if (unlikely(!__done || __res <= 0))
 		fail_fn(count);
 }
 
diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h
index 05a868a71ef5..5bc34681d994 100644
--- a/arch/sh/include/asm/syscall_32.h
+++ b/arch/sh/include/asm/syscall_32.h
@@ -21,23 +21,10 @@ static inline void syscall_rollback(struct task_struct *task,
 	 */
 }
 
-static inline bool syscall_has_error(struct pt_regs *regs)
-{
-	return (regs->sr & 0x1) ? true : false;
-}
-static inline void syscall_set_error(struct pt_regs *regs)
-{
-	regs->sr |= 0x1;
-}
-static inline void syscall_clear_error(struct pt_regs *regs)
-{
-	regs->sr &= ~0x1;
-}
-
 static inline long syscall_get_error(struct task_struct *task,
 				     struct pt_regs *regs)
 {
-	return syscall_has_error(regs) ? regs->regs[0] : 0;
+	return IS_ERR_VALUE(regs->regs[0]) ? regs->regs[0] : 0;
 }
 
 static inline long syscall_get_return_value(struct task_struct *task,
@@ -50,13 +37,10 @@ static inline void syscall_set_return_value(struct task_struct *task,
 					    struct pt_regs *regs,
 					    int error, long val)
 {
-	if (error) {
-		syscall_set_error(regs);
+	if (error)
 		regs->regs[0] = -error;
-	} else {
-		syscall_clear_error(regs);
+	else
 		regs->regs[0] = val;
-	}
 }
 
 static inline void syscall_get_arguments(struct task_struct *task,
diff --git a/arch/sh/include/asm/syscall_64.h b/arch/sh/include/asm/syscall_64.h
index e1143b9784d6..c3561ca72bee 100644
--- a/arch/sh/include/asm/syscall_64.h
+++ b/arch/sh/include/asm/syscall_64.h
@@ -21,23 +21,10 @@ static inline void syscall_rollback(struct task_struct *task,
 	 */
 }
 
-static inline bool syscall_has_error(struct pt_regs *regs)
-{
-	return (regs->sr & 0x1) ? true : false;
-}
-static inline void syscall_set_error(struct pt_regs *regs)
-{
-	regs->sr |= 0x1;
-}
-static inline void syscall_clear_error(struct pt_regs *regs)
-{
-	regs->sr &= ~0x1;
-}
-
 static inline long syscall_get_error(struct task_struct *task,
 				     struct pt_regs *regs)
 {
-	return syscall_has_error(regs) ? regs->regs[9] : 0;
+	return IS_ERR_VALUE(regs->regs[9]) ? regs->regs[9] : 0;
 }
 
 static inline long syscall_get_return_value(struct task_struct *task,
@@ -50,13 +37,10 @@ static inline void syscall_set_return_value(struct task_struct *task,
 					    struct pt_regs *regs,
 					    int error, long val)
 {
-	if (error) {
-		syscall_set_error(regs);
+	if (error)
 		regs->regs[9] = -error;
-	} else {
-		syscall_clear_error(regs);
+	else
 		regs->regs[9] = val;
-	}
 }
 
 static inline void syscall_get_arguments(struct task_struct *task,
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
index 2780917c0088..e3ea5411da6d 100644
--- a/arch/sh/kernel/cpu/sh4/fpu.c
+++ b/arch/sh/kernel/cpu/sh4/fpu.c
@@ -423,7 +423,7 @@ static int ieee_fpe_handler(struct pt_regs *regs)
 		int m;
 		unsigned int hx;
 
-		m = (finsn >> 9) & 0x7;
+		m = (finsn >> 8) & 0x7;
 		hx = tsk->thread.fpu.hard.fp_regs[m];
 
 		if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR)
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 534247508572..370d2cfa34eb 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -262,11 +262,11 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
 			BOOTMEM_DEFAULT);
 
 	/*
-	 * reserve physical page 0 - it's a special BIOS page on many boxes,
-	 * enabling clean reboots, SMP operation, laptop functions.
+	 * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
 	 */
-	reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET,
-			BOOTMEM_DEFAULT);
+	if (CONFIG_ZERO_PAGE_OFFSET != 0)
+		reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET,
+				BOOTMEM_DEFAULT);
 
 	sparse_memory_present_with_active_regions(0);
 
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 77c21bde376a..17784e19ae34 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -510,7 +510,6 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs,
 		case -ERESTARTNOHAND:
 		no_system_call_restart:
 			regs->regs[0] = -EINTR;
-			regs->sr |= 1;
 			break;
 
 		case -ERESTARTSYS:
@@ -589,8 +588,7 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 	if (signr > 0) {
-		if (regs->sr & 1)
-			handle_syscall_restart(save_r0, regs, &ka.sa);
+		handle_syscall_restart(save_r0, regs, &ka.sa);
 
 		/* Whee!  Actually deliver the signal.  */
 		if (handle_signal(signr, &ka, &info, oldset,
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index b22fdfaaa191..0663a0ee6021 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -60,7 +60,6 @@ handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
 		case -ERESTARTNOHAND:
 		no_system_call_restart:
 			regs->regs[REG_RET] = -EINTR;
-			regs->sr |= 1;
 			break;
 
 		case -ERESTARTSYS:
@@ -109,8 +108,7 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
 
 	signr = get_signal_to_deliver(&info, &ka, regs, 0);
 	if (signr > 0) {
-		if (regs->sr & 1)
-			handle_syscall_restart(regs, &ka.sa);
+		handle_syscall_restart(regs, &ka.sa);
 
 		/* Whee!  Actually deliver the signal.  */
 		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
diff --git a/arch/sh/lib/checksum.S b/arch/sh/lib/checksum.S
index cbdd0d40e545..356c8ec92893 100644
--- a/arch/sh/lib/checksum.S
+++ b/arch/sh/lib/checksum.S
@@ -36,8 +36,7 @@
  */
 
 /*	
- * unsigned int csum_partial(const unsigned char *buf, int len,
- *                           unsigned int sum);
+ * asmlinkage __wsum csum_partial(const void *buf, int len, __wsum sum);
  */
 
 .text
@@ -49,11 +48,31 @@ ENTRY(csum_partial)
 	   * Fortunately, it is easy to convert 2-byte alignment to 4-byte
 	   * alignment for the unrolled loop.
 	   */
-	mov	r5, r1
 	mov	r4, r0
-	tst	#2, r0		! Check alignment.
-	bt	2f		! Jump if alignment is ok.
+	tst	#3, r0		! Check alignment.
+	bt/s	2f		! Jump if alignment is ok.
+	 mov	r4, r7		! Keep a copy to check for alignment
 	!
+	tst	#1, r0		! Check alignment.
+	bt	21f		! Jump if alignment is boundary of 2bytes.
+
+	! buf is odd
+	tst	r5, r5
+	add	#-1, r5
+	bt	9f
+	mov.b	@r4+, r0
+	extu.b	r0, r0
+	addc	r0, r6		! t=0 from previous tst
+	mov	r6, r0
+	shll8	r6
+	shlr16	r0
+	shlr8	r0
+	or	r0, r6
+	mov	r4, r0
+	tst	#2, r0
+	bt	2f
+21:
+	! buf is 2 byte aligned (len could be 0)
 	add	#-2, r5		! Alignment uses up two bytes.
 	cmp/pz	r5		!
 	bt/s	1f		! Jump if we had at least two bytes.
@@ -61,16 +80,17 @@ ENTRY(csum_partial)
 	bra	6f
 	 add	#2, r5		! r5 was < 2.  Deal with it.
 1:
-	mov	r5, r1		! Save new len for later use.
 	mov.w	@r4+, r0
 	extu.w	r0, r0
 	addc	r0, r6
 	bf	2f
 	add	#1, r6
 2:
+	! buf is 4 byte aligned (len could be 0)
+	mov	r5, r1
 	mov	#-5, r0
-	shld	r0, r5
-	tst	r5, r5
+	shld	r0, r1
+	tst	r1, r1
 	bt/s	4f		! if it's =0, go to 4f
 	 clrt
 	.align	2
@@ -92,30 +112,31 @@ ENTRY(csum_partial)
 	addc	r0, r6
 	addc	r2, r6
 	movt	r0
-	dt	r5
+	dt	r1
 	bf/s	3b
 	 cmp/eq	#1, r0
-	! here, we know r5==0
-	addc	r5, r6			! add carry to r6
+	! here, we know r1==0
+	addc	r1, r6			! add carry to r6
 4:
-	mov	r1, r0
+	mov	r5, r0
 	and	#0x1c, r0
 	tst	r0, r0
-	bt/s	6f
-	 mov	r0, r5
-	shlr2	r5
+	bt	6f
+	! 4 bytes or more remaining
+	mov	r0, r1
+	shlr2	r1
 	mov	#0, r2
 5:
 	addc	r2, r6
 	mov.l	@r4+, r2
 	movt	r0
-	dt	r5
+	dt	r1
 	bf/s	5b
 	 cmp/eq	#1, r0
 	addc	r2, r6
-	addc	r5, r6		! r5==0 here, so it means add carry-bit
+	addc	r1, r6		! r1==0 here, so it means add carry-bit
 6:
-	mov	r1, r5
+	! 3 bytes or less remaining
 	mov	#3, r0
 	and	r0, r5
 	tst	r5, r5
@@ -139,8 +160,18 @@ ENTRY(csum_partial)
 8:
 	addc	r0, r6
 	mov	#0, r0
-	addc	r0, r6 
+	addc	r0, r6
 9:
+	! Check if the buffer was misaligned, if so realign sum
+	mov	r7, r0
+	tst	#1, r0
+	bt	10f
+	mov	r6, r0
+	shll8	r6
+	shlr16	r0
+	shlr8	r0
+	or	r0, r6
+10:
 	rts
 	 mov	r6, r0
 
diff --git a/arch/sparc/include/asm/cpudata_64.h b/arch/sparc/include/asm/cpudata_64.h
index 7da7c13d23c4..a11b89ee9ef8 100644
--- a/arch/sparc/include/asm/cpudata_64.h
+++ b/arch/sparc/include/asm/cpudata_64.h
@@ -17,7 +17,7 @@
 typedef struct {
 	/* Dcache line 1 */
 	unsigned int	__softirq_pending; /* must be 1st, see rtrap.S */
-	unsigned int	__pad0;
+	unsigned int	__nmi_count;
 	unsigned long	clock_tick;	/* %tick's per second */
 	unsigned long	__pad;
 	unsigned int	__pad1;
diff --git a/arch/sparc/include/asm/irq_64.h b/arch/sparc/include/asm/irq_64.h
index d47d4a1955a9..1934f2cbf513 100644
--- a/arch/sparc/include/asm/irq_64.h
+++ b/arch/sparc/include/asm/irq_64.h
@@ -66,9 +66,6 @@ extern void virt_irq_free(unsigned int virt_irq);
 extern void __init init_IRQ(void);
 extern void fixup_irqs(void);
 
-extern int register_perfctr_intr(void (*handler)(struct pt_regs *));
-extern void release_perfctr_intr(void (*handler)(struct pt_regs *));
-
 static inline void set_softint(unsigned long bits)
 {
 	__asm__ __volatile__("wr	%0, 0x0, %%set_softint"
@@ -98,5 +95,6 @@ void __trigger_all_cpu_backtrace(void);
 extern void *hardirq_stack[NR_CPUS];
 extern void *softirq_stack[NR_CPUS];
 #define __ARCH_HAS_DO_SOFTIRQ
+#define ARCH_HAS_NMI_WATCHDOG
 
 #endif
diff --git a/arch/sparc/include/asm/kdebug_64.h b/arch/sparc/include/asm/kdebug_64.h
index f905b773235a..feb3578e12c4 100644
--- a/arch/sparc/include/asm/kdebug_64.h
+++ b/arch/sparc/include/asm/kdebug_64.h
@@ -14,6 +14,8 @@ enum die_val {
 	DIE_TRAP,
 	DIE_TRAP_TL1,
 	DIE_CALL,
+	DIE_NMI,
+	DIE_NMIWATCHDOG,
 };
 
 #endif
diff --git a/arch/sparc/include/asm/nmi.h b/arch/sparc/include/asm/nmi.h
new file mode 100644
index 000000000000..fbd546dd4feb
--- /dev/null
+++ b/arch/sparc/include/asm/nmi.h
@@ -0,0 +1,10 @@
+#ifndef __NMI_H
+#define __NMI_H
+
+extern int __init nmi_init(void);
+extern void perfctr_irq(int irq, struct pt_regs *regs);
+extern void nmi_adjust_hz(unsigned int new_hz);
+
+extern int nmi_usable;
+
+#endif /* __NMI_H */
diff --git a/arch/sparc/include/asm/pcr.h b/arch/sparc/include/asm/pcr.h
new file mode 100644
index 000000000000..a2f5c61f924e
--- /dev/null
+++ b/arch/sparc/include/asm/pcr.h
@@ -0,0 +1,46 @@
+#ifndef __PCR_H
+#define __PCR_H
+
+struct pcr_ops {
+	u64 (*read)(void);
+	void (*write)(u64);
+};
+extern const struct pcr_ops *pcr_ops;
+
+extern void deferred_pcr_work_irq(int irq, struct pt_regs *regs);
+extern void schedule_deferred_pcr_work(void);
+
+#define PCR_PIC_PRIV		0x00000001 /* PIC access is privileged */
+#define PCR_STRACE		0x00000002 /* Trace supervisor events  */
+#define PCR_UTRACE		0x00000004 /* Trace user events        */
+#define PCR_N2_HTRACE		0x00000008 /* Trace hypervisor events  */
+#define PCR_N2_TOE_OV0		0x00000010 /* Trap if PIC 0 overflows  */
+#define PCR_N2_TOE_OV1		0x00000020 /* Trap if PIC 1 overflows  */
+#define PCR_N2_MASK0		0x00003fc0
+#define PCR_N2_MASK0_SHIFT	6
+#define PCR_N2_SL0		0x0003c000
+#define PCR_N2_SL0_SHIFT	14
+#define PCR_N2_OV0		0x00040000
+#define PCR_N2_MASK1		0x07f80000
+#define PCR_N2_MASK1_SHIFT	19
+#define PCR_N2_SL1		0x78000000
+#define PCR_N2_SL1_SHIFT	27
+#define PCR_N2_OV1		0x80000000
+
+extern unsigned int picl_shift;
+
+/* In order to commonize as much of the implementation as
+ * possible, we use PICH as our counter.  Mostly this is
+ * to accomodate Niagara-1 which can only count insn cycles
+ * in PICH.
+ */
+static inline u64 picl_value(unsigned int nmi_hz)
+{
+	u32 delta = local_cpu_data().clock_tick / (nmi_hz << picl_shift);
+
+	return ((u64)((0 - delta) & 0xffffffff)) << 32;
+}
+
+extern u64 pcr_enable;
+
+#endif /* __PCR_H */
diff --git a/arch/sparc/include/asm/pil.h b/arch/sparc/include/asm/pil.h
index d573820c0ff4..32a7efe76d00 100644
--- a/arch/sparc/include/asm/pil.h
+++ b/arch/sparc/include/asm/pil.h
@@ -23,6 +23,7 @@
 #define PIL_SMP_CTX_NEW_VERSION	4
 #define PIL_DEVICE_IRQ		5
 #define PIL_SMP_CALL_FUNC_SNGL	6
+#define PIL_DEFERRED_PCR_WORK	7
 #define PIL_NORMAL_MAX		14
 #define PIL_NMI			15
 
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 53adcaa0348b..54742e58831c 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -52,6 +52,8 @@ obj-$(CONFIG_SPARC64)   += visemul.o
 obj-$(CONFIG_SPARC64)   += hvapi.o
 obj-$(CONFIG_SPARC64)   += sstate.o
 obj-$(CONFIG_SPARC64)   += mdesc.o
+obj-$(CONFIG_SPARC64)	+= pcr.o
+obj-$(CONFIG_SPARC64)	+= nmi.o
 
 # sparc32 do not use GENERIC_HARDIRQS but uses the generic devres implementation
 obj-$(CONFIG_SPARC32)     += devres.o
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 32d32b4824f5..d85c3dc4953a 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -26,6 +26,7 @@ EXPORT_PER_CPU_SYMBOL(__cpu_data);
 struct cpu_info {
 	int psr_vers;
 	const char *name;
+	const char *pmu_name;
 };
 
 struct fpu_info {
@@ -45,6 +46,9 @@ struct manufacturer_info {
 #define CPU(ver, _name) \
 { .psr_vers = ver, .name = _name }
 
+#define CPU_PMU(ver, _name, _pmu_name)	\
+{ .psr_vers = ver, .name = _name, .pmu_name = _pmu_name }
+
 #define FPU(ver, _name) \
 { .fp_vers = ver, .name = _name }
 
@@ -183,10 +187,10 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
 },{
 	0x17,
 	.cpu_info = {
-		CPU(0x10, "TI UltraSparc I   (SpitFire)"),
-		CPU(0x11, "TI UltraSparc II  (BlackBird)"),
-		CPU(0x12, "TI UltraSparc IIi (Sabre)"),
-		CPU(0x13, "TI UltraSparc IIe (Hummingbird)"),
+		CPU_PMU(0x10, "TI UltraSparc I   (SpitFire)", "ultra12"),
+		CPU_PMU(0x11, "TI UltraSparc II  (BlackBird)", "ultra12"),
+		CPU_PMU(0x12, "TI UltraSparc IIi (Sabre)", "ultra12"),
+		CPU_PMU(0x13, "TI UltraSparc IIe (Hummingbird)", "ultra12"),
 		CPU(-1, NULL)
 	},
 	.fpu_info = {
@@ -199,7 +203,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
 },{
 	0x22,
 	.cpu_info = {
-		CPU(0x10, "TI UltraSparc I   (SpitFire)"),
+		CPU_PMU(0x10, "TI UltraSparc I   (SpitFire)", "ultra12"),
 		CPU(-1, NULL)
 	},
 	.fpu_info = {
@@ -209,12 +213,12 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
 },{
 	0x3e,
 	.cpu_info = {
-		CPU(0x14, "TI UltraSparc III (Cheetah)"),
-		CPU(0x15, "TI UltraSparc III+ (Cheetah+)"),
-		CPU(0x16, "TI UltraSparc IIIi (Jalapeno)"),
-		CPU(0x18, "TI UltraSparc IV (Jaguar)"),
-		CPU(0x19, "TI UltraSparc IV+ (Panther)"),
-		CPU(0x22, "TI UltraSparc IIIi+ (Serrano)"),
+		CPU_PMU(0x14, "TI UltraSparc III (Cheetah)", "ultra3"),
+		CPU_PMU(0x15, "TI UltraSparc III+ (Cheetah+)", "ultra3+"),
+		CPU_PMU(0x16, "TI UltraSparc IIIi (Jalapeno)", "ultra3i"),
+		CPU_PMU(0x18, "TI UltraSparc IV (Jaguar)", "ultra3+"),
+		CPU_PMU(0x19, "TI UltraSparc IV+ (Panther)", "ultra4+"),
+		CPU_PMU(0x22, "TI UltraSparc IIIi+ (Serrano)", "ultra3i"),
 		CPU(-1, NULL)
 	},
 	.fpu_info = {
@@ -234,6 +238,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
 
 const char *sparc_cpu_type;
 const char *sparc_fpu_type;
+const char *sparc_pmu_type;
 
 unsigned int fsr_storage;
 
@@ -244,6 +249,7 @@ static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers)
 
 	sparc_cpu_type = NULL;
 	sparc_fpu_type = NULL;
+	sparc_pmu_type = NULL;
 	manuf = NULL;
 
 	for (i = 0; i < ARRAY_SIZE(manufacturer_info); i++)
@@ -263,6 +269,7 @@ static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers)
 		{
 			if (cpu->psr_vers == psr_vers) {
 				sparc_cpu_type = cpu->name;
+				sparc_pmu_type = cpu->pmu_name;
 				sparc_fpu_type = "No FPU";
 				break;
 			}
@@ -290,6 +297,8 @@ static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers)
 		       psr_impl, fpu_vers);
 		sparc_fpu_type = "Unknown FPU";
 	}
+	if (sparc_pmu_type == NULL)
+		sparc_pmu_type = "Unknown PMU";
 }
 
 #ifdef CONFIG_SPARC32
@@ -315,11 +324,13 @@ static void __init sun4v_cpu_probe(void)
 	case SUN4V_CHIP_NIAGARA1:
 		sparc_cpu_type = "UltraSparc T1 (Niagara)";
 		sparc_fpu_type = "UltraSparc T1 integrated FPU";
+		sparc_pmu_type = "niagara";
 		break;
 
 	case SUN4V_CHIP_NIAGARA2:
 		sparc_cpu_type = "UltraSparc T2 (Niagara2)";
 		sparc_fpu_type = "UltraSparc T2 integrated FPU";
+		sparc_pmu_type = "niagara2";
 		break;
 
 	default:
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 4ac5c651e00d..3d2c6baae96b 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -196,6 +196,11 @@ int show_interrupts(struct seq_file *p, void *v)
 		seq_putc(p, '\n');
 skip:
 		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+	} else if (i == NR_IRQS) {
+		seq_printf(p, "NMI: ");
+		for_each_online_cpu(j)
+			seq_printf(p, "%10u ", cpu_data(j).__nmi_count);
+		seq_printf(p, "     Non-maskable interrupts\n");
 	}
 	return 0;
 }
@@ -779,69 +784,6 @@ void do_softirq(void)
 	local_irq_restore(flags);
 }
 
-static void unhandled_perf_irq(struct pt_regs *regs)
-{
-	unsigned long pcr, pic;
-
-	read_pcr(pcr);
-	read_pic(pic);
-
-	write_pcr(0);
-
-	printk(KERN_EMERG "CPU %d: Got unexpected perf counter IRQ.\n",
-	       smp_processor_id());
-	printk(KERN_EMERG "CPU %d: PCR[%016lx] PIC[%016lx]\n",
-	       smp_processor_id(), pcr, pic);
-}
-
-/* Almost a direct copy of the powerpc PMC code.  */
-static DEFINE_SPINLOCK(perf_irq_lock);
-static void *perf_irq_owner_caller; /* mostly for debugging */
-static void (*perf_irq)(struct pt_regs *regs) = unhandled_perf_irq;
-
-/* Invoked from level 15 PIL handler in trap table.  */
-void perfctr_irq(int irq, struct pt_regs *regs)
-{
-	clear_softint(1 << irq);
-	perf_irq(regs);
-}
-
-int register_perfctr_intr(void (*handler)(struct pt_regs *))
-{
-	int ret;
-
-	if (!handler)
-		return -EINVAL;
-
-	spin_lock(&perf_irq_lock);
-	if (perf_irq != unhandled_perf_irq) {
-		printk(KERN_WARNING "register_perfctr_intr: "
-		       "perf IRQ busy (reserved by caller %p)\n",
-		       perf_irq_owner_caller);
-		ret = -EBUSY;
-		goto out;
-	}
-
-	perf_irq_owner_caller = __builtin_return_address(0);
-	perf_irq = handler;
-
-	ret = 0;
-out:
-	spin_unlock(&perf_irq_lock);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(register_perfctr_intr);
-
-void release_perfctr_intr(void (*handler)(struct pt_regs *))
-{
-	spin_lock(&perf_irq_lock);
-	perf_irq_owner_caller = NULL;
-	perf_irq = unhandled_perf_irq;
-	spin_unlock(&perf_irq_lock);
-}
-EXPORT_SYMBOL_GPL(release_perfctr_intr);
-
 #ifdef CONFIG_HOTPLUG_CPU
 void fixup_irqs(void)
 {
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index 81a972e8d8ea..15d8a3f645c9 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -5,6 +5,7 @@
 
 /* cpu.c */
 extern const char *sparc_cpu_type;
+extern const char *sparc_pmu_type;
 extern const char *sparc_fpu_type;
 
 extern unsigned int fsr_storage;
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
new file mode 100644
index 000000000000..09f088ed4a64
--- /dev/null
+++ b/arch/sparc/kernel/nmi.c
@@ -0,0 +1,224 @@
+/* Pseudo NMI support on sparc64 systems.
+ *
+ * Copyright (C) 2009 David S. Miller <davem@davemloft.net>
+ *
+ * The NMI watchdog support and infrastructure is based almost
+ * entirely upon the x86 NMI support code.
+ */
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/percpu.h>
+#include <linux/nmi.h>
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include <linux/kernel_stat.h>
+#include <linux/slab.h>
+#include <linux/kdebug.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+
+#include <asm/ptrace.h>
+#include <asm/local.h>
+#include <asm/pcr.h>
+
+/* We don't have a real NMI on sparc64, but we can fake one
+ * up using profiling counter overflow interrupts and interrupt
+ * levels.
+ *
+ * The profile overflow interrupts at level 15, so we use
+ * level 14 as our IRQ off level.
+ */
+
+static int nmi_watchdog_active;
+static int panic_on_timeout;
+
+int nmi_usable;
+EXPORT_SYMBOL_GPL(nmi_usable);
+
+static unsigned int nmi_hz = HZ;
+
+static DEFINE_PER_CPU(unsigned int, last_irq_sum);
+static DEFINE_PER_CPU(local_t, alert_counter);
+static DEFINE_PER_CPU(int, nmi_touch);
+
+void touch_nmi_watchdog(void)
+{
+	if (nmi_watchdog_active) {
+		int cpu;
+
+		for_each_present_cpu(cpu) {
+			if (per_cpu(nmi_touch, cpu) != 1)
+				per_cpu(nmi_touch, cpu) = 1;
+		}
+	}
+
+	touch_softlockup_watchdog();
+}
+EXPORT_SYMBOL(touch_nmi_watchdog);
+
+static void die_nmi(const char *str, struct pt_regs *regs, int do_panic)
+{
+	if (notify_die(DIE_NMIWATCHDOG, str, regs, 0,
+		       pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
+		return;
+
+	console_verbose();
+	bust_spinlocks(1);
+
+	printk(KERN_EMERG "%s", str);
+	printk(" on CPU%d, ip %08lx, registers:\n",
+	       smp_processor_id(), regs->tpc);
+	show_regs(regs);
+
+	bust_spinlocks(0);
+
+	if (do_panic || panic_on_oops)
+		panic("Non maskable interrupt");
+
+	local_irq_enable();
+	do_exit(SIGBUS);
+}
+
+notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
+{
+	unsigned int sum, touched = 0;
+	int cpu = smp_processor_id();
+
+	clear_softint(1 << irq);
+	pcr_ops->write(PCR_PIC_PRIV);
+
+	local_cpu_data().__nmi_count++;
+
+	if (notify_die(DIE_NMI, "nmi", regs, 0,
+		       pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
+		touched = 1;
+
+	sum = kstat_irqs_cpu(0, cpu);
+	if (__get_cpu_var(nmi_touch)) {
+		__get_cpu_var(nmi_touch) = 0;
+		touched = 1;
+	}
+	if (!touched && __get_cpu_var(last_irq_sum) == sum) {
+		local_inc(&__get_cpu_var(alert_counter));
+		if (local_read(&__get_cpu_var(alert_counter)) == 5 * nmi_hz)
+			die_nmi("BUG: NMI Watchdog detected LOCKUP",
+				regs, panic_on_timeout);
+	} else {
+		__get_cpu_var(last_irq_sum) = sum;
+		local_set(&__get_cpu_var(alert_counter), 0);
+	}
+	if (nmi_usable) {
+		write_pic(picl_value(nmi_hz));
+		pcr_ops->write(pcr_enable);
+	}
+}
+
+static inline unsigned int get_nmi_count(int cpu)
+{
+	return cpu_data(cpu).__nmi_count;
+}
+
+static int endflag __initdata;
+
+static __init void nmi_cpu_busy(void *data)
+{
+	local_irq_enable_in_hardirq();
+	while (endflag == 0)
+		mb();
+}
+
+static void report_broken_nmi(int cpu, int *prev_nmi_count)
+{
+	printk(KERN_CONT "\n");
+
+	printk(KERN_WARNING
+		"WARNING: CPU#%d: NMI appears to be stuck (%d->%d)!\n",
+			cpu, prev_nmi_count[cpu], get_nmi_count(cpu));
+
+	printk(KERN_WARNING
+		"Please report this to bugzilla.kernel.org,\n");
+	printk(KERN_WARNING
+		"and attach the output of the 'dmesg' command.\n");
+
+	nmi_usable = 0;
+}
+
+static void stop_watchdog(void *unused)
+{
+	pcr_ops->write(PCR_PIC_PRIV);
+}
+
+static int __init check_nmi_watchdog(void)
+{
+	unsigned int *prev_nmi_count;
+	int cpu, err;
+
+	prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(unsigned int), GFP_KERNEL);
+	if (!prev_nmi_count) {
+		err = -ENOMEM;
+		goto error;
+	}
+
+	printk(KERN_INFO "Testing NMI watchdog ... ");
+
+	smp_call_function(nmi_cpu_busy, (void *)&endflag, 0);
+
+	for_each_possible_cpu(cpu)
+		prev_nmi_count[cpu] = get_nmi_count(cpu);
+	local_irq_enable();
+	mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */
+
+	for_each_online_cpu(cpu) {
+		if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5)
+			report_broken_nmi(cpu, prev_nmi_count);
+	}
+	endflag = 1;
+	if (!nmi_usable) {
+		kfree(prev_nmi_count);
+		err = -ENODEV;
+		goto error;
+	}
+	printk("OK.\n");
+
+	nmi_hz = 1;
+
+	kfree(prev_nmi_count);
+	return 0;
+error:
+	on_each_cpu(stop_watchdog, NULL, 1);
+	return err;
+}
+
+static void start_watchdog(void *unused)
+{
+	pcr_ops->write(PCR_PIC_PRIV);
+	write_pic(picl_value(nmi_hz));
+
+	pcr_ops->write(pcr_enable);
+}
+
+void nmi_adjust_hz(unsigned int new_hz)
+{
+	nmi_hz = new_hz;
+	on_each_cpu(start_watchdog, NULL, 1);
+}
+EXPORT_SYMBOL_GPL(nmi_adjust_hz);
+
+int __init nmi_init(void)
+{
+	nmi_usable = 1;
+
+	on_each_cpu(start_watchdog, NULL, 1);
+
+	return check_nmi_watchdog();
+}
+
+static int __init setup_nmi_watchdog(char *str)
+{
+	if (!strncmp(str, "panic", 5))
+		panic_on_timeout = 1;
+
+	return 0;
+}
+__setup("nmi_watchdog=", setup_nmi_watchdog);
diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c
new file mode 100644
index 000000000000..92e0dda141a4
--- /dev/null
+++ b/arch/sparc/kernel/pcr.c
@@ -0,0 +1,153 @@
+/* pcr.c: Generic sparc64 performance counter infrastructure.
+ *
+ * Copyright (C) 2009 David S. Miller (davem@davemloft.net)
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/pil.h>
+#include <asm/pcr.h>
+#include <asm/nmi.h>
+
+/* This code is shared between various users of the performance
+ * counters.  Users will be oprofile, pseudo-NMI watchdog, and the
+ * perf_counter support layer.
+ */
+
+#define PCR_SUN4U_ENABLE	(PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE)
+#define PCR_N2_ENABLE		(PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE | \
+				 PCR_N2_TOE_OV1 | \
+				 (2 << PCR_N2_SL1_SHIFT) | \
+				 (0xff << PCR_N2_MASK1_SHIFT))
+
+u64 pcr_enable;
+unsigned int picl_shift;
+
+/* Performance counter interrupts run unmasked at PIL level 15.
+ * Therefore we can't do things like wakeups and other work
+ * that expects IRQ disabling to be adhered to in locking etc.
+ *
+ * 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)
+{
+	clear_softint(1 << PIL_DEFERRED_PCR_WORK);
+}
+
+void schedule_deferred_pcr_work(void)
+{
+	set_softint(1 << PIL_DEFERRED_PCR_WORK);
+}
+
+const struct pcr_ops *pcr_ops;
+EXPORT_SYMBOL_GPL(pcr_ops);
+
+static u64 direct_pcr_read(void)
+{
+	u64 val;
+
+	read_pcr(val);
+	return val;
+}
+
+static void direct_pcr_write(u64 val)
+{
+	write_pcr(val);
+}
+
+static const struct pcr_ops direct_pcr_ops = {
+	.read	= direct_pcr_read,
+	.write	= direct_pcr_write,
+};
+
+static void n2_pcr_write(u64 val)
+{
+	unsigned long ret;
+
+	ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val);
+	if (val != HV_EOK)
+		write_pcr(val);
+}
+
+static const struct pcr_ops n2_pcr_ops = {
+	.read	= direct_pcr_read,
+	.write	= n2_pcr_write,
+};
+
+static unsigned long perf_hsvc_group;
+static unsigned long perf_hsvc_major;
+static unsigned long perf_hsvc_minor;
+
+static int __init register_perf_hsvc(void)
+{
+	if (tlb_type == hypervisor) {
+		switch (sun4v_chip_type) {
+		case SUN4V_CHIP_NIAGARA1:
+			perf_hsvc_group = HV_GRP_NIAG_PERF;
+			break;
+
+		case SUN4V_CHIP_NIAGARA2:
+			perf_hsvc_group = HV_GRP_N2_CPU;
+			break;
+
+		default:
+			return -ENODEV;
+		}
+
+
+		perf_hsvc_major = 1;
+		perf_hsvc_minor = 0;
+		if (sun4v_hvapi_register(perf_hsvc_group,
+					 perf_hsvc_major,
+					 &perf_hsvc_minor)) {
+			printk("perfmon: Could not register hvapi.\n");
+			return -ENODEV;
+		}
+	}
+	return 0;
+}
+
+static void __init unregister_perf_hsvc(void)
+{
+	if (tlb_type != hypervisor)
+		return;
+	sun4v_hvapi_unregister(perf_hsvc_group);
+}
+
+int __init pcr_arch_init(void)
+{
+	int err = register_perf_hsvc();
+
+	if (err)
+		return err;
+
+	switch (tlb_type) {
+	case hypervisor:
+		pcr_ops = &n2_pcr_ops;
+		pcr_enable = PCR_N2_ENABLE;
+		picl_shift = 2;
+		break;
+
+	case cheetah:
+	case cheetah_plus:
+	case spitfire:
+		pcr_ops = &direct_pcr_ops;
+		pcr_enable = PCR_SUN4U_ENABLE;
+		break;
+
+	default:
+		err = -ENODEV;
+		goto out_unregister;
+	}
+
+	return nmi_init();
+
+out_unregister:
+	unregister_perf_hsvc();
+	return err;
+}
+
+arch_initcall(pcr_arch_init);
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index cc8b5604442c..a73954b87f0a 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -29,6 +29,7 @@
 #include <linux/cpu.h>
 #include <linux/elfcore.h>
 #include <linux/sysrq.h>
+#include <linux/nmi.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -52,8 +53,10 @@
 
 static void sparc64_yield(int cpu)
 {
-	if (tlb_type != hypervisor)
+	if (tlb_type != hypervisor) {
+		touch_nmi_watchdog();
 		return;
+	}
 
 	clear_thread_flag(TIF_POLLING_NRFLAG);
 	smp_mb__after_clear_bit();
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index 49d061f4ae9d..f2bcfd2967d7 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -354,6 +354,7 @@ static int show_cpuinfo(struct seq_file *m, void *__unused)
 	seq_printf(m, 
 		   "cpu\t\t: %s\n"
 		   "fpu\t\t: %s\n"
+		   "pmu\t\t: %s\n"
 		   "prom\t\t: %s\n"
 		   "type\t\t: %s\n"
 		   "ncpus probed\t: %d\n"
@@ -366,6 +367,7 @@ static int show_cpuinfo(struct seq_file *m, void *__unused)
 		   ,
 		   sparc_cpu_type,
 		   sparc_fpu_type,
+		   sparc_pmu_type,
 		   prom_version,
 		   ((tlb_type == hypervisor) ?
 		    "sun4v" :
diff --git a/arch/sparc/kernel/ttable.S b/arch/sparc/kernel/ttable.S
index ea925503b42e..d9bdfb9d5c18 100644
--- a/arch/sparc/kernel/ttable.S
+++ b/arch/sparc/kernel/ttable.S
@@ -63,7 +63,8 @@ tl0_irq6:	TRAP_IRQ(smp_call_function_single_client, 6)
 #else
 tl0_irq6:	BTRAP(0x46)
 #endif
-tl0_irq7:	BTRAP(0x47) BTRAP(0x48) BTRAP(0x49)
+tl0_irq7:	TRAP_IRQ(deferred_pcr_work_irq, 7)
+tl0_irq8:	BTRAP(0x48) BTRAP(0x49)
 tl0_irq10:	BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d)
 tl0_irq14:	TRAP_IRQ(timer_interrupt, 14)
 tl0_irq15:	TRAP_NMI_IRQ(perfctr_irq, 15)
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index a9e474bf6385..4ab8993b0863 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -19,6 +19,7 @@
 #include <linux/interrupt.h>
 #include <linux/kprobes.h>
 #include <linux/kdebug.h>
+#include <linux/percpu.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -224,6 +225,30 @@ cannot_handle:
 	unhandled_fault (address, current, regs);
 }
 
+static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs)
+{
+	static int times;
+
+	if (times++ < 10)
+		printk(KERN_ERR "FAULT[%s:%d]: 32-bit process reports "
+		       "64-bit TPC [%lx]\n",
+		       current->comm, current->pid,
+		       regs->tpc);
+	show_regs(regs);
+}
+
+static void noinline bogus_32bit_fault_address(struct pt_regs *regs,
+					       unsigned long addr)
+{
+	static int times;
+
+	if (times++ < 10)
+		printk(KERN_ERR "FAULT[%s:%d]: 32-bit process "
+		       "reports 64-bit fault address [%lx]\n",
+		       current->comm, current->pid, addr);
+	show_regs(regs);
+}
+
 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
 {
 	struct mm_struct *mm = current->mm;
@@ -244,6 +269,19 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
 	    (fault_code & FAULT_CODE_DTLB))
 		BUG();
 
+	if (test_thread_flag(TIF_32BIT)) {
+		if (!(regs->tstate & TSTATE_PRIV)) {
+			if (unlikely((regs->tpc >> 32) != 0)) {
+				bogus_32bit_fault_tpc(regs);
+				goto intr_or_no_mm;
+			}
+		}
+		if (unlikely((address >> 32) != 0)) {
+			bogus_32bit_fault_address(regs, address);
+			goto intr_or_no_mm;
+		}
+	}
+
 	if (regs->tstate & TSTATE_PRIV) {
 		unsigned long tpc = regs->tpc;
 
@@ -264,12 +302,6 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
 	if (in_atomic() || !mm)
 		goto intr_or_no_mm;
 
-	if (test_thread_flag(TIF_32BIT)) {
-		if (!(regs->tstate & TSTATE_PRIV))
-			regs->tpc &= 0xffffffff;
-		address &= 0xffffffff;
-	}
-
 	if (!down_read_trylock(&mm->mmap_sem)) {
 		if ((regs->tstate & TSTATE_PRIV) &&
 		    !search_exception_tables(regs->tpc)) {
diff --git a/arch/sparc/oprofile/init.c b/arch/sparc/oprofile/init.c
index d6e170c074fc..d172f86439b1 100644
--- a/arch/sparc/oprofile/init.c
+++ b/arch/sparc/oprofile/init.c
@@ -13,217 +13,57 @@
 #include <linux/init.h>
  
 #ifdef CONFIG_SPARC64
-#include <asm/hypervisor.h>
-#include <asm/spitfire.h>
-#include <asm/cpudata.h>
-#include <asm/irq.h>
+#include <linux/notifier.h>
+#include <linux/rcupdate.h>
+#include <linux/kdebug.h>
+#include <asm/nmi.h>
 
-static int nmi_enabled;
-
-struct pcr_ops {
-	u64 (*read)(void);
-	void (*write)(u64);
-};
-static const struct pcr_ops *pcr_ops;
-
-static u64 direct_pcr_read(void)
-{
-	u64 val;
-
-	read_pcr(val);
-	return val;
-}
-
-static void direct_pcr_write(u64 val)
-{
-	write_pcr(val);
-}
-
-static const struct pcr_ops direct_pcr_ops = {
-	.read	= direct_pcr_read,
-	.write	= direct_pcr_write,
-};
-
-static void n2_pcr_write(u64 val)
+static int profile_timer_exceptions_notify(struct notifier_block *self,
+					   unsigned long val, void *data)
 {
-	unsigned long ret;
-
-	ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val);
-	if (val != HV_EOK)
-		write_pcr(val);
-}
-
-static const struct pcr_ops n2_pcr_ops = {
-	.read	= direct_pcr_read,
-	.write	= n2_pcr_write,
-};
-
-/* In order to commonize as much of the implementation as
- * possible, we use PICH as our counter.  Mostly this is
- * to accomodate Niagara-1 which can only count insn cycles
- * in PICH.
- */
-static u64 picl_value(void)
-{
-	u32 delta = local_cpu_data().clock_tick / HZ;
-
-	return ((u64)((0 - delta) & 0xffffffff)) << 32;
-}
-
-#define PCR_PIC_PRIV		0x00000001 /* PIC access is privileged */
-#define PCR_STRACE		0x00000002 /* Trace supervisor events  */
-#define PCR_UTRACE		0x00000004 /* Trace user events        */
-#define PCR_N2_HTRACE		0x00000008 /* Trace hypervisor events  */
-#define PCR_N2_TOE_OV0		0x00000010 /* Trap if PIC 0 overflows  */
-#define PCR_N2_TOE_OV1		0x00000020 /* Trap if PIC 1 overflows  */
-#define PCR_N2_MASK0		0x00003fc0
-#define PCR_N2_MASK0_SHIFT	6
-#define PCR_N2_SL0		0x0003c000
-#define PCR_N2_SL0_SHIFT	14
-#define PCR_N2_OV0		0x00040000
-#define PCR_N2_MASK1		0x07f80000
-#define PCR_N2_MASK1_SHIFT	19
-#define PCR_N2_SL1		0x78000000
-#define PCR_N2_SL1_SHIFT	27
-#define PCR_N2_OV1		0x80000000
-
-#define PCR_SUN4U_ENABLE	(PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE)
-#define PCR_N2_ENABLE		(PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE | \
-				 PCR_N2_TOE_OV1 | \
-				 (2 << PCR_N2_SL1_SHIFT) | \
-				 (0xff << PCR_N2_MASK1_SHIFT))
-
-static u64 pcr_enable = PCR_SUN4U_ENABLE;
-
-static void nmi_handler(struct pt_regs *regs)
-{
-	pcr_ops->write(PCR_PIC_PRIV);
-
-	if (nmi_enabled) {
-		oprofile_add_sample(regs, 0);
-
-		write_pic(picl_value());
-		pcr_ops->write(pcr_enable);
-	}
-}
-
-/* We count "clock cycle" events in the lower 32-bit PIC.
- * Then configure it such that it overflows every HZ, and thus
- * generates a level 15 interrupt at that frequency.
- */
-static void cpu_nmi_start(void *_unused)
-{
-	pcr_ops->write(PCR_PIC_PRIV);
-	write_pic(picl_value());
-
-	pcr_ops->write(pcr_enable);
-}
+	struct die_args *args = (struct die_args *)data;
+	int ret = NOTIFY_DONE;
 
-static void cpu_nmi_stop(void *_unused)
-{
-	pcr_ops->write(PCR_PIC_PRIV);
-}
-
-static int nmi_start(void)
-{
-	int err = register_perfctr_intr(nmi_handler);
-
-	if (!err) {
-		nmi_enabled = 1;
-		wmb();
-		err = on_each_cpu(cpu_nmi_start, NULL, 1);
-		if (err) {
-			nmi_enabled = 0;
-			wmb();
-			on_each_cpu(cpu_nmi_stop, NULL, 1);
-			release_perfctr_intr(nmi_handler);
-		}
+	switch (val) {
+	case DIE_NMI:
+		oprofile_add_sample(args->regs, 0);
+		ret = NOTIFY_STOP;
+		break;
+	default:
+		break;
 	}
-
-	return err;
-}
-
-static void nmi_stop(void)
-{
-	nmi_enabled = 0;
-	wmb();
-
-	on_each_cpu(cpu_nmi_stop, NULL, 1);
-	release_perfctr_intr(nmi_handler);
-	synchronize_sched();
+	return ret;
 }
 
-static unsigned long perf_hsvc_group;
-static unsigned long perf_hsvc_major;
-static unsigned long perf_hsvc_minor;
+static struct notifier_block profile_timer_exceptions_nb = {
+	.notifier_call	= profile_timer_exceptions_notify,
+};
 
-static int __init register_perf_hsvc(void)
+static int timer_start(void)
 {
-	if (tlb_type == hypervisor) {
-		switch (sun4v_chip_type) {
-		case SUN4V_CHIP_NIAGARA1:
-			perf_hsvc_group = HV_GRP_NIAG_PERF;
-			break;
-
-		case SUN4V_CHIP_NIAGARA2:
-			perf_hsvc_group = HV_GRP_N2_CPU;
-			break;
-
-		default:
-			return -ENODEV;
-		}
-
-
-		perf_hsvc_major = 1;
-		perf_hsvc_minor = 0;
-		if (sun4v_hvapi_register(perf_hsvc_group,
-					 perf_hsvc_major,
-					 &perf_hsvc_minor)) {
-			printk("perfmon: Could not register N2 hvapi.\n");
-			return -ENODEV;
-		}
-	}
+	if (register_die_notifier(&profile_timer_exceptions_nb))
+		return 1;
+	nmi_adjust_hz(HZ);
 	return 0;
 }
 
-static void unregister_perf_hsvc(void)
+
+static void timer_stop(void)
 {
-	if (tlb_type != hypervisor)
-		return;
-	sun4v_hvapi_unregister(perf_hsvc_group);
+	nmi_adjust_hz(1);
+	unregister_die_notifier(&profile_timer_exceptions_nb);
+	synchronize_sched();  /* Allow already-started NMIs to complete. */
 }
 
-static int oprofile_nmi_init(struct oprofile_operations *ops)
+static int op_nmi_timer_init(struct oprofile_operations *ops)
 {
-	int err = register_perf_hsvc();
-
-	if (err)
-		return err;
-
-	switch (tlb_type) {
-	case hypervisor:
-		pcr_ops = &n2_pcr_ops;
-		pcr_enable = PCR_N2_ENABLE;
-		break;
-
-	case cheetah:
-	case cheetah_plus:
-		pcr_ops = &direct_pcr_ops;
-		break;
-
-	default:
+	if (!nmi_usable)
 		return -ENODEV;
-	}
 
-	ops->create_files = NULL;
-	ops->setup = NULL;
-	ops->shutdown = NULL;
-	ops->start = nmi_start;
-	ops->stop = nmi_stop;
+	ops->start = timer_start;
+	ops->stop = timer_stop;
 	ops->cpu_type = "timer";
-
-	printk(KERN_INFO "oprofile: Using perfctr based NMI timer interrupt.\n");
-
+	printk(KERN_INFO "oprofile: Using perfctr NMI timer interrupt.\n");
 	return 0;
 }
 #endif
@@ -233,7 +73,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
 	int ret = -ENODEV;
 
 #ifdef CONFIG_SPARC64
-	ret = oprofile_nmi_init(ops);
+	ret = op_nmi_timer_init(ops);
 	if (!ret)
 		return ret;
 #endif
@@ -241,10 +81,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
 	return ret;
 }
 
-
 void oprofile_arch_exit(void)
 {
-#ifdef CONFIG_SPARC64
-	unregister_perf_hsvc();
-#endif
 }
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c
index 75115849af33..4a58c8ce3f69 100644
--- a/arch/x86/boot/video-vesa.c
+++ b/arch/x86/boot/video-vesa.c
@@ -269,9 +269,8 @@ void vesa_store_edid(void)
 	   we genuinely have to assume all registers are destroyed here. */
 
 	asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
-	    : "+a" (ax), "+b" (bx)
-	    :  "c" (cx), "D" (di)
-	    : "esi");
+	    : "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
+	    : : "esi", "edx");
 
 	if (ax != 0x004f)
 		return;		/* No EDID */
@@ -285,9 +284,9 @@ void vesa_store_edid(void)
 	dx = 0;			/* EDID block number */
 	di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
 	asm(INT10
-	    : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
-	    : "c" (cx), "D" (di)
-	    : "esi");
+	    : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info),
+	      "+c" (cx), "+D" (di)
+	    : : "esi");
 #endif /* CONFIG_FIRMWARE_EDID */
 }
 
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 9c79b2477008..097a6b64c24d 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -418,9 +418,9 @@ ENTRY(ia32_syscall)
 	orl   $TS_COMPAT,TI_status(%r10)
 	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
 	jnz ia32_tracesys
-ia32_do_syscall:	
 	cmpl $(IA32_NR_syscalls-1),%eax
-	ja  int_ret_from_sys_call	/* ia32_tracesys has set RAX(%rsp) */
+	ja ia32_badsys
+ia32_do_call:
 	IA32_ARG_FIXUP
 	call *ia32_sys_call_table(,%rax,8) # xxx: rip relative
 ia32_sysret:
@@ -435,7 +435,9 @@ ia32_tracesys:
 	call syscall_trace_enter
 	LOAD_ARGS32 ARGOFFSET  /* reload args from stack in case ptrace changed it */
 	RESTORE_REST
-	jmp ia32_do_syscall
+	cmpl $(IA32_NR_syscalls-1),%eax
+	ja  int_ret_from_sys_call	/* ia32_tracesys has set RAX(%rsp) */
+	jmp ia32_do_call
 END(ia32_syscall)
 
 ia32_badsys:
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 3d8ceddbd407..00d41ce4c844 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -49,6 +49,7 @@
 #define E820_RESERVED_KERN        128
 
 #ifndef __ASSEMBLY__
+#include <linux/types.h>
 struct e820entry {
 	__u64 addr;	/* start of memory segment */
 	__u64 size;	/* size of memory segment */
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
index b95162af0bf6..d2e3bf3608af 100644
--- a/arch/x86/include/asm/kvm.h
+++ b/arch/x86/include/asm/kvm.h
@@ -6,7 +6,7 @@
  *
  */
 
-#include <asm/types.h>
+#include <linux/types.h>
 #include <linux/ioctl.h>
 
 /* Architectural interrupt line count. */
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index 1d6e17c2f23a..32c6e17b960b 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -3,8 +3,8 @@
 
 #ifdef __x86_64__
 
+#include <linux/types.h>
 #include <asm/ioctls.h>
-#include <asm/types.h>
 
 /*
  * Machine Check support for x86
@@ -115,8 +115,6 @@ extern int mce_notify_user(void);
 
 #endif /* !CONFIG_X86_32 */
 
-
-
 #ifdef CONFIG_X86_MCE
 extern void mcheck_init(struct cpuinfo_x86 *c);
 #else
@@ -126,5 +124,4 @@ extern void stop_mce(void);
 extern void restart_mce(void);
 
 #endif /* __KERNEL__ */
-
 #endif /* _ASM_X86_MCE_H */
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index 14080d22edb3..a51ada8467de 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -23,6 +23,7 @@
 #ifndef _ASM_X86_MTRR_H
 #define _ASM_X86_MTRR_H
 
+#include <linux/types.h>
 #include <linux/ioctl.h>
 #include <linux/errno.h>
 
diff --git a/arch/x86/include/asm/ptrace-abi.h b/arch/x86/include/asm/ptrace-abi.h
index 25f1bb8fc626..8e0f8d199e05 100644
--- a/arch/x86/include/asm/ptrace-abi.h
+++ b/arch/x86/include/asm/ptrace-abi.h
@@ -83,7 +83,7 @@
 #ifdef CONFIG_X86_PTRACE_BTS
 
 #ifndef __ASSEMBLY__
-#include <asm/types.h>
+#include <linux/types.h>
 
 /* configuration/status structure used in PTRACE_BTS_CONFIG and
    PTRACE_BTS_STATUS commands.
diff --git a/arch/x86/include/asm/sigcontext.h b/arch/x86/include/asm/sigcontext.h
index 0afcb5e58acc..ec666491aaa4 100644
--- a/arch/x86/include/asm/sigcontext.h
+++ b/arch/x86/include/asm/sigcontext.h
@@ -2,7 +2,7 @@
 #define _ASM_X86_SIGCONTEXT_H
 
 #include <linux/compiler.h>
-#include <asm/types.h>
+#include <linux/types.h>
 
 #define FP_XSTATE_MAGIC1	0x46505853U
 #define FP_XSTATE_MAGIC2	0x46505845U
diff --git a/arch/x86/include/asm/sigcontext32.h b/arch/x86/include/asm/sigcontext32.h
index 6126188cf3a9..ad1478c4ae12 100644
--- a/arch/x86/include/asm/sigcontext32.h
+++ b/arch/x86/include/asm/sigcontext32.h
@@ -1,6 +1,8 @@
 #ifndef _ASM_X86_SIGCONTEXT32_H
 #define _ASM_X86_SIGCONTEXT32_H
 
+#include <linux/types.h>
+
 /* signal context for 32bit programs. */
 
 #define X86_FXSR_MAGIC		0x0000
diff --git a/arch/x86/include/asm/swab.h b/arch/x86/include/asm/swab.h
index 306d4178ffc9..557cd9f00661 100644
--- a/arch/x86/include/asm/swab.h
+++ b/arch/x86/include/asm/swab.h
@@ -1,7 +1,7 @@
 #ifndef _ASM_X86_SWAB_H
 #define _ASM_X86_SWAB_H
 
-#include <asm/types.h>
+#include <linux/types.h>
 #include <linux/compiler.h>
 
 static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 4abff454c55b..7c243a2c5115 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -157,11 +157,11 @@ static int __init acpi_sleep_setup(char *str)
 #ifdef CONFIG_HIBERNATION
 		if (strncmp(str, "s4_nohwsig", 10) == 0)
 			acpi_no_s4_hw_signature();
+		if (strncmp(str, "s4_nonvs", 8) == 0)
+			acpi_s4_no_nvs();
 #endif
 		if (strncmp(str, "old_ordering", 12) == 0)
 			acpi_old_suspend_ordering();
-		if (strncmp(str, "s4_nonvs", 8) == 0)
-			acpi_s4_no_nvs();
 		str = strchr(str, ',');
 		if (str != NULL)
 			str += strspn(str, ", \t");
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c
index c6f15647eba9..383d827eef89 100644
--- a/arch/x86/kernel/apic.c
+++ b/arch/x86/kernel/apic.c
@@ -1461,7 +1461,7 @@ static int __init detect_init_APIC(void)
 	switch (boot_cpu_data.x86_vendor) {
 	case X86_VENDOR_AMD:
 		if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) ||
-		    (boot_cpu_data.x86 == 15))
+		    (boot_cpu_data.x86 >= 15))
 			break;
 		goto no_apic;
 	case X86_VENDOR_INTEL:
diff --git a/arch/x86/kernel/cpu/cpufreq/Kconfig b/arch/x86/kernel/cpu/cpufreq/Kconfig
index efae3b22a0ff..65792c2cc462 100644
--- a/arch/x86/kernel/cpu/cpufreq/Kconfig
+++ b/arch/x86/kernel/cpu/cpufreq/Kconfig
@@ -245,17 +245,6 @@ config X86_E_POWERSAVER
 
 comment "shared options"
 
-config X86_ACPI_CPUFREQ_PROC_INTF
-	bool "/proc/acpi/processor/../performance interface (deprecated)"
-	depends on PROC_FS
-	depends on X86_ACPI_CPUFREQ || X86_POWERNOW_K7_ACPI || X86_POWERNOW_K8_ACPI
-	help
-	  This enables the deprecated /proc/acpi/processor/../performance
-	  interface. While it is helpful for debugging, the generic,
-	  cross-architecture cpufreq interfaces should be used.
-
-	  If in doubt, say N.
-
 config X86_SPEEDSTEP_LIB
 	tristate
 	default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD)
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 549f2ada55f5..430e5c38a544 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -30,7 +30,7 @@
 static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
 {
 	/* Unmask CPUID levels if masked: */
-	if (c->x86 == 6 && c->x86_model >= 15) {
+	if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) {
 		u64 misc_enable;
 
 		rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 58527a9fc404..7293508d8f5c 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -36,8 +36,11 @@ static struct _cache_table cache_table[] __cpuinitdata =
 {
 	{ 0x06, LVL_1_INST, 8 },	/* 4-way set assoc, 32 byte line size */
 	{ 0x08, LVL_1_INST, 16 },	/* 4-way set assoc, 32 byte line size */
+	{ 0x09, LVL_1_INST, 32 },	/* 4-way set assoc, 64 byte line size */
 	{ 0x0a, LVL_1_DATA, 8 },	/* 2 way set assoc, 32 byte line size */
 	{ 0x0c, LVL_1_DATA, 16 },	/* 4-way set assoc, 32 byte line size */
+	{ 0x0d, LVL_1_DATA, 16 },	/* 4-way set assoc, 64 byte line size */
+	{ 0x21, LVL_2,      256 },	/* 8-way set assoc, 64 byte line size */
 	{ 0x22, LVL_3,      512 },	/* 4-way set assoc, sectored cache, 64 byte line size */
 	{ 0x23, LVL_3,      1024 },	/* 8-way set assoc, sectored cache, 64 byte line size */
 	{ 0x25, LVL_3,      2048 },	/* 8-way set assoc, sectored cache, 64 byte line size */
@@ -85,6 +88,18 @@ static struct _cache_table cache_table[] __cpuinitdata =
 	{ 0x85, LVL_2,    2048 },	/* 8-way set assoc, 32 byte line size */
 	{ 0x86, LVL_2,     512 },	/* 4-way set assoc, 64 byte line size */
 	{ 0x87, LVL_2,    1024 },	/* 8-way set assoc, 64 byte line size */
+	{ 0xd0, LVL_3,     512 },	/* 4-way set assoc, 64 byte line size */
+	{ 0xd1, LVL_3,    1024 },	/* 4-way set assoc, 64 byte line size */
+	{ 0xd2, LVL_3,    2048 },	/* 4-way set assoc, 64 byte line size */
+	{ 0xd6, LVL_3,    1024 },	/* 8-way set assoc, 64 byte line size */
+	{ 0xd7, LVL_3,    2038 },	/* 8-way set assoc, 64 byte line size */
+	{ 0xd8, LVL_3,    4096 },	/* 12-way set assoc, 64 byte line size */
+	{ 0xdc, LVL_3,    2048 },	/* 12-way set assoc, 64 byte line size */
+	{ 0xdd, LVL_3,    4096 },	/* 12-way set assoc, 64 byte line size */
+	{ 0xde, LVL_3,    8192 },	/* 12-way set assoc, 64 byte line size */
+	{ 0xe2, LVL_3,    2048 },	/* 16-way set assoc, 64 byte line size */
+	{ 0xe3, LVL_3,    4096 },	/* 16-way set assoc, 64 byte line size */
+	{ 0xe4, LVL_3,    8192 },	/* 16-way set assoc, 64 byte line size */
 	{ 0x00, 0, 0}
 };
 
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index d259e5d2e054..236a401b8259 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -1594,8 +1594,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
 
 	/* kvm/qemu doesn't have mtrr set right, don't trim them all */
 	if (!highest_pfn) {
-		WARN(!kvm_para_available(), KERN_WARNING
-				"WARNING: strange, CPU MTRRs all blank?\n");
+		printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n");
 		return 0;
 	}
 
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c
index da91701a2348..169a120587be 100644
--- a/arch/x86/kernel/ds.c
+++ b/arch/x86/kernel/ds.c
@@ -15,8 +15,8 @@
  * - buffer allocation (memory accounting)
  *
  *
- * Copyright (C) 2007-2008 Intel Corporation.
- * Markus Metzger <markus.t.metzger@intel.com>, 2007-2008
+ * Copyright (C) 2007-2009 Intel Corporation.
+ * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
  */
 
 
@@ -890,7 +890,7 @@ int ds_set_pebs_reset(struct pebs_tracer *tracer, u64 value)
 }
 
 static const struct ds_configuration ds_cfg_netburst = {
-	.name = "netburst",
+	.name = "Netburst",
 	.ctl[dsf_bts]		= (1 << 2) | (1 << 3),
 	.ctl[dsf_bts_kernel]	= (1 << 5),
 	.ctl[dsf_bts_user]	= (1 << 6),
@@ -904,7 +904,7 @@ static const struct ds_configuration ds_cfg_netburst = {
 #endif
 };
 static const struct ds_configuration ds_cfg_pentium_m = {
-	.name = "pentium m",
+	.name = "Pentium M",
 	.ctl[dsf_bts]		= (1 << 6) | (1 << 7),
 
 	.sizeof_field		= sizeof(long),
@@ -915,8 +915,8 @@ static const struct ds_configuration ds_cfg_pentium_m = {
 	.sizeof_rec[ds_pebs]	= sizeof(long) * 18,
 #endif
 };
-static const struct ds_configuration ds_cfg_core2 = {
-	.name = "core 2",
+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),
@@ -949,19 +949,22 @@ void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
 	switch (c->x86) {
 	case 0x6:
 		switch (c->x86_model) {
-		case 0 ... 0xC:
-			/* sorry, don't know about them */
-			break;
-		case 0xD:
-		case 0xE: /* Pentium M */
+		case 0x9:
+		case 0xd: /* Pentium M */
 			ds_configure(&ds_cfg_pentium_m);
 			break;
-		default: /* Core2, Atom, ... */
-			ds_configure(&ds_cfg_core2);
+		case 0xf:
+		case 0x17: /* Core2 */
+		case 0x1c: /* Atom */
+			ds_configure(&ds_cfg_core2_atom);
+			break;
+		case 0x1a: /* i7 */
+		default:
+			/* sorry, don't know about them */
 			break;
 		}
 		break;
-	case 0xF:
+	case 0xf:
 		switch (c->x86_model) {
 		case 0x0:
 		case 0x1:
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index e4c9710cae52..586bed677557 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -347,6 +347,7 @@ ENTRY(save_args)
 	popq_cfi %rax			/* move return address... */
 	mov PER_CPU_VAR(irq_stack_ptr),%rsp
 	EMPTY_FRAME 0
+	pushq_cfi %rbp			/* backlink for unwinder */
 	pushq_cfi %rax			/* ... to the new stack */
 	/*
 	 * We entered an interrupt context - irqs are off:
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c
index e4d36bd56b62..0a7f6d6b1206 100644
--- a/arch/x86/kernel/io_apic.c
+++ b/arch/x86/kernel/io_apic.c
@@ -2527,14 +2527,15 @@ static void irq_complete_move(struct irq_desc **descp)
 
 	vector = ~get_irq_regs()->orig_ax;
 	me = smp_processor_id();
+
+	if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) {
 #ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
 		*descp = desc = move_irq_desc(desc, me);
 		/* get the new one */
 		cfg = desc->chip_data;
 #endif
-
-	if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain))
 		send_cleanup_vector(cfg);
+	}
 }
 #else
 static inline void irq_complete_move(struct irq_desc **descp) {}
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c
index bf629cadec1a..22608ebf831b 100644
--- a/arch/x86/kernel/irqinit_32.c
+++ b/arch/x86/kernel/irqinit_32.c
@@ -78,15 +78,6 @@ void __init init_ISA_irqs(void)
 	}
 }
 
-/*
- * IRQ2 is cascade interrupt to second interrupt controller
- */
-static struct irqaction irq2 = {
-	.handler = no_action,
-	.mask = CPU_MASK_NONE,
-	.name = "cascade",
-};
-
 DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
 	[0 ... IRQ0_VECTOR - 1] = -1,
 	[IRQ0_VECTOR] = 0,
@@ -185,9 +176,6 @@ void __init native_init_IRQ(void)
 	alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
 #endif
 
-	if (!acpi_ioapic)
-		setup_irq(2, &irq2);
-
 	/* setup after call gates are initialised (usually add in
 	 * the architecture specific gates)
 	 */
diff --git a/arch/x86/mach-default/setup.c b/arch/x86/mach-default/setup.c
index df167f265622..a265a7c63190 100644
--- a/arch/x86/mach-default/setup.c
+++ b/arch/x86/mach-default/setup.c
@@ -38,6 +38,15 @@ void __init pre_intr_init_hook(void)
 	init_ISA_irqs();
 }
 
+/*
+ * IRQ2 is cascade interrupt to second interrupt controller
+ */
+static struct irqaction irq2 = {
+	.handler = no_action,
+	.mask = CPU_MASK_NONE,
+	.name = "cascade",
+};
+
 /**
  * intr_init_hook - post gate setup interrupt initialisation
  *
@@ -53,6 +62,9 @@ void __init intr_init_hook(void)
 		if (x86_quirks->arch_intr_init())
 			return;
 	}
+	if (!acpi_ioapic)
+		setup_irq(2, &irq2);
+
 }
 
 /**
diff --git a/arch/x86/mach-voyager/setup.c b/arch/x86/mach-voyager/setup.c
index 0ade62555ff3..66b7eb57d8e4 100644
--- a/arch/x86/mach-voyager/setup.c
+++ b/arch/x86/mach-voyager/setup.c
@@ -34,13 +34,23 @@ void __init intr_init_hook(void)
 	setup_irq(2, &irq2);
 }
 
-void __init pre_setup_arch_hook(void)
+static void voyager_disable_tsc(void)
 {
 	/* Voyagers run their CPUs from independent clocks, so disable
 	 * the TSC code because we can't sync them */
 	setup_clear_cpu_cap(X86_FEATURE_TSC);
 }
 
+void __init pre_setup_arch_hook(void)
+{
+	voyager_disable_tsc();
+}
+
+void __init pre_time_init_hook(void)
+{
+	voyager_disable_tsc();
+}
+
 void __init trap_init_hook(void)
 {
 }
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c
index 58c7cac3440d..6f5a38c7f900 100644
--- a/arch/x86/mach-voyager/voyager_smp.c
+++ b/arch/x86/mach-voyager/voyager_smp.c
@@ -81,7 +81,7 @@ static void enable_local_vic_irq(unsigned int irq);
 static void disable_local_vic_irq(unsigned int irq);
 static void before_handle_vic_irq(unsigned int irq);
 static void after_handle_vic_irq(unsigned int irq);
-static void set_vic_irq_affinity(unsigned int irq, cpumask_t mask);
+static void set_vic_irq_affinity(unsigned int irq, const struct cpumask *mask);
 static void ack_vic_irq(unsigned int irq);
 static void vic_enable_cpi(void);
 static void do_boot_cpu(__u8 cpuid);
@@ -211,8 +211,6 @@ static __u32 cpu_booted_map;
 static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
 
 /* This is for the new dynamic CPU boot code */
-cpumask_t cpu_callin_map = CPU_MASK_NONE;
-cpumask_t cpu_callout_map = CPU_MASK_NONE;
 
 /* The per processor IRQ masks (these are usually kept in sync) */
 static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned;
@@ -378,7 +376,7 @@ void __init find_smp_config(void)
 	cpus_addr(phys_cpu_present_map)[0] |=
 	    voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK +
 				       3) << 24;
-	cpu_possible_map = phys_cpu_present_map;
+	init_cpu_possible(&phys_cpu_present_map);
 	printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n",
 	       cpus_addr(phys_cpu_present_map)[0]);
 	/* Here we set up the VIC to enable SMP */
@@ -1598,16 +1596,16 @@ static void after_handle_vic_irq(unsigned int irq)
  * change the mask and then do an interrupt enable CPI to re-enable on
  * the selected processors */
 
-void set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
+void set_vic_irq_affinity(unsigned int irq, const struct cpumask *mask)
 {
 	/* Only extended processors handle interrupts */
 	unsigned long real_mask;
 	unsigned long irq_mask = 1 << irq;
 	int cpu;
 
-	real_mask = cpus_addr(mask)[0] & voyager_extended_vic_processors;
+	real_mask = cpus_addr(*mask)[0] & voyager_extended_vic_processors;
 
-	if (cpus_addr(mask)[0] == 0)
+	if (cpus_addr(*mask)[0] == 0)
 		/* can't have no CPUs to accept the interrupt -- extremely
 		 * bad things will happen */
 		return;
@@ -1749,10 +1747,10 @@ static void __cpuinit voyager_smp_prepare_boot_cpu(void)
 	int cpu = smp_processor_id();
 	switch_to_new_gdt(cpu);
 
-	cpu_set(cpu, cpu_online_map);
-	cpu_set(cpu, cpu_callout_map);
-	cpu_set(cpu, cpu_possible_map);
-	cpu_set(cpu, cpu_present_map);
+	cpu_online_map = cpumask_of_cpu(smp_processor_id());
+	cpu_callout_map = cpumask_of_cpu(smp_processor_id());
+	cpu_callin_map = CPU_MASK_NONE;
+	cpu_present_map = cpumask_of_cpu(smp_processor_id());
 }
 
 static int __cpuinit voyager_cpu_up(unsigned int cpu)
@@ -1781,9 +1779,9 @@ void __init smp_setup_processor_id(void)
 	current_thread_info()->cpu = hard_smp_processor_id();
 }
 
-static void voyager_send_call_func(cpumask_t callmask)
+static void voyager_send_call_func(const struct cpumask *callmask)
 {
-	__u32 mask = cpus_addr(callmask)[0] & ~(1 << smp_processor_id());
+	__u32 mask = cpus_addr(*callmask)[0] & ~(1 << smp_processor_id());
 	send_CPI(mask, VIC_CALL_FUNCTION_CPI);
 }
 
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 65709a6aa6ee..8c3f3113a6ec 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -807,8 +807,6 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
 	/* get the address */
 	address = read_cr2();
 
-	if (unlikely(notify_page_fault(regs)))
-		return;
 	if (unlikely(kmmio_fault(regs, address)))
 		return;
 
@@ -838,6 +836,9 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
 		if (spurious_fault(error_code, address))
 			return;
 
+		/* kprobes don't want to hook the spurious faults. */
+		if (notify_page_fault(regs))
+			return;
 		/*
 		 * Don't take the mm semaphore here. If we fixup a prefetch
 		 * fault we could otherwise deadlock.
@@ -846,6 +847,8 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
 		return;
 	}
 
+	if (unlikely(notify_page_fault(regs)))
+		return;
 	/*
 	 * It's safe to allow irq's after cr2 has been saved and the
 	 * vmalloc fault has been handled.
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 4064345cf144..fecbce6e7d7c 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -572,6 +572,7 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
 	case PCI_DEVICE_ID_INTEL_ICH7_1:
 	case PCI_DEVICE_ID_INTEL_ICH7_30:
 	case PCI_DEVICE_ID_INTEL_ICH7_31:
+	case PCI_DEVICE_ID_INTEL_TGP_LPC:
 	case PCI_DEVICE_ID_INTEL_ESB2_0:
 	case PCI_DEVICE_ID_INTEL_ICH8_0:
 	case PCI_DEVICE_ID_INTEL_ICH8_1:
diff --git a/arch/x86/xen/multicalls.h b/arch/x86/xen/multicalls.h
index e786fa7f2615..9e565da5d1f7 100644
--- a/arch/x86/xen/multicalls.h
+++ b/arch/x86/xen/multicalls.h
@@ -19,8 +19,10 @@ DECLARE_PER_CPU(unsigned long, xen_mc_irq_flags);
    paired with xen_mc_issue() */
 static inline void xen_mc_batch(void)
 {
+	unsigned long flags;
 	/* need to disable interrupts until this entry is complete */
-	local_irq_save(__get_cpu_var(xen_mc_irq_flags));
+	local_irq_save(flags);
+	__get_cpu_var(xen_mc_irq_flags) = flags;
 }
 
 static inline struct multicall_space xen_mc_entry(size_t args)
diff --git a/block/blk-core.c b/block/blk-core.c
index ca69f3d94100..29bcfac6c688 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -69,7 +69,7 @@ static void drive_stat_acct(struct request *rq, int new_io)
 	int rw = rq_data_dir(rq);
 	int cpu;
 
-	if (!blk_fs_request(rq) || !disk || !blk_queue_io_stat(disk->queue))
+	if (!blk_fs_request(rq) || !disk || !blk_do_io_stat(disk->queue))
 		return;
 
 	cpu = part_stat_lock();
@@ -1667,7 +1667,7 @@ static void blk_account_io_completion(struct request *req, unsigned int bytes)
 {
 	struct gendisk *disk = req->rq_disk;
 
-	if (!disk || !blk_queue_io_stat(disk->queue))
+	if (!disk || !blk_do_io_stat(disk->queue))
 		return;
 
 	if (blk_fs_request(req)) {
@@ -1686,7 +1686,7 @@ static void blk_account_io_done(struct request *req)
 {
 	struct gendisk *disk = req->rq_disk;
 
-	if (!disk || !blk_queue_io_stat(disk->queue))
+	if (!disk || !blk_do_io_stat(disk->queue))
 		return;
 
 	/*
diff --git a/block/blk.h b/block/blk.h
index 6e1ed40534e9..0dce92c37496 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -108,4 +108,12 @@ static inline int blk_cpu_to_group(int cpu)
 #endif
 }
 
+static inline int blk_do_io_stat(struct request_queue *q)
+{
+	if (q)
+		return blk_queue_io_stat(q);
+
+	return 0;
+}
+
 #endif
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index d7f9839ba264..a7799a99f2d9 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -9,6 +9,7 @@ menuconfig ACPI
 	depends on PCI
 	depends on PM
 	select PNP
+	select CPU_IDLE
 	default y
 	---help---
 	  Advanced Configuration and Power Interface (ACPI) support for 
@@ -287,7 +288,7 @@ config ACPI_CONTAINER
 	  support physical cpu/memory hot-plug.
 
 	  If one selects "m", this driver can be loaded with
-	  "modprobe acpi_container".
+	  "modprobe container".
 
 config ACPI_HOTPLUG_MEMORY
 	tristate "Memory Hotplug"
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 9684cc827930..22ce48985720 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -538,10 +538,9 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
 			if (ACPI_FAILURE(status)) {
 				ACPI_WARNING((AE_INFO,
 					      "Truncating %u table entries!",
-					      (unsigned)
-					      (acpi_gbl_root_table_list.size -
-					       acpi_gbl_root_table_list.
-					       count)));
+					      (unsigned) (table_count -
+					       (acpi_gbl_root_table_list.
+					       count - 2))));
 				break;
 			}
 		}
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c
index da9450bc60f7..9c9897dbe907 100644
--- a/drivers/acpi/acpica/uteval.c
+++ b/drivers/acpi/acpica/uteval.c
@@ -116,9 +116,9 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
-	/* Default return value is SUPPORTED */
+	/* Default return value is 0, NOT-SUPPORTED */
 
-	return_desc->integer.value = ACPI_UINT32_MAX;
+	return_desc->integer.value = 0;
 	walk_state->return_desc = return_desc;
 
 	/* Compare input string to static table of supported interfaces */
@@ -127,10 +127,8 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
 		if (!ACPI_STRCMP
 		    (string_desc->string.pointer,
 		     acpi_interfaces_supported[i])) {
-
-			/* The interface is supported */
-
-			return_ACPI_STATUS(AE_OK);
+			return_desc->integer.value = ACPI_UINT32_MAX;
+			goto done;
 		}
 	}
 
@@ -141,15 +139,14 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
 	 */
 	status = acpi_os_validate_interface(string_desc->string.pointer);
 	if (ACPI_SUCCESS(status)) {
-
-		/* The interface is supported */
-
-		return_ACPI_STATUS(AE_OK);
+		return_desc->integer.value = ACPI_UINT32_MAX;
 	}
 
-	/* The interface is not supported */
+done:
+	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n",
+		string_desc->string.pointer,
+		return_desc->integer.value == 0 ? "not-" : ""));
 
-	return_desc->integer.value = 0;
 	return_ACPI_STATUS(AE_OK);
 }
 
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 17020c12623c..fe0cdf83641a 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -163,7 +163,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
 	case ACPI_NOTIFY_BUS_CHECK:
 		/* Fall through */
 	case ACPI_NOTIFY_DEVICE_CHECK:
-		printk("Container driver received %s event\n",
+		printk(KERN_WARNING "Container driver received %s event\n",
 		       (type == ACPI_NOTIFY_BUS_CHECK) ?
 		       "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK");
 		status = acpi_bus_get_device(handle, &device);
@@ -174,7 +174,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
 					kobject_uevent(&device->dev.kobj,
 						       KOBJ_ONLINE);
 				else
-					printk("Failed to add container\n");
+					printk(KERN_WARNING
+					       "Failed to add container\n");
 			}
 		} else {
 			if (ACPI_SUCCESS(status)) {
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 5b30b8d91d71..35094f230b1e 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -855,10 +855,14 @@ fdd_out:
 static ssize_t show_docked(struct device *dev,
 			   struct device_attribute *attr, char *buf)
 {
+	struct acpi_device *tmp;
+
 	struct dock_station *dock_station = *((struct dock_station **)
 		dev->platform_data);
-	return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station));
 
+	if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp)))
+		return snprintf(buf, PAGE_SIZE, "1\n");
+	return snprintf(buf, PAGE_SIZE, "0\n");
 }
 static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
 
@@ -984,7 +988,7 @@ static int dock_add(acpi_handle handle)
 
 	ret = device_create_file(&dock_device->dev, &dev_attr_docked);
 	if (ret) {
-		printk("Error %d adding sysfs file\n", ret);
+		printk(KERN_ERR "Error %d adding sysfs file\n", ret);
 		platform_device_unregister(dock_device);
 		kfree(dock_station);
 		dock_station = NULL;
@@ -992,7 +996,7 @@ static int dock_add(acpi_handle handle)
 	}
 	ret = device_create_file(&dock_device->dev, &dev_attr_undock);
 	if (ret) {
-		printk("Error %d adding sysfs file\n", ret);
+		printk(KERN_ERR "Error %d adding sysfs file\n", ret);
 		device_remove_file(&dock_device->dev, &dev_attr_docked);
 		platform_device_unregister(dock_device);
 		kfree(dock_station);
@@ -1001,7 +1005,7 @@ static int dock_add(acpi_handle handle)
 	}
 	ret = device_create_file(&dock_device->dev, &dev_attr_uid);
 	if (ret) {
-		printk("Error %d adding sysfs file\n", ret);
+		printk(KERN_ERR "Error %d adding sysfs file\n", ret);
 		device_remove_file(&dock_device->dev, &dev_attr_docked);
 		device_remove_file(&dock_device->dev, &dev_attr_undock);
 		platform_device_unregister(dock_device);
@@ -1011,7 +1015,7 @@ static int dock_add(acpi_handle handle)
 	}
 	ret = device_create_file(&dock_device->dev, &dev_attr_flags);
 	if (ret) {
-		printk("Error %d adding sysfs file\n", ret);
+		printk(KERN_ERR "Error %d adding sysfs file\n", ret);
 		device_remove_file(&dock_device->dev, &dev_attr_docked);
 		device_remove_file(&dock_device->dev, &dev_attr_undock);
 		device_remove_file(&dock_device->dev, &dev_attr_uid);
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index a2b82c90a683..5c2f5d343be6 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -982,7 +982,7 @@ int __init acpi_ec_ecdt_probe(void)
 		saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
 		if (!saved_ec)
 			return -ENOMEM;
-		memcpy(&saved_ec, boot_ec, sizeof(saved_ec));
+		memcpy(saved_ec, boot_ec, sizeof(*saved_ec));
 	/* fall through */
 	}
 	/* This workaround is needed only on some broken machines,
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index adec3d15810a..5479b9f42513 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -255,12 +255,12 @@ static int acpi_platform_notify(struct device *dev)
 	}
 	type = acpi_get_bus_type(dev->bus);
 	if (!type) {
-		DBG("No ACPI bus support for %s\n", dev->bus_id);
+		DBG("No ACPI bus support for %s\n", dev_name(dev));
 		ret = -EINVAL;
 		goto end;
 	}
 	if ((ret = type->find_device(dev, &handle)) != 0)
-		DBG("Can't get handler for %s\n", dev->bus_id);
+		DBG("Can't get handler for %s\n", dev_name(dev));
       end:
 	if (!ret)
 		acpi_bind_one(dev, handle);
@@ -271,10 +271,10 @@ static int acpi_platform_notify(struct device *dev)
 
 		acpi_get_name(dev->archdata.acpi_handle,
 			      ACPI_FULL_PATHNAME, &buffer);
-		DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer);
+		DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer);
 		kfree(buffer.pointer);
 	} else
-		DBG("Device %s -> No ACPI support\n", dev->bus_id);
+		DBG("Device %s -> No ACPI support\n", dev_name(dev));
 #endif
 
 	return ret;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 6729a4992f2b..b3193ec0a2ef 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -228,10 +228,10 @@ void acpi_os_vprintf(const char *fmt, va_list args)
 	if (acpi_in_debugger) {
 		kdb_printf("%s", buffer);
 	} else {
-		printk("%s", buffer);
+		printk(KERN_CONT "%s", buffer);
 	}
 #else
-	printk("%s", buffer);
+	printk(KERN_CONT "%s", buffer);
 #endif
 }
 
@@ -1317,6 +1317,54 @@ acpi_os_validate_interface (char *interface)
 	return AE_SUPPORT;
 }
 
+#ifdef	CONFIG_X86
+
+struct aml_port_desc {
+	uint	start;
+	uint	end;
+	char*   name;
+	char	warned;
+};
+
+static struct aml_port_desc aml_invalid_port_list[] = {
+	{0x20, 0x21, "PIC0", 0},
+	{0xA0, 0xA1, "PIC1", 0},
+	{0x4D0, 0x4D1, "ELCR", 0}
+};
+
+/*
+ * valid_aml_io_address()
+ *
+ * if valid, return true
+ * else invalid, warn once, return false
+ */
+static bool valid_aml_io_address(uint address, uint length)
+{
+	int i;
+	int entries = sizeof(aml_invalid_port_list) / sizeof(struct aml_port_desc);
+
+	for (i = 0; i < entries; ++i) {
+		if ((address >= aml_invalid_port_list[i].start &&
+			address <= aml_invalid_port_list[i].end) ||
+			(address + length >= aml_invalid_port_list[i].start &&
+			address  + length <= aml_invalid_port_list[i].end))
+		{
+			if (!aml_invalid_port_list[i].warned)
+			{
+				printk(KERN_ERR "ACPI: Denied BIOS AML access"
+					" to invalid port 0x%x+0x%x (%s)\n",
+					address, length,
+					aml_invalid_port_list[i].name);
+				aml_invalid_port_list[i].warned = 1;
+			}
+			return false;	/* invalid */
+		}
+	}
+	return true;	/* valid */
+}
+#else
+static inline bool valid_aml_io_address(uint address, uint length) { return true; }
+#endif
 /******************************************************************************
  *
  * FUNCTION:    acpi_os_validate_address
@@ -1346,6 +1394,8 @@ acpi_os_validate_address (
 
 	switch (space_id) {
 	case ACPI_ADR_SPACE_SYSTEM_IO:
+		if (!valid_aml_io_address(address, length))
+			return AE_AML_ILLEGAL_ADDRESS;
 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 		/* Only interference checks against SystemIO and SytemMemory
 		   are needed */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 1c6e73c7865e..6c772ca76bd1 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -593,7 +593,7 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
 		return -ENODEV;
 	} else {
 		acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING;
-		printk(PREFIX "%s [%s] enabled at IRQ %d\n",
+		printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n",
 		       acpi_device_name(link->device),
 		       acpi_device_bid(link->device), link->irq.active);
 	}
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 66a9d8145562..7bc22a471fe3 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -66,43 +66,17 @@ ACPI_MODULE_NAME("processor_idle");
 #define ACPI_PROCESSOR_FILE_POWER	"power"
 #define US_TO_PM_TIMER_TICKS(t)		((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
 #define PM_TIMER_TICK_NS		(1000000000ULL/PM_TIMER_FREQUENCY)
-#ifndef CONFIG_CPU_IDLE
-#define C2_OVERHEAD			4	/* 1us (3.579 ticks per us) */
-#define C3_OVERHEAD			4	/* 1us (3.579 ticks per us) */
-static void (*pm_idle_save) (void) __read_mostly;
-#else
 #define C2_OVERHEAD			1	/* 1us */
 #define C3_OVERHEAD			1	/* 1us */
-#endif
 #define PM_TIMER_TICKS_TO_US(p)		(((p) * 1000)/(PM_TIMER_FREQUENCY/1000))
 
 static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
-#ifdef CONFIG_CPU_IDLE
 module_param(max_cstate, uint, 0000);
-#else
-module_param(max_cstate, uint, 0644);
-#endif
 static unsigned int nocst __read_mostly;
 module_param(nocst, uint, 0000);
 
-#ifndef CONFIG_CPU_IDLE
-/*
- * bm_history -- bit-mask with a bit per jiffy of bus-master activity
- * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms
- * 800 HZ: 0xFFFFFFFF: 32 jiffies = 40ms
- * 100 HZ: 0x0000000F: 4 jiffies = 40ms
- * reduce history for more aggressive entry into C3
- */
-static unsigned int bm_history __read_mostly =
-    (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
-module_param(bm_history, uint, 0644);
-
-static int acpi_processor_set_power_policy(struct acpi_processor *pr);
-
-#else	/* CONFIG_CPU_IDLE */
 static unsigned int latency_factor __read_mostly = 2;
 module_param(latency_factor, uint, 0644);
-#endif
 
 /*
  * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
@@ -224,71 +198,6 @@ static void acpi_safe_halt(void)
 	current_thread_info()->status |= TS_POLLING;
 }
 
-#ifndef CONFIG_CPU_IDLE
-
-static void
-acpi_processor_power_activate(struct acpi_processor *pr,
-			      struct acpi_processor_cx *new)
-{
-	struct acpi_processor_cx *old;
-
-	if (!pr || !new)
-		return;
-
-	old = pr->power.state;
-
-	if (old)
-		old->promotion.count = 0;
-	new->demotion.count = 0;
-
-	/* Cleanup from old state. */
-	if (old) {
-		switch (old->type) {
-		case ACPI_STATE_C3:
-			/* Disable bus master reload */
-			if (new->type != ACPI_STATE_C3 && pr->flags.bm_check)
-				acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
-			break;
-		}
-	}
-
-	/* Prepare to use new state. */
-	switch (new->type) {
-	case ACPI_STATE_C3:
-		/* Enable bus master reload */
-		if (old->type != ACPI_STATE_C3 && pr->flags.bm_check)
-			acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
-		break;
-	}
-
-	pr->power.state = new;
-
-	return;
-}
-
-static atomic_t c3_cpu_count;
-
-/* Common C-state entry for C2, C3, .. */
-static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
-{
-	/* Don't trace irqs off for idle */
-	stop_critical_timings();
-	if (cstate->entry_method == ACPI_CSTATE_FFH) {
-		/* Call into architectural FFH based C-state */
-		acpi_processor_ffh_cstate_enter(cstate);
-	} else {
-		int unused;
-		/* IO port based C-state */
-		inb(cstate->address);
-		/* Dummy wait op - must do something useless after P_LVL2 read
-		   because chipsets cannot guarantee that STPCLK# signal
-		   gets asserted in time to freeze execution properly. */
-		unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
-	}
-	start_critical_timings();
-}
-#endif /* !CONFIG_CPU_IDLE */
-
 #ifdef ARCH_APICTIMER_STOPS_ON_C3
 
 /*
@@ -390,421 +299,6 @@ static int tsc_halts_in_c(int state)
 }
 #endif
 
-#ifndef CONFIG_CPU_IDLE
-static void acpi_processor_idle(void)
-{
-	struct acpi_processor *pr = NULL;
-	struct acpi_processor_cx *cx = NULL;
-	struct acpi_processor_cx *next_state = NULL;
-	int sleep_ticks = 0;
-	u32 t1, t2 = 0;
-
-	/*
-	 * Interrupts must be disabled during bus mastering calculations and
-	 * for C2/C3 transitions.
-	 */
-	local_irq_disable();
-
-	pr = __get_cpu_var(processors);
-	if (!pr) {
-		local_irq_enable();
-		return;
-	}
-
-	/*
-	 * Check whether we truly need to go idle, or should
-	 * reschedule:
-	 */
-	if (unlikely(need_resched())) {
-		local_irq_enable();
-		return;
-	}
-
-	cx = pr->power.state;
-	if (!cx || acpi_idle_suspend) {
-		if (pm_idle_save) {
-			pm_idle_save(); /* enables IRQs */
-		} else {
-			acpi_safe_halt();
-			local_irq_enable();
-		}
-
-		return;
-	}
-
-	/*
-	 * Check BM Activity
-	 * -----------------
-	 * Check for bus mastering activity (if required), record, and check
-	 * for demotion.
-	 */
-	if (pr->flags.bm_check) {
-		u32 bm_status = 0;
-		unsigned long diff = jiffies - pr->power.bm_check_timestamp;
-
-		if (diff > 31)
-			diff = 31;
-
-		pr->power.bm_activity <<= diff;
-
-		acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
-		if (bm_status) {
-			pr->power.bm_activity |= 0x1;
-			acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
-		}
-		/*
-		 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
-		 * the true state of bus mastering activity; forcing us to
-		 * manually check the BMIDEA bit of each IDE channel.
-		 */
-		else if (errata.piix4.bmisx) {
-			if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
-			    || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
-				pr->power.bm_activity |= 0x1;
-		}
-
-		pr->power.bm_check_timestamp = jiffies;
-
-		/*
-		 * If bus mastering is or was active this jiffy, demote
-		 * to avoid a faulty transition.  Note that the processor
-		 * won't enter a low-power state during this call (to this
-		 * function) but should upon the next.
-		 *
-		 * TBD: A better policy might be to fallback to the demotion
-		 *      state (use it for this quantum only) istead of
-		 *      demoting -- and rely on duration as our sole demotion
-		 *      qualification.  This may, however, introduce DMA
-		 *      issues (e.g. floppy DMA transfer overrun/underrun).
-		 */
-		if ((pr->power.bm_activity & 0x1) &&
-		    cx->demotion.threshold.bm) {
-			local_irq_enable();
-			next_state = cx->demotion.state;
-			goto end;
-		}
-	}
-
-#ifdef CONFIG_HOTPLUG_CPU
-	/*
-	 * Check for P_LVL2_UP flag before entering C2 and above on
-	 * an SMP system. We do it here instead of doing it at _CST/P_LVL
-	 * detection phase, to work cleanly with logical CPU hotplug.
-	 */
-	if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
-	    !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
-		cx = &pr->power.states[ACPI_STATE_C1];
-#endif
-
-	/*
-	 * Sleep:
-	 * ------
-	 * Invoke the current Cx state to put the processor to sleep.
-	 */
-	if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) {
-		current_thread_info()->status &= ~TS_POLLING;
-		/*
-		 * TS_POLLING-cleared state must be visible before we
-		 * test NEED_RESCHED:
-		 */
-		smp_mb();
-		if (need_resched()) {
-			current_thread_info()->status |= TS_POLLING;
-			local_irq_enable();
-			return;
-		}
-	}
-
-	switch (cx->type) {
-
-	case ACPI_STATE_C1:
-		/*
-		 * Invoke C1.
-		 * Use the appropriate idle routine, the one that would
-		 * be used without acpi C-states.
-		 */
-		if (pm_idle_save) {
-			pm_idle_save(); /* enables IRQs */
-		} else {
-			acpi_safe_halt();
-			local_irq_enable();
-		}
-
-		/*
-		 * TBD: Can't get time duration while in C1, as resumes
-		 *      go to an ISR rather than here.  Need to instrument
-		 *      base interrupt handler.
-		 *
-		 * Note: the TSC better not stop in C1, sched_clock() will
-		 *       skew otherwise.
-		 */
-		sleep_ticks = 0xFFFFFFFF;
-
-		break;
-
-	case ACPI_STATE_C2:
-		/* Get start time (ticks) */
-		t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-		/* Tell the scheduler that we are going deep-idle: */
-		sched_clock_idle_sleep_event();
-		/* Invoke C2 */
-		acpi_state_timer_broadcast(pr, cx, 1);
-		acpi_cstate_enter(cx);
-		/* Get end time (ticks) */
-		t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
-		/* TSC halts in C2, so notify users */
-		if (tsc_halts_in_c(ACPI_STATE_C2))
-			mark_tsc_unstable("possible TSC halt in C2");
-#endif
-		/* Compute time (ticks) that we were actually asleep */
-		sleep_ticks = ticks_elapsed(t1, t2);
-
-		/* Tell the scheduler how much we idled: */
-		sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
-
-		/* Re-enable interrupts */
-		local_irq_enable();
-		/* Do not account our idle-switching overhead: */
-		sleep_ticks -= cx->latency_ticks + C2_OVERHEAD;
-
-		current_thread_info()->status |= TS_POLLING;
-		acpi_state_timer_broadcast(pr, cx, 0);
-		break;
-
-	case ACPI_STATE_C3:
-		acpi_unlazy_tlb(smp_processor_id());
-		/*
-		 * Must be done before busmaster disable as we might
-		 * need to access HPET !
-		 */
-		acpi_state_timer_broadcast(pr, cx, 1);
-		/*
-		 * disable bus master
-		 * bm_check implies we need ARB_DIS
-		 * !bm_check implies we need cache flush
-		 * bm_control implies whether we can do ARB_DIS
-		 *
-		 * That leaves a case where bm_check is set and bm_control is
-		 * not set. In that case we cannot do much, we enter C3
-		 * without doing anything.
-		 */
-		if (pr->flags.bm_check && pr->flags.bm_control) {
-			if (atomic_inc_return(&c3_cpu_count) ==
-			    num_online_cpus()) {
-				/*
-				 * All CPUs are trying to go to C3
-				 * Disable bus master arbitration
-				 */
-				acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
-			}
-		} else if (!pr->flags.bm_check) {
-			/* SMP with no shared cache... Invalidate cache  */
-			ACPI_FLUSH_CPU_CACHE();
-		}
-
-		/* Get start time (ticks) */
-		t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-		/* Invoke C3 */
-		/* Tell the scheduler that we are going deep-idle: */
-		sched_clock_idle_sleep_event();
-		acpi_cstate_enter(cx);
-		/* Get end time (ticks) */
-		t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-		if (pr->flags.bm_check && pr->flags.bm_control) {
-			/* Enable bus master arbitration */
-			atomic_dec(&c3_cpu_count);
-			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
-		}
-
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
-		/* TSC halts in C3, so notify users */
-		if (tsc_halts_in_c(ACPI_STATE_C3))
-			mark_tsc_unstable("TSC halts in C3");
-#endif
-		/* Compute time (ticks) that we were actually asleep */
-		sleep_ticks = ticks_elapsed(t1, t2);
-		/* Tell the scheduler how much we idled: */
-		sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
-
-		/* Re-enable interrupts */
-		local_irq_enable();
-		/* Do not account our idle-switching overhead: */
-		sleep_ticks -= cx->latency_ticks + C3_OVERHEAD;
-
-		current_thread_info()->status |= TS_POLLING;
-		acpi_state_timer_broadcast(pr, cx, 0);
-		break;
-
-	default:
-		local_irq_enable();
-		return;
-	}
-	cx->usage++;
-	if ((cx->type != ACPI_STATE_C1) && (sleep_ticks > 0))
-		cx->time += sleep_ticks;
-
-	next_state = pr->power.state;
-
-#ifdef CONFIG_HOTPLUG_CPU
-	/* Don't do promotion/demotion */
-	if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) &&
-	    !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) {
-		next_state = cx;
-		goto end;
-	}
-#endif
-
-	/*
-	 * Promotion?
-	 * ----------
-	 * Track the number of longs (time asleep is greater than threshold)
-	 * and promote when the count threshold is reached.  Note that bus
-	 * mastering activity may prevent promotions.
-	 * Do not promote above max_cstate.
-	 */
-	if (cx->promotion.state &&
-	    ((cx->promotion.state - pr->power.states) <= max_cstate)) {
-		if (sleep_ticks > cx->promotion.threshold.ticks &&
-		  cx->promotion.state->latency <=
-				pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) {
-			cx->promotion.count++;
-			cx->demotion.count = 0;
-			if (cx->promotion.count >=
-			    cx->promotion.threshold.count) {
-				if (pr->flags.bm_check) {
-					if (!
-					    (pr->power.bm_activity & cx->
-					     promotion.threshold.bm)) {
-						next_state =
-						    cx->promotion.state;
-						goto end;
-					}
-				} else {
-					next_state = cx->promotion.state;
-					goto end;
-				}
-			}
-		}
-	}
-
-	/*
-	 * Demotion?
-	 * ---------
-	 * Track the number of shorts (time asleep is less than time threshold)
-	 * and demote when the usage threshold is reached.
-	 */
-	if (cx->demotion.state) {
-		if (sleep_ticks < cx->demotion.threshold.ticks) {
-			cx->demotion.count++;
-			cx->promotion.count = 0;
-			if (cx->demotion.count >= cx->demotion.threshold.count) {
-				next_state = cx->demotion.state;
-				goto end;
-			}
-		}
-	}
-
-      end:
-	/*
-	 * Demote if current state exceeds max_cstate
-	 * or if the latency of the current state is unacceptable
-	 */
-	if ((pr->power.state - pr->power.states) > max_cstate ||
-		pr->power.state->latency >
-				pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) {
-		if (cx->demotion.state)
-			next_state = cx->demotion.state;
-	}
-
-	/*
-	 * New Cx State?
-	 * -------------
-	 * If we're going to start using a new Cx state we must clean up
-	 * from the previous and prepare to use the new.
-	 */
-	if (next_state != pr->power.state)
-		acpi_processor_power_activate(pr, next_state);
-}
-
-static int acpi_processor_set_power_policy(struct acpi_processor *pr)
-{
-	unsigned int i;
-	unsigned int state_is_set = 0;
-	struct acpi_processor_cx *lower = NULL;
-	struct acpi_processor_cx *higher = NULL;
-	struct acpi_processor_cx *cx;
-
-
-	if (!pr)
-		return -EINVAL;
-
-	/*
-	 * This function sets the default Cx state policy (OS idle handler).
-	 * Our scheme is to promote quickly to C2 but more conservatively
-	 * to C3.  We're favoring C2  for its characteristics of low latency
-	 * (quick response), good power savings, and ability to allow bus
-	 * mastering activity.  Note that the Cx state policy is completely
-	 * customizable and can be altered dynamically.
-	 */
-
-	/* startup state */
-	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
-		cx = &pr->power.states[i];
-		if (!cx->valid)
-			continue;
-
-		if (!state_is_set)
-			pr->power.state = cx;
-		state_is_set++;
-		break;
-	}
-
-	if (!state_is_set)
-		return -ENODEV;
-
-	/* demotion */
-	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
-		cx = &pr->power.states[i];
-		if (!cx->valid)
-			continue;
-
-		if (lower) {
-			cx->demotion.state = lower;
-			cx->demotion.threshold.ticks = cx->latency_ticks;
-			cx->demotion.threshold.count = 1;
-			if (cx->type == ACPI_STATE_C3)
-				cx->demotion.threshold.bm = bm_history;
-		}
-
-		lower = cx;
-	}
-
-	/* promotion */
-	for (i = (ACPI_PROCESSOR_MAX_POWER - 1); i > 0; i--) {
-		cx = &pr->power.states[i];
-		if (!cx->valid)
-			continue;
-
-		if (higher) {
-			cx->promotion.state = higher;
-			cx->promotion.threshold.ticks = cx->latency_ticks;
-			if (cx->type >= ACPI_STATE_C2)
-				cx->promotion.threshold.count = 4;
-			else
-				cx->promotion.threshold.count = 10;
-			if (higher->type == ACPI_STATE_C3)
-				cx->promotion.threshold.bm = bm_history;
-		}
-
-		higher = cx;
-	}
-
-	return 0;
-}
-#endif /* !CONFIG_CPU_IDLE */
-
 static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
 {
 
@@ -1047,11 +541,7 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
 	 */
 	cx->valid = 1;
 
-#ifndef CONFIG_CPU_IDLE
-	cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
-#else
 	cx->latency_ticks = cx->latency;
-#endif
 
 	return;
 }
@@ -1121,7 +611,6 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
 					  " for C3 to be enabled on SMP systems\n"));
 			return;
 		}
-		acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
 	}
 
 	/*
@@ -1132,11 +621,16 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
 	 */
 	cx->valid = 1;
 
-#ifndef CONFIG_CPU_IDLE
-	cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
-#else
 	cx->latency_ticks = cx->latency;
-#endif
+	/*
+	 * On older chipsets, BM_RLD needs to be set
+	 * in order for Bus Master activity to wake the
+	 * system from C3.  Newer chipsets handle DMA
+	 * during C3 automatically and BM_RLD is a NOP.
+	 * In either case, the proper way to
+	 * handle BM_RLD is to set it and leave it set.
+	 */
+	acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
 
 	return;
 }
@@ -1201,20 +695,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
 
 	pr->power.count = acpi_processor_power_verify(pr);
 
-#ifndef CONFIG_CPU_IDLE
-	/*
-	 * Set Default Policy
-	 * ------------------
-	 * Now that we know which states are supported, set the default
-	 * policy.  Note that this policy can be changed dynamically
-	 * (e.g. encourage deeper sleeps to conserve battery life when
-	 * not on AC).
-	 */
-	result = acpi_processor_set_power_policy(pr);
-	if (result)
-		return result;
-#endif
-
 	/*
 	 * if one state of type C2 or C3 is available, mark this
 	 * CPU as being "idle manageable"
@@ -1312,69 +792,6 @@ static const struct file_operations acpi_processor_power_fops = {
 	.release = single_release,
 };
 
-#ifndef CONFIG_CPU_IDLE
-
-int acpi_processor_cst_has_changed(struct acpi_processor *pr)
-{
-	int result = 0;
-
-	if (boot_option_idle_override)
-		return 0;
-
-	if (!pr)
-		return -EINVAL;
-
-	if (nocst) {
-		return -ENODEV;
-	}
-
-	if (!pr->flags.power_setup_done)
-		return -ENODEV;
-
-	/*
-	 * Fall back to the default idle loop, when pm_idle_save had
-	 * been initialized.
-	 */
-	if (pm_idle_save) {
-		pm_idle = pm_idle_save;
-		/* Relies on interrupts forcing exit from idle. */
-		synchronize_sched();
-	}
-
-	pr->flags.power = 0;
-	result = acpi_processor_get_power_info(pr);
-	if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
-		pm_idle = acpi_processor_idle;
-
-	return result;
-}
-
-#ifdef CONFIG_SMP
-static void smp_callback(void *v)
-{
-	/* we already woke the CPU up, nothing more to do */
-}
-
-/*
- * This function gets called when a part of the kernel has a new latency
- * requirement.  This means we need to get all processors out of their C-state,
- * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that
- * wakes them all right up.
- */
-static int acpi_processor_latency_notify(struct notifier_block *b,
-		unsigned long l, void *v)
-{
-	smp_call_function(smp_callback, NULL, 1);
-	return NOTIFY_OK;
-}
-
-static struct notifier_block acpi_processor_latency_notifier = {
-	.notifier_call = acpi_processor_latency_notify,
-};
-
-#endif
-
-#else /* CONFIG_CPU_IDLE */
 
 /**
  * acpi_idle_bm_check - checks if bus master activity was detected
@@ -1383,7 +800,7 @@ static int acpi_idle_bm_check(void)
 {
 	u32 bm_status = 0;
 
-	acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
+	acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
 	if (bm_status)
 		acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
 	/*
@@ -1400,25 +817,6 @@ static int acpi_idle_bm_check(void)
 }
 
 /**
- * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state
- * @pr: the processor
- * @target: the new target state
- */
-static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr,
-					   struct acpi_processor_cx *target)
-{
-	if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) {
-		acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
-		pr->flags.bm_rld_set = 0;
-	}
-
-	if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) {
-		acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
-		pr->flags.bm_rld_set = 1;
-	}
-}
-
-/**
  * acpi_idle_do_entry - a helper function that does C2 and C3 type entry
  * @cx: cstate data
  *
@@ -1473,9 +871,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
 		return 0;
 	}
 
-	if (pr->flags.bm_check)
-		acpi_idle_update_bm_rld(pr, cx);
-
 	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 	acpi_idle_do_entry(cx);
 	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
@@ -1527,9 +922,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
 	 */
 	acpi_state_timer_broadcast(pr, cx, 1);
 
-	if (pr->flags.bm_check)
-		acpi_idle_update_bm_rld(pr, cx);
-
 	if (cx->type == ACPI_STATE_C3)
 		ACPI_FLUSH_CPU_CACHE();
 
@@ -1621,8 +1013,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 	 */
 	acpi_state_timer_broadcast(pr, cx, 1);
 
-	acpi_idle_update_bm_rld(pr, cx);
-
 	/*
 	 * disable bus master
 	 * bm_check implies we need ARB_DIS
@@ -1795,8 +1185,6 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
 	return ret;
 }
 
-#endif /* CONFIG_CPU_IDLE */
-
 int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
 			      struct acpi_device *device)
 {
@@ -1825,10 +1213,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
 			       "ACPI: processor limited to max C-state %d\n",
 			       max_cstate);
 		first_run++;
-#if !defined(CONFIG_CPU_IDLE) && defined(CONFIG_SMP)
-		pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY,
-				&acpi_processor_latency_notifier);
-#endif
 	}
 
 	if (!pr)
@@ -1852,11 +1236,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
 	 * platforms that only support C1.
 	 */
 	if (pr->flags.power) {
-#ifdef CONFIG_CPU_IDLE
 		acpi_processor_setup_cpuidle(pr);
 		if (cpuidle_register_device(&pr->power.dev))
 			return -EIO;
-#endif
 
 		printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id);
 		for (i = 1; i <= pr->power.count; i++)
@@ -1864,13 +1246,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
 				printk(" C%d[C%d]", i,
 				       pr->power.states[i].type);
 		printk(")\n");
-
-#ifndef CONFIG_CPU_IDLE
-		if (pr->id == 0) {
-			pm_idle_save = pm_idle;
-			pm_idle = acpi_processor_idle;
-		}
-#endif
 	}
 
 	/* 'power' [R] */
@@ -1889,34 +1264,12 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
 	if (boot_option_idle_override)
 		return 0;
 
-#ifdef CONFIG_CPU_IDLE
 	cpuidle_unregister_device(&pr->power.dev);
-#endif
 	pr->flags.power_setup_done = 0;
 
 	if (acpi_device_dir(device))
 		remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,
 				  acpi_device_dir(device));
 
-#ifndef CONFIG_CPU_IDLE
-
-	/* Unregister the idle handler when processor #0 is removed. */
-	if (pr->id == 0) {
-		if (pm_idle_save)
-			pm_idle = pm_idle_save;
-
-		/*
-		 * We are about to unload the current idle thread pm callback
-		 * (pm_idle), Wait for all processors to update cached/local
-		 * copies of pm_idle before proceeding.
-		 */
-		cpu_idle_wait();
-#ifdef CONFIG_SMP
-		pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY,
-				&acpi_processor_latency_notifier);
-#endif
-	}
-#endif
-
 	return 0;
 }
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 846e227592d4..9cc769b587ff 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -31,14 +31,6 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 
-#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-#endif
-
 #ifdef CONFIG_X86
 #include <asm/cpufeature.h>
 #endif
@@ -434,96 +426,6 @@ int acpi_processor_notify_smm(struct module *calling_module)
 
 EXPORT_SYMBOL(acpi_processor_notify_smm);
 
-#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
-/* /proc/acpi/processor/../performance interface (DEPRECATED) */
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_processor_perf_fops = {
-	.owner = THIS_MODULE,
-	.open = acpi_processor_perf_open_fs,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
-{
-	struct acpi_processor *pr = seq->private;
-	int i;
-
-
-	if (!pr)
-		goto end;
-
-	if (!pr->performance) {
-		seq_puts(seq, "<not supported>\n");
-		goto end;
-	}
-
-	seq_printf(seq, "state count:             %d\n"
-		   "active state:            P%d\n",
-		   pr->performance->state_count, pr->performance->state);
-
-	seq_puts(seq, "states:\n");
-	for (i = 0; i < pr->performance->state_count; i++)
-		seq_printf(seq,
-			   "   %cP%d:                  %d MHz, %d mW, %d uS\n",
-			   (i == pr->performance->state ? '*' : ' '), i,
-			   (u32) pr->performance->states[i].core_frequency,
-			   (u32) pr->performance->states[i].power,
-			   (u32) pr->performance->states[i].transition_latency);
-
-      end:
-	return 0;
-}
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_processor_perf_seq_show,
-			   PDE(inode)->data);
-}
-
-static void acpi_cpufreq_add_file(struct acpi_processor *pr)
-{
-	struct acpi_device *device = NULL;
-
-
-	if (acpi_bus_get_device(pr->handle, &device))
-		return;
-
-	/* add file 'performance' [R/W] */
-	proc_create_data(ACPI_PROCESSOR_FILE_PERFORMANCE, S_IFREG | S_IRUGO,
-			 acpi_device_dir(device),
-			 &acpi_processor_perf_fops, acpi_driver_data(device));
-	return;
-}
-
-static void acpi_cpufreq_remove_file(struct acpi_processor *pr)
-{
-	struct acpi_device *device = NULL;
-
-
-	if (acpi_bus_get_device(pr->handle, &device))
-		return;
-
-	/* remove file 'performance' */
-	remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
-			  acpi_device_dir(device));
-
-	return;
-}
-
-#else
-static void acpi_cpufreq_add_file(struct acpi_processor *pr)
-{
-	return;
-}
-static void acpi_cpufreq_remove_file(struct acpi_processor *pr)
-{
-	return;
-}
-#endif				/* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
-
 static int acpi_processor_get_psd(struct acpi_processor	*pr)
 {
 	int result = 0;
@@ -747,14 +649,12 @@ err_ret:
 }
 EXPORT_SYMBOL(acpi_processor_preregister_performance);
 
-
 int
 acpi_processor_register_performance(struct acpi_processor_performance
 				    *performance, unsigned int cpu)
 {
 	struct acpi_processor *pr;
 
-
 	if (!(acpi_processor_ppc_status & PPC_REGISTERED))
 		return -EINVAL;
 
@@ -781,8 +681,6 @@ acpi_processor_register_performance(struct acpi_processor_performance
 		return -EIO;
 	}
 
-	acpi_cpufreq_add_file(pr);
-
 	mutex_unlock(&performance_mutex);
 	return 0;
 }
@@ -795,7 +693,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance
 {
 	struct acpi_processor *pr;
 
-
 	mutex_lock(&performance_mutex);
 
 	pr = per_cpu(processors, cpu);
@@ -808,8 +705,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance
 		kfree(pr->performance->states);
 	pr->performance = NULL;
 
-	acpi_cpufreq_remove_file(pr);
-
 	mutex_unlock(&performance_mutex);
 
 	return;
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 7e3c609cbef2..519266654f06 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -90,31 +90,6 @@ void __init acpi_old_suspend_ordering(void)
 	old_suspend_ordering = true;
 }
 
-/*
- * According to the ACPI specification the BIOS should make sure that ACPI is
- * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states.  Still,
- * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
- * on such systems during resume.  Unfortunately that doesn't help in
- * particularly pathological cases in which SCI_EN has to be set directly on
- * resume, although the specification states very clearly that this flag is
- * owned by the hardware.  The set_sci_en_on_resume variable will be set in such
- * cases.
- */
-static bool set_sci_en_on_resume;
-/*
- * The ACPI specification wants us to save NVS memory regions during hibernation
- * and to restore them during the subsequent resume.  However, it is not certain
- * if this mechanism is going to work on all machines, so we allow the user to
- * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line
- * option.
- */
-static bool s4_no_nvs;
-
-void __init acpi_s4_no_nvs(void)
-{
-	s4_no_nvs = true;
-}
-
 /**
  *	acpi_pm_disable_gpes - Disable the GPEs.
  */
@@ -193,6 +168,18 @@ static void acpi_pm_end(void)
 #endif /* CONFIG_ACPI_SLEEP */
 
 #ifdef CONFIG_SUSPEND
+/*
+ * According to the ACPI specification the BIOS should make sure that ACPI is
+ * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states.  Still,
+ * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
+ * on such systems during resume.  Unfortunately that doesn't help in
+ * particularly pathological cases in which SCI_EN has to be set directly on
+ * resume, although the specification states very clearly that this flag is
+ * owned by the hardware.  The set_sci_en_on_resume variable will be set in such
+ * cases.
+ */
+static bool set_sci_en_on_resume;
+
 extern void do_suspend_lowlevel(void);
 
 static u32 acpi_suspend_states[] = {
@@ -396,6 +383,20 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
 #endif /* CONFIG_SUSPEND */
 
 #ifdef CONFIG_HIBERNATION
+/*
+ * The ACPI specification wants us to save NVS memory regions during hibernation
+ * and to restore them during the subsequent resume.  However, it is not certain
+ * if this mechanism is going to work on all machines, so we allow the user to
+ * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line
+ * option.
+ */
+static bool s4_no_nvs;
+
+void __init acpi_s4_no_nvs(void)
+{
+	s4_no_nvs = true;
+}
+
 static unsigned long s4_hardware_signature;
 static struct acpi_table_facs *facs;
 static bool nosigcheck;
@@ -679,7 +680,7 @@ static void acpi_power_off_prepare(void)
 static void acpi_power_off(void)
 {
 	/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
-	printk("%s called\n", __func__);
+	printk(KERN_DEBUG "%s called\n", __func__);
 	local_irq_disable();
 	acpi_enable_wakeup_device(ACPI_STATE_S5);
 	acpi_enter_sleep_state(ACPI_STATE_S5);
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 775c97a282bd..a8852952fac4 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -293,7 +293,12 @@ static void __init check_multiple_madt(void)
 
 int __init acpi_table_init(void)
 {
-	acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
+	acpi_status status;
+
+	status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
+	if (ACPI_FAILURE(status))
+		return 1;
+
 	check_multiple_madt();
 	return 0;
 }
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index f261737636da..bb5ed059114a 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1020,7 +1020,7 @@ acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
 	}
 
 	seq_printf(seq, "levels: ");
-	for (i = 0; i < dev->brightness->count; i++)
+	for (i = 2; i < dev->brightness->count; i++)
 		seq_printf(seq, " %d", dev->brightness->levels[i]);
 	seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr);
 
@@ -1059,7 +1059,7 @@ acpi_video_device_write_brightness(struct file *file,
 		return -EFAULT;
 
 	/* validate through the list of available levels */
-	for (i = 0; i < dev->brightness->count; i++)
+	for (i = 2; i < dev->brightness->count; i++)
 		if (level == dev->brightness->levels[i]) {
 			if (ACPI_SUCCESS
 			    (acpi_video_device_lcd_set_level(dev, level)))
@@ -1260,7 +1260,7 @@ static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
 			printk(KERN_WARNING PREFIX
 			       "This indicates a BIOS bug. Please contact the manufacturer.\n");
 		}
-		printk("%llx\n", options);
+		printk(KERN_WARNING "%llx\n", options);
 		seq_printf(seq, "can POST: <integrated video>");
 		if (options & 2)
 			seq_printf(seq, " <PCI video>");
@@ -1712,7 +1712,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
 	max = max_below = 0;
 	min = min_above = 255;
 	/* Find closest level to level_current */
-	for (i = 0; i < device->brightness->count; i++) {
+	for (i = 2; i < device->brightness->count; i++) {
 		l = device->brightness->levels[i];
 		if (abs(l - level_current) < abs(delta)) {
 			delta = l - level_current;
@@ -1722,7 +1722,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
 	}
 	/* Ajust level_current to closest available level */
 	level_current += delta;
-	for (i = 0; i < device->brightness->count; i++) {
+	for (i = 2; i < device->brightness->count; i++) {
 		l = device->brightness->levels[i];
 		if (l < min)
 			min = l;
@@ -2006,6 +2006,12 @@ static int acpi_video_bus_add(struct acpi_device *device)
 			device->pnp.bus_id[3] = '0' + instance;
 		instance ++;
 	}
+	/* a hack to fix the duplicate name "VGA" problem on Pa 3553 */
+	if (!strcmp(device->pnp.bus_id, "VGA")) {
+		if (instance)
+			device->pnp.bus_id[3] = '0' + instance;
+		instance++;
+	}
 
 	video->device = device;
 	strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 77bba4c083cb..a603bbf9b1b7 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -61,9 +61,14 @@
 #define EM_MSG_LED_VALUE_ON           0x00010000
 
 static int ahci_skip_host_reset;
+static int ahci_ignore_sss;
+
 module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444);
 MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)");
 
+module_param_named(ignore_sss, ahci_ignore_sss, int, 0444);
+MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)");
+
 static int ahci_enable_alpm(struct ata_port *ap,
 		enum link_pm policy);
 static void ahci_disable_alpm(struct ata_port *ap);
@@ -2692,8 +2697,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	host->iomap = pcim_iomap_table(pdev);
 	host->private_data = hpriv;
 
-	if (!(hpriv->cap & HOST_CAP_SSS))
+	if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
 		host->flags |= ATA_HOST_PARALLEL_SCAN;
+	else
+		printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n");
 
 	if (pi.flags & ATA_FLAG_EM)
 		ahci_reset_em(host);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 88c242856dae..9fbf0595f3d4 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -164,6 +164,11 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
 
+static bool ata_sstatus_online(u32 sstatus)
+{
+	return (sstatus & 0xf) == 0x3;
+}
+
 /**
  *	ata_link_next - link iteration helper
  *	@link: the previous link, NULL to start
@@ -1015,18 +1020,6 @@ static const char *sata_spd_string(unsigned int spd)
 	return spd_str[spd - 1];
 }
 
-void ata_dev_disable(struct ata_device *dev)
-{
-	if (ata_dev_enabled(dev)) {
-		if (ata_msg_drv(dev->link->ap))
-			ata_dev_printk(dev, KERN_WARNING, "disabled\n");
-		ata_acpi_on_disable(dev);
-		ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 |
-					     ATA_DNXFER_QUIET);
-		dev->class++;
-	}
-}
-
 static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy)
 {
 	struct ata_link *link = dev->link;
@@ -2239,6 +2232,40 @@ retry:
 	return rc;
 }
 
+static int ata_do_link_spd_horkage(struct ata_device *dev)
+{
+	struct ata_link *plink = ata_dev_phys_link(dev);
+	u32 target, target_limit;
+
+	if (!sata_scr_valid(plink))
+		return 0;
+
+	if (dev->horkage & ATA_HORKAGE_1_5_GBPS)
+		target = 1;
+	else
+		return 0;
+
+	target_limit = (1 << target) - 1;
+
+	/* if already on stricter limit, no need to push further */
+	if (plink->sata_spd_limit <= target_limit)
+		return 0;
+
+	plink->sata_spd_limit = target_limit;
+
+	/* Request another EH round by returning -EAGAIN if link is
+	 * going faster than the target speed.  Forward progress is
+	 * guaranteed by setting sata_spd_limit to target_limit above.
+	 */
+	if (plink->sata_spd > target) {
+		ata_dev_printk(dev, KERN_INFO,
+			       "applying link speed limit horkage to %s\n",
+			       sata_spd_string(target));
+		return -EAGAIN;
+	}
+	return 0;
+}
+
 static inline u8 ata_dev_knobble(struct ata_device *dev)
 {
 	struct ata_port *ap = dev->link->ap;
@@ -2329,6 +2356,10 @@ int ata_dev_configure(struct ata_device *dev)
 		return 0;
 	}
 
+	rc = ata_do_link_spd_horkage(dev);
+	if (rc)
+		return rc;
+
 	/* let ACPI work its magic */
 	rc = ata_acpi_on_devcfg(dev);
 	if (rc)
@@ -2784,7 +2815,7 @@ int ata_bus_probe(struct ata_port *ap)
 			/* This is the last chance, better to slow
 			 * down than lose it.
 			 */
-			sata_down_spd_limit(&ap->link);
+			sata_down_spd_limit(&ap->link, 0);
 			ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
 		}
 	}
@@ -2880,21 +2911,27 @@ void ata_port_disable(struct ata_port *ap)
 /**
  *	sata_down_spd_limit - adjust SATA spd limit downward
  *	@link: Link to adjust SATA spd limit for
+ *	@spd_limit: Additional limit
  *
  *	Adjust SATA spd limit of @link downward.  Note that this
  *	function only adjusts the limit.  The change must be applied
  *	using sata_set_spd().
  *
+ *	If @spd_limit is non-zero, the speed is limited to equal to or
+ *	lower than @spd_limit if such speed is supported.  If
+ *	@spd_limit is slower than any supported speed, only the lowest
+ *	supported speed is allowed.
+ *
  *	LOCKING:
  *	Inherited from caller.
  *
  *	RETURNS:
  *	0 on success, negative errno on failure
  */
-int sata_down_spd_limit(struct ata_link *link)
+int sata_down_spd_limit(struct ata_link *link, u32 spd_limit)
 {
 	u32 sstatus, spd, mask;
-	int rc, highbit;
+	int rc, bit;
 
 	if (!sata_scr_valid(link))
 		return -EOPNOTSUPP;
@@ -2903,7 +2940,7 @@ int sata_down_spd_limit(struct ata_link *link)
 	 * If not, use cached value in link->sata_spd.
 	 */
 	rc = sata_scr_read(link, SCR_STATUS, &sstatus);
-	if (rc == 0)
+	if (rc == 0 && ata_sstatus_online(sstatus))
 		spd = (sstatus >> 4) & 0xf;
 	else
 		spd = link->sata_spd;
@@ -2913,8 +2950,8 @@ int sata_down_spd_limit(struct ata_link *link)
 		return -EINVAL;
 
 	/* unconditionally mask off the highest bit */
-	highbit = fls(mask) - 1;
-	mask &= ~(1 << highbit);
+	bit = fls(mask) - 1;
+	mask &= ~(1 << bit);
 
 	/* Mask off all speeds higher than or equal to the current
 	 * one.  Force 1.5Gbps if current SPD is not available.
@@ -2928,6 +2965,15 @@ int sata_down_spd_limit(struct ata_link *link)
 	if (!mask)
 		return -EINVAL;
 
+	if (spd_limit) {
+		if (mask & ((1 << spd_limit) - 1))
+			mask &= (1 << spd_limit) - 1;
+		else {
+			bit = ffs(mask) - 1;
+			mask = 1 << bit;
+		}
+	}
+
 	link->sata_spd_limit = mask;
 
 	ata_link_printk(link, KERN_WARNING, "limiting SATA link speed to %s\n",
@@ -4215,6 +4261,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
 	/* Devices that do not need bridging limits applied */
 	{ "MTRON MSP-SATA*",		NULL,	ATA_HORKAGE_BRIDGE_OK, },
 
+	/* Devices which aren't very happy with higher link speeds */
+	{ "WD My Book",			NULL,	ATA_HORKAGE_1_5_GBPS, },
+
 	/* End Marker */
 	{ }
 };
@@ -4709,8 +4758,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
 
 /**
  *	ata_qc_new - Request an available ATA command, for queueing
- *	@ap: Port associated with device @dev
- *	@dev: Device from whom we request an available command structure
+ *	@ap: target port
  *
  *	LOCKING:
  *	None.
@@ -5175,7 +5223,7 @@ bool ata_phys_link_online(struct ata_link *link)
 	u32 sstatus;
 
 	if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
-	    (sstatus & 0xf) == 0x3)
+	    ata_sstatus_online(sstatus))
 		return true;
 	return false;
 }
@@ -5199,7 +5247,7 @@ bool ata_phys_link_offline(struct ata_link *link)
 	u32 sstatus;
 
 	if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
-	    (sstatus & 0xf) != 0x3)
+	    !ata_sstatus_online(sstatus))
 		return true;
 	return false;
 }
@@ -5412,8 +5460,8 @@ void ata_dev_init(struct ata_device *dev)
 	dev->horkage = 0;
 	spin_unlock_irqrestore(ap->lock, flags);
 
-	memset((void *)dev + ATA_DEVICE_CLEAR_OFFSET, 0,
-	       sizeof(*dev) - ATA_DEVICE_CLEAR_OFFSET);
+	memset((void *)dev + ATA_DEVICE_CLEAR_BEGIN, 0,
+	       ATA_DEVICE_CLEAR_END - ATA_DEVICE_CLEAR_BEGIN);
 	dev->pio_mask = UINT_MAX;
 	dev->mwdma_mask = UINT_MAX;
 	dev->udma_mask = UINT_MAX;
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 8147a8386370..ce2ef0475339 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -82,6 +82,10 @@ enum {
 	ATA_EH_FASTDRAIN_INTERVAL	=  3000,
 
 	ATA_EH_UA_TRIES			= 5,
+
+	/* probe speed down parameters, see ata_eh_schedule_probe() */
+	ATA_EH_PROBE_TRIAL_INTERVAL	= 60000,	/* 1 min */
+	ATA_EH_PROBE_TRIALS		= 2,
 };
 
 /* The following table determines how we sequence resets.  Each entry
@@ -1176,6 +1180,32 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc)
 }
 
 /**
+ *	ata_dev_disable - disable ATA device
+ *	@dev: ATA device to disable
+ *
+ *	Disable @dev.
+ *
+ *	Locking:
+ *	EH context.
+ */
+void ata_dev_disable(struct ata_device *dev)
+{
+	if (!ata_dev_enabled(dev))
+		return;
+
+	if (ata_msg_drv(dev->link->ap))
+		ata_dev_printk(dev, KERN_WARNING, "disabled\n");
+	ata_acpi_on_disable(dev);
+	ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET);
+	dev->class++;
+
+	/* From now till the next successful probe, ering is used to
+	 * track probe failures.  Clear accumulated device error info.
+	 */
+	ata_ering_clear(&dev->ering);
+}
+
+/**
  *	ata_eh_detach_dev - detach ATA device
  *	@dev: ATA device to detach
  *
@@ -1849,7 +1879,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev,
 	/* speed down? */
 	if (verdict & ATA_EH_SPDN_SPEED_DOWN) {
 		/* speed down SATA link speed if possible */
-		if (sata_down_spd_limit(link) == 0) {
+		if (sata_down_spd_limit(link, 0) == 0) {
 			action |= ATA_EH_RESET;
 			goto done;
 		}
@@ -2601,11 +2631,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
 	}
 
 	if (try == max_tries - 1) {
-		sata_down_spd_limit(link);
+		sata_down_spd_limit(link, 0);
 		if (slave)
-			sata_down_spd_limit(slave);
+			sata_down_spd_limit(slave, 0);
 	} else if (rc == -EPIPE)
-		sata_down_spd_limit(failed_link);
+		sata_down_spd_limit(failed_link, 0);
 
 	if (hardreset)
 		reset = hardreset;
@@ -2744,6 +2774,8 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
 						     readid_flags, dev->id);
 			switch (rc) {
 			case 0:
+				/* clear error info accumulated during probe */
+				ata_ering_clear(&dev->ering);
 				new_mask |= 1 << dev->devno;
 				break;
 			case -ENOENT:
@@ -2947,9 +2979,24 @@ static int ata_eh_skip_recovery(struct ata_link *link)
 	return 1;
 }
 
+static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg)
+{
+	u64 interval = msecs_to_jiffies(ATA_EH_PROBE_TRIAL_INTERVAL);
+	u64 now = get_jiffies_64();
+	int *trials = void_arg;
+
+	if (ent->timestamp < now - min(now, interval))
+		return -1;
+
+	(*trials)++;
+	return 0;
+}
+
 static int ata_eh_schedule_probe(struct ata_device *dev)
 {
 	struct ata_eh_context *ehc = &dev->link->eh_context;
+	struct ata_link *link = ata_dev_phys_link(dev);
+	int trials = 0;
 
 	if (!(ehc->i.probe_mask & (1 << dev->devno)) ||
 	    (ehc->did_probe_mask & (1 << dev->devno)))
@@ -2962,6 +3009,25 @@ static int ata_eh_schedule_probe(struct ata_device *dev)
 	ehc->saved_xfer_mode[dev->devno] = 0;
 	ehc->saved_ncq_enabled &= ~(1 << dev->devno);
 
+	/* Record and count probe trials on the ering.  The specific
+	 * error mask used is irrelevant.  Because a successful device
+	 * detection clears the ering, this count accumulates only if
+	 * there are consecutive failed probes.
+	 *
+	 * If the count is equal to or higher than ATA_EH_PROBE_TRIALS
+	 * in the last ATA_EH_PROBE_TRIAL_INTERVAL, link speed is
+	 * forced to 1.5Gbps.
+	 *
+	 * This is to work around cases where failed link speed
+	 * negotiation results in device misdetection leading to
+	 * infinite DEVXCHG or PHRDY CHG events.
+	 */
+	ata_ering_record(&dev->ering, 0, AC_ERR_OTHER);
+	ata_ering_map(&dev->ering, ata_count_probe_trials_cb, &trials);
+
+	if (trials > ATA_EH_PROBE_TRIALS)
+		sata_down_spd_limit(link, 1);
+
 	return 1;
 }
 
@@ -2969,7 +3035,11 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)
 {
 	struct ata_eh_context *ehc = &dev->link->eh_context;
 
-	ehc->tries[dev->devno]--;
+	/* -EAGAIN from EH routine indicates retry without prejudice.
+	 * The requester is responsible for ensuring forward progress.
+	 */
+	if (err != -EAGAIN)
+		ehc->tries[dev->devno]--;
 
 	switch (err) {
 	case -ENODEV:
@@ -2979,12 +3049,13 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)
 		/* give it just one more chance */
 		ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
 	case -EIO:
-		if (ehc->tries[dev->devno] == 1 && dev->pio_mode > XFER_PIO_0) {
+		if (ehc->tries[dev->devno] == 1) {
 			/* This is the last chance, better to slow
 			 * down than lose it.
 			 */
-			sata_down_spd_limit(ata_dev_phys_link(dev));
-			ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
+			sata_down_spd_limit(ata_dev_phys_link(dev), 0);
+			if (dev->pio_mode > XFER_PIO_0)
+				ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
 		}
 	}
 
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 98ca07a2db87..619f2c33950e 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -729,7 +729,7 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
 		if (tries) {
 			/* consecutive revalidation failures? speed down */
 			if (reval_failed)
-				sata_down_spd_limit(link);
+				sata_down_spd_limit(link, 0);
 			else
 				reval_failed = 1;
 
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 3c4c5ae277ba..b9747fa59e54 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -415,6 +415,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
 
 /**
  *	ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl
+ *	@ap: target port
  *	@sdev: SCSI device to get identify data for
  *	@arg: User buffer area for identify data
  *
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index fe2839e58774..cea8014cd87e 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -79,7 +79,6 @@ extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
 			   u64 block, u32 n_block, unsigned int tf_flags,
 			   unsigned int tag);
 extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev);
-extern void ata_dev_disable(struct ata_device *dev);
 extern void ata_pio_queue_task(struct ata_port *ap, void *data,
 			       unsigned long delay);
 extern void ata_port_flush_task(struct ata_port *ap);
@@ -100,7 +99,7 @@ extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags);
 extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
 			      unsigned int readid_flags);
 extern int ata_dev_configure(struct ata_device *dev);
-extern int sata_down_spd_limit(struct ata_link *link);
+extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit);
 extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel);
 extern void ata_sg_clean(struct ata_queued_cmd *qc);
 extern void ata_qc_free(struct ata_queued_cmd *qc);
@@ -160,6 +159,7 @@ extern void ata_scsi_error(struct Scsi_Host *host);
 extern void ata_port_wait_eh(struct ata_port *ap);
 extern void ata_eh_fastdrain_timerfn(unsigned long arg);
 extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
+extern void ata_dev_disable(struct ata_device *dev);
 extern void ata_eh_detach_dev(struct ata_device *dev);
 extern void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
 			       unsigned int action);
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index 3080f371222c..f1b26f7c8e4d 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -12,7 +12,7 @@
  *
  * Probe code based on drivers/ide/legacy/qd65xx.c
  * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
- * Samuel Thibault <samuel.thibault@fnac.net>
+ * Samuel Thibault <samuel.thibault@ens-lyon.org>
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index f2d8a020ea53..4ae1a4138b47 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -663,8 +663,8 @@ static const struct pci_device_id mv_pci_tbl[] = {
 	{ PCI_VDEVICE(MARVELL, 0x5081), chip_508x },
 	/* RocketRAID 1720/174x have different identifiers */
 	{ PCI_VDEVICE(TTI, 0x1720), chip_6042 },
-	{ PCI_VDEVICE(TTI, 0x1740), chip_508x },
-	{ PCI_VDEVICE(TTI, 0x1742), chip_508x },
+	{ PCI_VDEVICE(TTI, 0x1740), chip_6042 },
+	{ PCI_VDEVICE(TTI, 0x1742), chip_6042 },
 
 	{ PCI_VDEVICE(MARVELL, 0x6040), chip_604x },
 	{ PCI_VDEVICE(MARVELL, 0x6041), chip_604x },
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index c49ad0e61b6f..444af0415ca1 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -436,11 +436,16 @@ static struct ata_port_operations nv_nf2_ops = {
 	.hardreset		= nv_noclassify_hardreset,
 };
 
-/* CK804 finally gets hardreset right */
+/* For initial probing after boot and hot plugging, hardreset mostly
+ * works fine on CK804 but curiously, reprobing on the initial port by
+ * rescanning or rmmod/insmod fails to acquire the initial D2H Reg FIS
+ * in somewhat undeterministic way.  Use noclassify hardreset.
+ */
 static struct ata_port_operations nv_ck804_ops = {
 	.inherits		= &nv_common_ops,
 	.freeze			= nv_ck804_freeze,
 	.thaw			= nv_ck804_thaw,
+	.hardreset		= nv_noclassify_hardreset,
 	.host_stop		= nv_ck804_host_stop,
 };
 
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 9f029595f454..d0091609e210 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -324,7 +324,7 @@ static void sil_fill_sg(struct ata_queued_cmd *qc)
 
 		prd->addr = cpu_to_le32(addr);
 		prd->flags_len = cpu_to_le32(sg_len);
-		VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, sg_len);
+		VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", si, addr, sg_len);
 
 		last_prd = prd;
 		prd++;
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index f5be8081cd81..735bbe2be51a 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -761,7 +761,7 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
 	tristate "/dev/nvram support"
-	depends on ATARI || X86 || ARM || GENERIC_NVRAM
+	depends on ATARI || X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
 	---help---
 	  If you say Y here and create a character special file /dev/nvram
 	  with major number 10 and minor number 144 using mknod ("man mknod"),
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index f29fbe9b8ed7..cb8ca5698963 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -268,7 +268,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
 
 	/* Allocate a new buffer before freeing the old one ... */
 	multiplier = use_unicode ? 3 : 1;  /* chars can take up to 3 bytes */
-	bp = kmalloc((sel_end-sel_start)/2*multiplier+1, GFP_KERNEL);
+	bp = kmalloc(((sel_end-sel_start)/2+1)*multiplier, GFP_KERNEL);
 	if (!bp) {
 		printk(KERN_WARNING "selection: kmalloc() failed\n");
 		clear_selection();
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index b60be7b0decf..f146e90404fa 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -1713,8 +1713,8 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
 		for (i = 0; i < SX_NBOARDS; i++)
 			sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags);
 		sx_dprintk(SX_DEBUG_FIRMWARE, "\n");
-		unlock_kernel();
-		return -EIO;
+		rc = -EIO;
+		goto out;
 	}
 
 	switch (cmd) {
@@ -1747,7 +1747,8 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
 		break;
 	case SXIO_DO_RAMTEST:
 		if (sx_initialized)	/* Already initialized: better not ramtest the board.  */
-			return -EPERM;
+			rc = -EPERM;
+			break;
 		if (IS_SX_BOARD(board)) {
 			rc = do_memtest(board, 0, 0x7000);
 			if (!rc)
@@ -1844,6 +1845,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
 		rc = -ENOTTY;
 		break;
 	}
+out:
 	unlock_kernel();
 	func_exit();
 	return rc;
diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c
index 55433849bfa6..33bd75347518 100644
--- a/drivers/dca/dca-core.c
+++ b/drivers/dca/dca-core.c
@@ -28,7 +28,7 @@
 #include <linux/device.h>
 #include <linux/dca.h>
 
-#define DCA_VERSION "1.4"
+#define DCA_VERSION "1.8"
 
 MODULE_VERSION(DCA_VERSION);
 MODULE_LICENSE("GPL");
@@ -60,16 +60,17 @@ int dca_add_requester(struct device *dev)
 {
 	struct dca_provider *dca;
 	int err, slot = -ENODEV;
+	unsigned long flags;
 
 	if (!dev)
 		return -EFAULT;
 
-	spin_lock(&dca_lock);
+	spin_lock_irqsave(&dca_lock, flags);
 
 	/* check if the requester has not been added already */
 	dca = dca_find_provider_by_dev(dev);
 	if (dca) {
-		spin_unlock(&dca_lock);
+		spin_unlock_irqrestore(&dca_lock, flags);
 		return -EEXIST;
 	}
 
@@ -78,19 +79,21 @@ int dca_add_requester(struct device *dev)
 		if (slot >= 0)
 			break;
 	}
-	if (slot < 0) {
-		spin_unlock(&dca_lock);
+
+	spin_unlock_irqrestore(&dca_lock, flags);
+
+	if (slot < 0)
 		return slot;
-	}
 
 	err = dca_sysfs_add_req(dca, dev, slot);
 	if (err) {
-		dca->ops->remove_requester(dca, dev);
-		spin_unlock(&dca_lock);
+		spin_lock_irqsave(&dca_lock, flags);
+		if (dca == dca_find_provider_by_dev(dev))
+			dca->ops->remove_requester(dca, dev);
+		spin_unlock_irqrestore(&dca_lock, flags);
 		return err;
 	}
 
-	spin_unlock(&dca_lock);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(dca_add_requester);
@@ -103,25 +106,25 @@ int dca_remove_requester(struct device *dev)
 {
 	struct dca_provider *dca;
 	int slot;
+	unsigned long flags;
 
 	if (!dev)
 		return -EFAULT;
 
-	spin_lock(&dca_lock);
+	spin_lock_irqsave(&dca_lock, flags);
 	dca = dca_find_provider_by_dev(dev);
 	if (!dca) {
-		spin_unlock(&dca_lock);
+		spin_unlock_irqrestore(&dca_lock, flags);
 		return -ENODEV;
 	}
 	slot = dca->ops->remove_requester(dca, dev);
-	if (slot < 0) {
-		spin_unlock(&dca_lock);
+	spin_unlock_irqrestore(&dca_lock, flags);
+
+	if (slot < 0)
 		return slot;
-	}
 
 	dca_sysfs_remove_req(dca, slot);
 
-	spin_unlock(&dca_lock);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(dca_remove_requester);
@@ -135,17 +138,18 @@ u8 dca_common_get_tag(struct device *dev, int cpu)
 {
 	struct dca_provider *dca;
 	u8 tag;
+	unsigned long flags;
 
-	spin_lock(&dca_lock);
+	spin_lock_irqsave(&dca_lock, flags);
 
 	dca = dca_find_provider_by_dev(dev);
 	if (!dca) {
-		spin_unlock(&dca_lock);
+		spin_unlock_irqrestore(&dca_lock, flags);
 		return -ENODEV;
 	}
 	tag = dca->ops->get_tag(dca, dev, cpu);
 
-	spin_unlock(&dca_lock);
+	spin_unlock_irqrestore(&dca_lock, flags);
 	return tag;
 }
 
@@ -217,11 +221,16 @@ static BLOCKING_NOTIFIER_HEAD(dca_provider_chain);
 int register_dca_provider(struct dca_provider *dca, struct device *dev)
 {
 	int err;
+	unsigned long flags;
 
 	err = dca_sysfs_add_provider(dca, dev);
 	if (err)
 		return err;
+
+	spin_lock_irqsave(&dca_lock, flags);
 	list_add(&dca->node, &dca_providers);
+	spin_unlock_irqrestore(&dca_lock, flags);
+
 	blocking_notifier_call_chain(&dca_provider_chain,
 				     DCA_PROVIDER_ADD, NULL);
 	return 0;
@@ -234,9 +243,15 @@ EXPORT_SYMBOL_GPL(register_dca_provider);
  */
 void unregister_dca_provider(struct dca_provider *dca)
 {
+	unsigned long flags;
+
 	blocking_notifier_call_chain(&dca_provider_chain,
 				     DCA_PROVIDER_REMOVE, NULL);
+
+	spin_lock_irqsave(&dca_lock, flags);
 	list_del(&dca->node);
+	spin_unlock_irqrestore(&dca_lock, flags);
+
 	dca_sysfs_remove_provider(dca);
 }
 EXPORT_SYMBOL_GPL(unregister_dca_provider);
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index 7be2cf3514e7..a5dd7a665aa8 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -412,6 +412,7 @@ fw_card_add(struct fw_card *card,
 {
 	u32 *config_rom;
 	size_t length;
+	int err;
 
 	card->max_receive = max_receive;
 	card->link_speed = link_speed;
@@ -422,7 +423,13 @@ fw_card_add(struct fw_card *card,
 	list_add_tail(&card->link, &card_list);
 	mutex_unlock(&card_mutex);
 
-	return card->driver->enable(card, config_rom, length);
+	err = card->driver->enable(card, config_rom, length);
+	if (err < 0) {
+		mutex_lock(&card_mutex);
+		list_del(&card->link);
+		mutex_unlock(&card_mutex);
+	}
+	return err;
 }
 EXPORT_SYMBOL(fw_card_add);
 
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 9da581452874..6915fb82d0b0 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -136,7 +136,7 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)
 	obj = kcalloc(1, sizeof(*obj), GFP_KERNEL);
 
 	obj->dev = dev;
-	obj->filp = shmem_file_setup("drm mm object", size, 0);
+	obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
 	if (IS_ERR(obj->filp)) {
 		kfree(obj);
 		return NULL;
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index 03705240000f..abf4dfc8ec22 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -153,7 +153,10 @@ static struct axis_conversion lis3lv02d_axis_y_inverted = {1, -2, 3};
 static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3};
 static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3};
 static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3};
+static struct axis_conversion lis3lv02d_axis_xy_rotated_left_usd = {-2, 1, -3};
 static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3};
+static struct axis_conversion lis3lv02d_axis_xy_rotated_right = {2, -1, 3};
+static struct axis_conversion lis3lv02d_axis_xy_swap_yz_inverted = {2, -1, -3};
 
 #define AXIS_DMI_MATCH(_ident, _name, _axis) {		\
 	.ident = _ident,				\
@@ -172,10 +175,12 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
 	AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted),
 	AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted),
 	AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left),
+	AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd),
+	AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd),
+	AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right),
+	AXIS_DMI_MATCH("NC671xx", "HP Compaq 671", xy_swap_yz_inverted),
 	{ NULL, }
 /* Laptop models without axis info (yet):
- * "NC651xx" "HP Compaq 651"
- * "NC671xx" "HP Compaq 671"
  * "NC6910" "HP Compaq 6910"
  * HP Compaq 8710x Notebook PC / Mobile Workstation
  * "NC2400" "HP Compaq nc2400"
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index b1c6f68d98ce..3dad2299d9c5 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -465,6 +465,16 @@ config BLK_DEV_CS5535
 
 	  It is safe to say Y to this question.
 
+config BLK_DEV_CS5536
+	tristate "CS5536 chipset support"
+	depends on X86_32
+	select BLK_DEV_IDEDMA_PCI
+	help
+	  This option enables support for the AMD CS5536
+	  companion chip used with the Geode LX processor family.
+
+	  If unsure, say N.
+
 config BLK_DEV_HPT366
 	tristate "HPT36X/37X chipset support"
 	select BLK_DEV_IDEDMA_PCI
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index c2b9c93f0095..d0e3d7d5b467 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_BLK_DEV_CMD64X)		+= cmd64x.o
 obj-$(CONFIG_BLK_DEV_CS5520)		+= cs5520.o
 obj-$(CONFIG_BLK_DEV_CS5530)		+= cs5530.o
 obj-$(CONFIG_BLK_DEV_CS5535)		+= cs5535.o
+obj-$(CONFIG_BLK_DEV_CS5536)		+= cs5536.o
 obj-$(CONFIG_BLK_DEV_SC1200)		+= sc1200.o
 obj-$(CONFIG_BLK_DEV_CY82C693)		+= cy82c693.o
 obj-$(CONFIG_BLK_DEV_DELKIN)		+= delkin_cb.o
diff --git a/drivers/ide/cs5536.c b/drivers/ide/cs5536.c
new file mode 100644
index 000000000000..7a62db719a46
--- /dev/null
+++ b/drivers/ide/cs5536.c
@@ -0,0 +1,308 @@
+/*
+ * CS5536 PATA support
+ * (C) 2007 Martin K. Petersen <mkp@mkp.net>
+ * (C) 2009 Bartlomiej Zolnierkiewicz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Documentation:
+ *	Available from AMD web site.
+ *
+ * The IDE timing registers for the CS5536 live in the Geode Machine
+ * Specific Register file and not PCI config space.  Most BIOSes
+ * virtualize the PCI registers so the chip looks like a standard IDE
+ * controller.  Unfortunately not all implementations get this right.
+ * In particular some have problems with unaligned accesses to the
+ * virtualized PCI registers.  This driver always does full dword
+ * writes to work around the issue.  Also, in case of a bad BIOS this
+ * driver can be loaded with the "msr=1" parameter which forces using
+ * the Machine Specific Registers to configure the device.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+#include <asm/msr.h>
+
+#define DRV_NAME	"cs5536"
+
+enum {
+	MSR_IDE_CFG		= 0x51300010,
+	PCI_IDE_CFG		= 0x40,
+
+	CFG			= 0,
+	DTC			= 2,
+	CAST			= 3,
+	ETC			= 4,
+
+	IDE_CFG_CHANEN		= (1 << 1),
+	IDE_CFG_CABLE		= (1 << 17) | (1 << 16),
+
+	IDE_D0_SHIFT		= 24,
+	IDE_D1_SHIFT		= 16,
+	IDE_DRV_MASK		= 0xff,
+
+	IDE_CAST_D0_SHIFT	= 6,
+	IDE_CAST_D1_SHIFT	= 4,
+	IDE_CAST_DRV_MASK	= 0x3,
+
+	IDE_CAST_CMD_SHIFT	= 24,
+	IDE_CAST_CMD_MASK	= 0xff,
+
+	IDE_ETC_UDMA_MASK	= 0xc0,
+};
+
+static int use_msr;
+
+static int cs5536_read(struct pci_dev *pdev, int reg, u32 *val)
+{
+	if (unlikely(use_msr)) {
+		u32 dummy;
+
+		rdmsr(MSR_IDE_CFG + reg, *val, dummy);
+		return 0;
+	}
+
+	return pci_read_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
+}
+
+static int cs5536_write(struct pci_dev *pdev, int reg, int val)
+{
+	if (unlikely(use_msr)) {
+		wrmsr(MSR_IDE_CFG + reg, val, 0);
+		return 0;
+	}
+
+	return pci_write_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
+}
+
+static void cs5536_program_dtc(ide_drive_t *drive, u8 tim)
+{
+	struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
+	int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+	u32 dtc;
+
+	cs5536_read(pdev, DTC, &dtc);
+	dtc &= ~(IDE_DRV_MASK << dshift);
+	dtc |= tim << dshift;
+	cs5536_write(pdev, DTC, dtc);
+}
+
+/**
+ *	cs5536_cable_detect	-	detect cable type
+ *	@hwif: Port to detect on
+ *
+ *	Perform cable detection for ATA66 capable cable.
+ *
+ *	Returns a cable type.
+ */
+
+static u8 cs5536_cable_detect(ide_hwif_t *hwif)
+{
+	struct pci_dev *pdev = to_pci_dev(hwif->dev);
+	u32 cfg;
+
+	cs5536_read(pdev, CFG, &cfg);
+
+	if (cfg & IDE_CFG_CABLE)
+		return ATA_CBL_PATA80;
+	else
+		return ATA_CBL_PATA40;
+}
+
+/**
+ *	cs5536_set_pio_mode		-	PIO timing setup
+ *	@drive: ATA device
+ *	@pio: PIO mode number
+ */
+
+static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio)
+{
+	static const u8 drv_timings[5] = {
+		0x98, 0x55, 0x32, 0x21, 0x20,
+	};
+
+	static const u8 addr_timings[5] = {
+		0x2, 0x1, 0x0, 0x0, 0x0,
+	};
+
+	static const u8 cmd_timings[5] = {
+		0x99, 0x92, 0x90, 0x22, 0x20,
+	};
+
+	struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
+	ide_drive_t *pair = ide_get_pair_dev(drive);
+	int cshift = (drive->dn & 1) ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
+	u32 cast;
+	u8 cmd_pio = pio;
+
+	if (pair)
+		cmd_pio = min(pio, ide_get_best_pio_mode(pair, 255, 4));
+
+	drive->drive_data &= (IDE_DRV_MASK << 8);
+	drive->drive_data |= drv_timings[pio];
+
+	cs5536_program_dtc(drive, drv_timings[pio]);
+
+	cs5536_read(pdev, CAST, &cast);
+
+	cast &= ~(IDE_CAST_DRV_MASK << cshift);
+	cast |= addr_timings[pio] << cshift;
+
+	cast &= ~(IDE_CAST_CMD_MASK << IDE_CAST_CMD_SHIFT);
+	cast |= cmd_timings[cmd_pio] << IDE_CAST_CMD_SHIFT;
+
+	cs5536_write(pdev, CAST, cast);
+}
+
+/**
+ *	cs5536_set_dma_mode		-	DMA timing setup
+ *	@drive: ATA device
+ *	@mode: DMA mode
+ */
+
+static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)
+{
+	static const u8 udma_timings[6] = {
+		0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6,
+	};
+
+	static const u8 mwdma_timings[3] = {
+		0x67, 0x21, 0x20,
+	};
+
+	struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
+	int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+	u32 etc;
+
+	cs5536_read(pdev, ETC, &etc);
+
+	if (mode >= XFER_UDMA_0) {
+		etc &= ~(IDE_DRV_MASK << dshift);
+		etc |= udma_timings[mode - XFER_UDMA_0] << dshift;
+	} else { /* MWDMA */
+		etc &= ~(IDE_ETC_UDMA_MASK << dshift);
+		drive->drive_data &= IDE_DRV_MASK;
+		drive->drive_data |= mwdma_timings[mode - XFER_MW_DMA_0] << 8;
+	}
+
+	cs5536_write(pdev, ETC, etc);
+}
+
+static void cs5536_dma_start(ide_drive_t *drive)
+{
+	if (drive->current_speed < XFER_UDMA_0 &&
+	    (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK))
+		cs5536_program_dtc(drive, drive->drive_data >> 8);
+
+	ide_dma_start(drive);
+}
+
+static int cs5536_dma_end(ide_drive_t *drive)
+{
+	int ret = ide_dma_end(drive);
+
+	if (drive->current_speed < XFER_UDMA_0 &&
+	    (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK))
+		cs5536_program_dtc(drive, drive->drive_data & IDE_DRV_MASK);
+
+	return ret;
+}
+
+static const struct ide_port_ops cs5536_port_ops = {
+	.set_pio_mode		= cs5536_set_pio_mode,
+	.set_dma_mode		= cs5536_set_dma_mode,
+	.cable_detect		= cs5536_cable_detect,
+};
+
+static const struct ide_dma_ops cs5536_dma_ops = {
+	.dma_host_set		= ide_dma_host_set,
+	.dma_setup		= ide_dma_setup,
+	.dma_exec_cmd		= ide_dma_exec_cmd,
+	.dma_start		= cs5536_dma_start,
+	.dma_end		= cs5536_dma_end,
+	.dma_test_irq		= ide_dma_test_irq,
+	.dma_lost_irq		= ide_dma_lost_irq,
+	.dma_timeout		= ide_dma_timeout,
+};
+
+static const struct ide_port_info cs5536_info = {
+	.name		= DRV_NAME,
+	.port_ops	= &cs5536_port_ops,
+	.dma_ops	= &cs5536_dma_ops,
+	.host_flags	= IDE_HFLAG_SINGLE,
+	.pio_mask	= ATA_PIO4,
+	.mwdma_mask	= ATA_MWDMA2,
+	.udma_mask	= ATA_UDMA5,
+};
+
+/**
+ *	cs5536_init_one
+ *	@dev: PCI device
+ *	@id: Entry in match table
+ */
+
+static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	u32 cfg;
+
+	if (use_msr)
+		printk(KERN_INFO DRV_NAME ": Using MSR regs instead of PCI\n");
+
+	cs5536_read(dev, CFG, &cfg);
+
+	if ((cfg & IDE_CFG_CHANEN) == 0) {
+		printk(KERN_ERR DRV_NAME ": disabled by BIOS\n");
+		return -ENODEV;
+	}
+
+	return ide_pci_init_one(dev, &cs5536_info, NULL);
+}
+
+static const struct pci_device_id cs5536_pci_tbl[] = {
+	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), },
+	{ },
+};
+
+static struct pci_driver cs5536_pci_driver = {
+	.name		= DRV_NAME,
+	.id_table	= cs5536_pci_tbl,
+	.probe		= cs5536_init_one,
+	.remove		= ide_pci_remove,
+	.suspend	= ide_pci_suspend,
+	.resume		= ide_pci_resume,
+};
+
+static int __init cs5536_init(void)
+{
+	return pci_register_driver(&cs5536_pci_driver);
+}
+
+static void __exit cs5536_exit(void)
+{
+	pci_unregister_driver(&cs5536_pci_driver);
+}
+
+MODULE_AUTHOR("Martin K. Petersen, Bartlomiej Zolnierkiewicz");
+MODULE_DESCRIPTION("low-level driver for the CS5536 IDE controller");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, cs5536_pci_tbl);
+
+module_param_named(msr, use_msr, int, 0644);
+MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)");
+
+module_init(cs5536_init);
+module_exit(cs5536_exit);
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index 97a35c667aee..415d7e24f2b6 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -534,7 +534,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
 		d.dma_ops = NULL;
 	}
 
-	ret = ide_host_register(host, NULL, hws);
+	ret = ide_host_register(host, &d, hws);
 	if (ret)
 		goto err_free;
 
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index d8f295bdad76..ec7d07fa570a 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -282,7 +282,7 @@ static int do_drive_get_GTF(ide_drive_t *drive,
 	port = hwif->channel ? drive->dn - 2: drive->dn;
 
 	DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n",
-		 hwif->name, dev->bus_id, port, hwif->channel);
+		 hwif->name, dev_name(dev), port, hwif->channel);
 
 	if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) {
 		DEBPRINT("%s drive %d:%d not present\n",
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index cae69372cf45..0bfeb0c79d6e 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -787,6 +787,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 		if (blk_fs_request(rq)) {
 			ide_end_request(drive, 1, rq->nr_sectors);
 			return ide_stopped;
+		} else if (rq->cmd_type == REQ_TYPE_ATA_PC && !rq->bio) {
+			ide_end_request(drive, 1, 1);
+			return ide_stopped;
 		}
 		goto end_request;
 	}
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index cc163319dfbd..9ee51adf567f 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -418,11 +418,14 @@ void ide_map_sg(ide_drive_t *drive, struct request *rq)
 	ide_hwif_t *hwif = drive->hwif;
 	struct scatterlist *sg = hwif->sg_table;
 
-	if (rq->cmd_type != REQ_TYPE_ATA_TASKFILE) {
-		hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
-	} else {
+	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
 		sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
 		hwif->sg_nents = 1;
+	} else if (!rq->bio) {
+		sg_init_one(sg, rq->data, rq->data_len);
+		hwif->sg_nents = 1;
+	} else {
+		hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
 	}
 }
 
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 0db1ed9f5fc2..ce0818a993f6 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1467,6 +1467,30 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
 }
 EXPORT_SYMBOL_GPL(ide_host_alloc);
 
+static void ide_port_free(ide_hwif_t *hwif)
+{
+	ide_port_free_devices(hwif);
+	ide_free_port_slot(hwif->index);
+	kfree(hwif);
+}
+
+static void ide_disable_port(ide_hwif_t *hwif)
+{
+	struct ide_host *host = hwif->host;
+	int i;
+
+	printk(KERN_INFO "%s: disabling port\n", hwif->name);
+
+	for (i = 0; i < MAX_HOST_PORTS; i++) {
+		if (host->ports[i] == hwif) {
+			host->ports[i] = NULL;
+			host->n_ports--;
+		}
+	}
+
+	ide_port_free(hwif);
+}
+
 int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
 		      hw_regs_t **hws)
 {
@@ -1507,8 +1531,12 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
 			hwif->present = 1;
 
 		if (hwif->chipset != ide_4drives || !hwif->mate ||
-		    !hwif->mate->present)
-			ide_register_port(hwif);
+		    !hwif->mate->present) {
+			if (ide_register_port(hwif)) {
+				ide_disable_port(hwif);
+				continue;
+			}
+		}
 
 		if (hwif->present)
 			ide_port_tune_devices(hwif);
@@ -1521,7 +1549,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
 		if (hwif_init(hwif) == 0) {
 			printk(KERN_INFO "%s: failed to initialize IDE "
 					 "interface\n", hwif->name);
-			hwif->present = 0;
+			device_unregister(&hwif->gendev);
+			ide_disable_port(hwif);
 			continue;
 		}
 
@@ -1660,12 +1689,8 @@ void ide_host_free(struct ide_host *host)
 	int i;
 
 	ide_host_for_each_port(i, hwif, host) {
-		if (hwif == NULL)
-			continue;
-
-		ide_port_free_devices(hwif);
-		ide_free_port_slot(hwif->index);
-		kfree(hwif);
+		if (hwif)
+			ide_port_free(hwif);
 	}
 
 	kfree(host);
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c
index 5b2e3af43c4b..08c4fa35e9b1 100644
--- a/drivers/ide/qd65xx.c
+++ b/drivers/ide/qd65xx.c
@@ -16,7 +16,7 @@
 
 /*
  * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
- * Samuel Thibault <samuel.thibault@fnac.net>
+ * Samuel Thibault <samuel.thibault@ens-lyon.org>
  */
 
 #include <linux/module.h>
diff --git a/drivers/ide/qd65xx.h b/drivers/ide/qd65xx.h
index 6636f9665d16..d7e67a1a1dcc 100644
--- a/drivers/ide/qd65xx.h
+++ b/drivers/ide/qd65xx.h
@@ -4,7 +4,7 @@
 
 /*
  * Authors:	Petr Soucek <petr@ryston.cz>
- * 		Samuel Thibault <samuel.thibault@fnac.net>
+ * 		Samuel Thibault <samuel.thibault@ens-lyon.org>
  */
 
 /* truncates a in [b,c] */
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index 882f6f07c476..40b0812a045c 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -261,9 +261,9 @@ static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq)
 				bcount = cur_len;
 			/*
 			 * This workaround for zero count seems required.
-			 * (standard ide_build_dmatable do it too)
+			 * (standard ide_build_dmatable does it too)
 			 */
-			if ((bcount & 0xffff) == 0x0000)
+			if (bcount == 0x10000)
 				bcount = 0x8000;
 			*table++ = bcount & 0xffff;
 			*table++ = cur_addr;
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index 703c3eeb20a8..6092fe3f409d 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -448,6 +448,11 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
 		d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS;
 #endif
 
+#ifdef CONFIG_AMIGAONE
+	if (machine_is(amigaone))
+		d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS;
+#endif
+
 	d.udma_mask = via_config->udma_mask;
 
 	vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index a329e6bd5d2d..3838bc4acaba 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -1823,6 +1823,10 @@ static int dv1394_open(struct inode *inode, struct file *file)
 
 #endif
 
+	printk(KERN_INFO "%s: NOTE, the dv1394 interface is unsupported "
+	       "and will not be available in the new firewire driver stack. "
+	       "Try libraw1394 based programs instead.\n", current->comm);
+
 	return 0;
 }
 
@@ -2567,10 +2571,6 @@ static int __init dv1394_init_module(void)
 {
 	int ret;
 
-	printk(KERN_WARNING
-	       "NOTE: The dv1394 driver is unsupported and may be removed in a "
-	       "future Linux release. Use raw1394 instead.\n");
-
 	cdev_init(&dv1394_cdev, &dv1394_fops);
 	dv1394_cdev.owner = THIS_MODULE;
 	ret = cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 1e3aea9eecf1..09658b218474 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -25,13 +25,13 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
 {
 	dev_info_t *hash;
 	linear_conf_t *conf = mddev_to_conf(mddev);
+	sector_t idx = sector >> conf->sector_shift;
 
 	/*
 	 * sector_div(a,b) returns the remainer and sets a to a/b
 	 */
-	sector >>= conf->sector_shift;
-	(void)sector_div(sector, conf->spacing);
-	hash = conf->hash_table[sector];
+	(void)sector_div(idx, conf->spacing);
+	hash = conf->hash_table[idx];
 
 	while (sector >= hash->num_sectors + hash->start_sector)
 		hash++;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 41e2509bf896..4495104f6c9f 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1481,6 +1481,11 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
 		if (find_rdev_nr(mddev, rdev->desc_nr))
 			return -EBUSY;
 	}
+	if (mddev->max_disks && rdev->desc_nr >= mddev->max_disks) {
+		printk(KERN_WARNING "md: %s: array is limited to %d devices\n",
+		       mdname(mddev), mddev->max_disks);
+		return -EBUSY;
+	}
 	bdevname(rdev->bdev,b);
 	while ( (s=strchr(b, '/')) != NULL)
 		*s = '!';
@@ -2441,6 +2446,15 @@ static void analyze_sbs(mddev_t * mddev)
 
 	i = 0;
 	rdev_for_each(rdev, tmp, mddev) {
+		if (rdev->desc_nr >= mddev->max_disks ||
+		    i > mddev->max_disks) {
+			printk(KERN_WARNING
+			       "md: %s: %s: only %d devices permitted\n",
+			       mdname(mddev), bdevname(rdev->bdev, b),
+			       mddev->max_disks);
+			kick_rdev_from_array(rdev);
+			continue;
+		}
 		if (rdev != freshest)
 			if (super_types[mddev->major_version].
 			    validate_super(mddev, rdev)) {
@@ -4614,13 +4628,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
 	 * noticed in interrupt contexts ...
 	 */
 
-	if (rdev->desc_nr == mddev->max_disks) {
-		printk(KERN_WARNING "%s: can not hot-add to full array!\n",
-			mdname(mddev));
-		err = -EBUSY;
-		goto abort_unbind_export;
-	}
-
 	rdev->raid_disk = -1;
 
 	md_update_sb(mddev, 1);
@@ -4634,9 +4641,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
 	md_new_event(mddev);
 	return 0;
 
-abort_unbind_export:
-	unbind_rdev_from_array(rdev);
-
 abort_export:
 	export_rdev(rdev);
 	return err;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 7b4f5f7155d8..01e3cffd03b8 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1640,7 +1640,8 @@ static void raid1d(mddev_t *mddev)
 			}
 
 			bio = r1_bio->bios[r1_bio->read_disk];
-			if ((disk=read_balance(conf, r1_bio)) == -1) {
+			if ((disk=read_balance(conf, r1_bio)) == -1 ||
+			    disk == r1_bio->read_disk) {
 				printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
 				       " read error for block %llu\n",
 				       bdevname(bio->bi_bdev,b),
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 6098b626811f..47fee05eaefb 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -576,6 +576,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
 		vv->vflip = c->value;
 		break;
 	default: {
+		mutex_unlock(&dev->lock);
 		return -EINVAL;
 	}
 	}
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
index 64379f2bf237..3ec28945c26f 100644
--- a/drivers/media/common/tuners/mxl5007t.c
+++ b/drivers/media/common/tuners/mxl5007t.c
@@ -657,7 +657,7 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
 {
 	struct mxl5007t_state *state = fe->tuner_priv;
 	int rf_locked, ref_locked;
-	s32 rf_input_level;
+	s32 rf_input_level = 0;
 	int ret;
 
 	if (fe->ops.i2c_gate_ctrl)
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 98ee16773ff2..7e3aeaa7370f 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -93,6 +93,9 @@ struct dvb_ca_slot {
 	/* current state of the CAM */
 	int slot_state;
 
+	/* mutex used for serializing access to one CI slot */
+	struct mutex slot_lock;
+
 	/* Number of CAMCHANGES that have occurred since last processing */
 	atomic_t camchange_count;
 
@@ -711,14 +714,20 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
 	dprintk("%s\n", __func__);
 
 
-	// sanity check
+	/* sanity check */
 	if (bytes_write > ca->slot_info[slot].link_buf_size)
 		return -EINVAL;
 
-	/* check if interface is actually waiting for us to read from it, or if a read is in progress */
+	/* it is possible we are dealing with a single buffer implementation,
+	   thus if there is data available for read or if there is even a read
+	   already in progress, we do nothing but awake the kernel thread to
+	   process the data if necessary. */
 	if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
 		goto exitnowrite;
 	if (status & (STATUSREG_DA | STATUSREG_RE)) {
+		if (status & STATUSREG_DA)
+			dvb_ca_en50221_thread_wakeup(ca);
+
 		status = -EAGAIN;
 		goto exitnowrite;
 	}
@@ -987,6 +996,8 @@ static int dvb_ca_en50221_thread(void *data)
 		/* go through all the slots processing them */
 		for (slot = 0; slot < ca->slot_count; slot++) {
 
+			mutex_lock(&ca->slot_info[slot].slot_lock);
+
 			// check the cam status + deal with CAMCHANGEs
 			while (dvb_ca_en50221_check_camstatus(ca, slot)) {
 				/* clear down an old CI slot if necessary */
@@ -1122,7 +1133,7 @@ static int dvb_ca_en50221_thread(void *data)
 
 			case DVB_CA_SLOTSTATE_RUNNING:
 				if (!ca->open)
-					continue;
+					break;
 
 				// poll slots for data
 				pktcount = 0;
@@ -1146,6 +1157,8 @@ static int dvb_ca_en50221_thread(void *data)
 				}
 				break;
 			}
+
+			mutex_unlock(&ca->slot_info[slot].slot_lock);
 		}
 	}
 
@@ -1181,6 +1194,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
 	switch (cmd) {
 	case CA_RESET:
 		for (slot = 0; slot < ca->slot_count; slot++) {
+			mutex_lock(&ca->slot_info[slot].slot_lock);
 			if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) {
 				dvb_ca_en50221_slot_shutdown(ca, slot);
 				if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
@@ -1188,6 +1202,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
 								     slot,
 								     DVB_CA_EN50221_CAMCHANGE_INSERTED);
 			}
+			mutex_unlock(&ca->slot_info[slot].slot_lock);
 		}
 		ca->next_read_slot = 0;
 		dvb_ca_en50221_thread_wakeup(ca);
@@ -1308,7 +1323,9 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
 				goto exit;
 			}
 
+			mutex_lock(&ca->slot_info[slot].slot_lock);
 			status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2);
+			mutex_unlock(&ca->slot_info[slot].slot_lock);
 			if (status == (fraglen + 2)) {
 				written = 1;
 				break;
@@ -1664,6 +1681,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
 		ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE;
 		atomic_set(&ca->slot_info[i].camchange_count, 0);
 		ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
+		mutex_init(&ca->slot_info[i].slot_lock);
 	}
 
 	if (signal_pending(current)) {
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
index 8467e63ddc0d..7df2e141187a 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
@@ -45,8 +45,10 @@ struct dvb_ca_en50221 {
 	/* the module owning this structure */
 	struct module* owner;
 
-	/* NOTE: the read_*, write_* and poll_slot_status functions must use locks as
-	 * they may be called from several threads at once */
+	/* NOTE: the read_*, write_* and poll_slot_status functions will be
+	 * called for different slots concurrently and need to use locks where
+	 * and if appropriate. There will be no concurrent access to one slot.
+	 */
 
 	/* functions for accessing attribute memory on the CAM */
 	int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address);
diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c
index b1a9c4cdec93..199ece0d4883 100644
--- a/drivers/media/dvb/dvb-usb/af9005-fe.c
+++ b/drivers/media/dvb/dvb-usb/af9005-fe.c
@@ -220,7 +220,7 @@ static int af9005_get_post_vit_ber(struct dvb_frontend *fe,
 				   u16 * abort_count)
 {
 	u32 loc_cw_count = 0, loc_err_count;
-	u16 loc_abort_count;
+	u16 loc_abort_count = 0;
 	int ret;
 
 	ret =
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index e1e9aa5c6b84..6a97a40d3dfb 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -694,7 +694,12 @@ static int af9015_read_config(struct usb_device *udev)
 
 	/* IR remote controller */
 	req.addr = AF9015_EEPROM_IR_MODE;
-	ret = af9015_rw_udev(udev, &req);
+	/* first message will timeout often due to possible hw bug */
+	for (i = 0; i < 4; i++) {
+		ret = af9015_rw_udev(udev, &req);
+		if (!ret)
+			break;
+	}
 	if (ret)
 		goto error;
 	deb_info("%s: IR mode:%d\n", __func__, val);
@@ -835,18 +840,19 @@ static int af9015_read_config(struct usb_device *udev)
 	if (!dvb_usb_af9015_dual_mode)
 		af9015_config.dual_mode = 0;
 
-	/* set buffer size according to USB port speed */
+	/* Set adapter0 buffer size according to USB port speed, adapter1 buffer
+	   size can be static because it is enabled only USB2.0 */
 	for (i = 0; i < af9015_properties_count; i++) {
 		/* USB1.1 set smaller buffersize and disable 2nd adapter */
 		if (udev->speed == USB_SPEED_FULL) {
-			af9015_properties[i].adapter->stream.u.bulk.buffersize =
-				TS_USB11_MAX_PACKET_SIZE;
+			af9015_properties[i].adapter[0].stream.u.bulk.buffersize
+				= TS_USB11_MAX_PACKET_SIZE;
 			/* disable 2nd adapter because we don't have
 			   PID-filters */
 			af9015_config.dual_mode = 0;
 		} else {
-			af9015_properties[i].adapter->stream.u.bulk.buffersize =
-				TS_USB20_MAX_PACKET_SIZE;
+			af9015_properties[i].adapter[0].stream.u.bulk.buffersize
+				= TS_USB20_MAX_PACKET_SIZE;
 		}
 	}
 
@@ -1254,6 +1260,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
 					.type = USB_BULK,
 					.count = 6,
 					.endpoint = 0x85,
+					.u = {
+						.bulk = {
+							.buffersize =
+						TS_USB20_MAX_PACKET_SIZE,
+						}
+					}
 				},
 			}
 		},
@@ -1353,6 +1365,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
 					.type = USB_BULK,
 					.count = 6,
 					.endpoint = 0x85,
+					.u = {
+						.bulk = {
+							.buffersize =
+						TS_USB20_MAX_PACKET_SIZE,
+						}
+					}
 				},
 			}
 		},
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 391732788911..635d30a55078 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -1393,6 +1393,9 @@ struct usb_device_id dib0700_usb_id_table[] = {
 	{ USB_DEVICE(USB_VID_ASUS,	USB_PID_ASUS_U3000H) },
 /* 40 */{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E) },
 	{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E_SE) },
+	{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
+	{ USB_DEVICE(USB_VID_TERRATEC,
+			USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
 	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1537,7 +1540,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			{   "DiBcom STK7700D reference design",
 				{ &dib0700_usb_id_table[14], NULL },
 				{ NULL },
-			}
+			},
+
 		},
 
 		.rc_interval      = DEFAULT_RC_INTERVAL,
@@ -1557,7 +1561,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			},
 		},
 
-		.num_device_descs = 2,
+		.num_device_descs = 3,
 		.devices = {
 			{   "ASUS My Cinema U3000 Mini DVBT Tuner",
 				{ &dib0700_usb_id_table[23], NULL },
@@ -1566,6 +1570,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			{   "Yuan EC372S",
 				{ &dib0700_usb_id_table[31], NULL },
 				{ NULL },
+			},
+			{   "Terratec Cinergy T Express",
+				{ &dib0700_usb_id_table[42], NULL },
+				{ NULL },
 			}
 		},
 
@@ -1653,7 +1661,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			}
 		},
 
-		.num_device_descs = 4,
+		.num_device_descs = 5,
 		.devices = {
 			{   "DiBcom STK7070PD reference design",
 				{ &dib0700_usb_id_table[17], NULL },
@@ -1670,6 +1678,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			{   "Hauppauge Nova-TD-500 (84xxx)",
 				{ &dib0700_usb_id_table[36], NULL },
 				{ NULL },
+			},
+			{  "Terratec Cinergy DT USB XS Diversity",
+				{ &dib0700_usb_id_table[43], NULL },
+				{ NULL },
 			}
 		}
 	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index a4fca3fca5ee..0db0c06ee6f2 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -162,8 +162,10 @@
 #define USB_PID_AVERMEDIA_A309				0xa309
 #define USB_PID_TECHNOTREND_CONNECT_S2400               0x3006
 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY	0x005a
+#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2	0x0081
 #define USB_PID_TERRATEC_CINERGY_HT_USB_XE		0x0058
 #define USB_PID_TERRATEC_CINERGY_HT_EXPRESS		0x0060
+#define USB_PID_TERRATEC_CINERGY_T_EXPRESS		0x0062
 #define USB_PID_TERRATEC_CINERGY_T_XXS			0x0078
 #define USB_PID_PINNACLE_EXPRESSCARD_320CX		0x022e
 #define USB_PID_PINNACLE_PCTV2000E			0x022c
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index ec4e08dbc699..1e81e713df63 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -646,7 +646,7 @@ static int drx_tune(struct drx397xD_state *s,
 	u32 edi = 0, ebx = 0, ebp = 0, edx = 0;
 	u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0;
 
-	int rc, df_tuner;
+	int rc, df_tuner = 0;
 	int a, b, c, d;
 	pr_debug("%s %d\n", __func__, s->config.d60);
 
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
index cf4d8936bb83..3e08d985d6e5 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -545,9 +545,6 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe,
 
 	s5h1409_enable_modulation(fe, p->u.vsb.modulation);
 
-	/* Allow the demod to settle */
-	msleep(100);
-
 	if (fe->ops.tuner_ops.set_params) {
 		if (fe->ops.i2c_gate_ctrl)
 			fe->ops.i2c_gate_ctrl(fe, 1);
@@ -562,6 +559,10 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe,
 		s5h1409_set_qam_interleave_mode(fe);
 	}
 
+	/* Issue a reset to the demod so it knows to resync against the
+	   newly tuned frequency */
+	s5h1409_softreset(fe);
+
 	return 0;
 }
 
diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c
index 83dc7e12d5f0..a67d1775a43c 100644
--- a/drivers/media/dvb/frontends/stb0899_algo.c
+++ b/drivers/media/dvb/frontends/stb0899_algo.c
@@ -31,6 +31,8 @@ inline u32 stb0899_do_div(u64 n, u32 d)
 	return n;
 }
 
+#if 0
+/* These functions are currently unused */
 /*
  * stb0899_calc_srate
  * Compute symbol rate
@@ -63,6 +65,7 @@ static u32 stb0899_get_srate(struct stb0899_state *state)
 
 	return stb0899_calc_srate(internal->master_clk, sfr);
 }
+#endif
 
 /*
  * stb0899_set_srate
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 1638e1d9f538..83e9e7750c8c 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -470,6 +470,7 @@ static void frontend_init(struct budget *budget)
 		budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config, &budget->i2c_adap);
 		if (budget->dvb_frontend) {
 			budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
+			budget->dvb_frontend->tuner_priv = NULL;
 			break;
 		}
 		break;
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 0aa96df80fc2..d91e0638448f 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1384,7 +1384,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
 static int ttusb_dec_init_stb(struct ttusb_dec *dec)
 {
 	int result;
-	unsigned int mode, model, version;
+	unsigned int mode = 0, model = 0, version = 0;
 
 	dprintk("%s\n", __func__);
 
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index 0747dc8862b0..fdfc7bf86b9e 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -194,10 +194,10 @@ static int amradio_start(struct amradio_device *radio)
 		return retval;
 	}
 
-	mutex_unlock(&radio->lock);
-
 	radio->muted = 0;
 
+	mutex_unlock(&radio->lock);
+
 	return retval;
 }
 
@@ -230,10 +230,10 @@ static int amradio_stop(struct amradio_device *radio)
 		return retval;
 	}
 
-	mutex_unlock(&radio->lock);
-
 	radio->muted = 1;
 
+	mutex_unlock(&radio->lock);
+
 	return retval;
 }
 
@@ -284,10 +284,10 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
 		return retval;
 	}
 
-	mutex_unlock(&radio->lock);
-
 	radio->stereo = 0;
 
+	mutex_unlock(&radio->lock);
+
 	return retval;
 }
 
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 14bebf8a116f..87e91072627a 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -18,7 +18,6 @@
  */
 
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/i2c.h>
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 8f1db57bd1dd..bfe25841dbf4 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -1586,7 +1586,8 @@ static int mpeg_open(struct file *file)
 	lock_kernel();
 	list_for_each(list, &cx23885_devlist) {
 		h = list_entry(list, struct cx23885_dev, devlist);
-		if (h->v4l_device->minor == minor) {
+		if (h->v4l_device &&
+		    h->v4l_device->minor == minor) {
 			dev = h;
 			break;
 		}
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 2d81c4d04340..eaa11893bfe9 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -730,12 +730,13 @@ static int video_open(struct file *file)
 	lock_kernel();
 	list_for_each(list, &cx23885_devlist) {
 		h = list_entry(list, struct cx23885_dev, devlist);
-		if (h->video_dev->minor == minor) {
+		if (h->video_dev &&
+		    h->video_dev->minor == minor) {
 			dev  = h;
 			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 		}
 		if (h->vbi_dev &&
-		   h->vbi_dev->minor == minor) {
+		    h->vbi_dev->minor == minor) {
 			dev  = h;
 			type = V4L2_BUF_TYPE_VBI_CAPTURE;
 		}
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 88f2fd32bfe3..25eb3bec9e5d 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -1382,6 +1382,14 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
 
 static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg)
 {
+	/* ignore this command */
+	if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG)
+		return 0;
+
+	/* Old-style drivers rely on initialization on first use, so
+	   call the init whenever a command is issued to this driver.
+	   New-style drivers using v4l2_subdev should call init explicitly. */
+	cx25840_init(i2c_get_clientdata(client), 0);
 	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
 }
 
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 613dfea4ff3e..aef5297534af 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -614,34 +614,41 @@ static struct stv0288_config tevii_tuner_earda_config = {
 	.set_ts_params = cx24116_set_ts_param,
 };
 
-static int dvb_register(struct cx8802_dev *dev)
+static int cx8802_alloc_frontends(struct cx8802_dev *dev)
 {
 	struct cx88_core *core = dev->core;
-	struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
-	int mfe_shared = 0; /* bus not shared by default */
+	struct videobuf_dvb_frontend *fe = NULL;
 	int i;
 
-	if (0 != core->i2c_rc) {
-		printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
-		goto frontend_detach;
-	}
-
-	if (!core->board.num_frontends)
-		return -EINVAL;
-
 	mutex_init(&dev->frontends.lock);
 	INIT_LIST_HEAD(&dev->frontends.felist);
 
+	if (!core->board.num_frontends)
+		return -ENODEV;
+
 	printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
 			 core->board.num_frontends);
 	for (i = 1; i <= core->board.num_frontends; i++) {
-		fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, i);
-		if (!fe0) {
+		fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
+		if (!fe) {
 			printk(KERN_ERR "%s() failed to alloc\n", __func__);
 			videobuf_dvb_dealloc_frontends(&dev->frontends);
-			goto frontend_detach;
+			return -ENOMEM;
 		}
 	}
+	return 0;
+}
+
+static int dvb_register(struct cx8802_dev *dev)
+{
+	struct cx88_core *core = dev->core;
+	struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
+	int mfe_shared = 0; /* bus not shared by default */
+
+	if (0 != core->i2c_rc) {
+		printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
+		goto frontend_detach;
+	}
 
 	/* Get the first frontend */
 	fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
@@ -1243,6 +1250,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
 	struct cx88_core *core = drv->core;
 	struct cx8802_dev *dev = drv->core->dvbdev;
 	int err;
+	struct videobuf_dvb_frontend *fe;
+	int i;
 
 	dprintk( 1, "%s\n", __func__);
 	dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
@@ -1258,39 +1267,34 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
 	/* If vp3054 isn't enabled, a stub will just return 0 */
 	err = vp3054_i2c_probe(dev);
 	if (0 != err)
-		goto fail_probe;
+		goto fail_core;
 
 	/* dvb stuff */
 	printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
 	dev->ts_gen_cntrl = 0x0c;
 
+	err = cx8802_alloc_frontends(dev);
+	if (err)
+		goto fail_core;
+
 	err = -ENODEV;
-	if (core->board.num_frontends) {
-		struct videobuf_dvb_frontend *fe;
-		int i;
-
-		for (i = 1; i <= core->board.num_frontends; i++) {
-			fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
-			if (fe == NULL) {
-				printk(KERN_ERR "%s() failed to get frontend(%d)\n",
+	for (i = 1; i <= core->board.num_frontends; i++) {
+		fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
+		if (fe == NULL) {
+			printk(KERN_ERR "%s() failed to get frontend(%d)\n",
 					__func__, i);
-				goto fail_probe;
-			}
-			videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
+			goto fail_probe;
+		}
+		videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
 				    &dev->pci->dev, &dev->slock,
 				    V4L2_BUF_TYPE_VIDEO_CAPTURE,
 				    V4L2_FIELD_TOP,
 				    sizeof(struct cx88_buffer),
 				    dev);
-			/* init struct videobuf_dvb */
-			fe->dvb.name = dev->core->name;
-		}
-	} else {
-		/* no frontends allocated */
-		printk(KERN_ERR "%s/2 .num_frontends should be non-zero\n",
-			core->name);
-		goto fail_core;
+		/* init struct videobuf_dvb */
+		fe->dvb.name = dev->core->name;
 	}
+
 	err = dvb_register(dev);
 	if (err)
 		/* frontends/adapter de-allocated in dvb_register */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 60a8b3187f14..6025fdd23344 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -336,8 +336,8 @@ struct cx88_core {
 	/* config info -- dvb */
 #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
 	int 			   (*prev_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
-	void			   (*gate_ctrl)(struct cx88_core  *core, int open);
 #endif
+	void			   (*gate_ctrl)(struct cx88_core  *core, int open);
 
 	/* state info */
 	struct task_struct         *kthread;
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 94378ccb7505..5d882a44e3ee 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -62,9 +62,15 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev)
 
 	dprintk("Stopping isoc\n");
 	for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
-		usb_unlink_urb(dev->adev.urb[i]);
+		if (!irqs_disabled())
+			usb_kill_urb(dev->adev.urb[i]);
+		else
+			usb_unlink_urb(dev->adev.urb[i]);
 		usb_free_urb(dev->adev.urb[i]);
 		dev->adev.urb[i] = NULL;
+
+		kfree(dev->adev.transfer_buffer[i]);
+		dev->adev.transfer_buffer[i] = NULL;
 	}
 
 	return 0;
@@ -389,11 +395,15 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
 static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
 						    *substream)
 {
-	struct em28xx *dev;
+       unsigned long flags;
 
+	struct em28xx *dev;
 	snd_pcm_uframes_t hwptr_done;
+
 	dev = snd_pcm_substream_chip(substream);
+       spin_lock_irqsave(&dev->adev.slock, flags);
 	hwptr_done = dev->adev.hwptr_done_capture;
+       spin_unlock_irqrestore(&dev->adev.slock, flags);
 
 	return hwptr_done;
 }
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index ef9bf008a924..3b3ca3f46d52 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -102,6 +102,18 @@ static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
 /* Board  - EM2870 Kworld 355u
    Analog - No input analog */
 
+static struct em28xx_reg_seq kworld_330u_analog[] = {
+	{EM28XX_R08_GPIO,	0x6d,	~EM_GPIO_4,	10},
+	{EM2880_R04_GPO,	0x00,	0xff,		10},
+	{ -1,			-1,	-1,		-1},
+};
+
+static struct em28xx_reg_seq kworld_330u_digital[] = {
+	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{EM2880_R04_GPO,	0x08,	0xff,		10},
+	{ -1,			-1,	-1,		-1},
+};
+
 /* Callback for the most boards */
 static struct em28xx_reg_seq default_tuner_gpio[] = {
 	{EM28XX_R08_GPIO,	EM_GPIO_4,	EM_GPIO_4,	10},
@@ -1177,29 +1189,33 @@ struct em28xx_board em28xx_boards[] = {
 			.gpio     = hauppauge_wintv_hvr_900_analog,
 		} },
 	},
-	[EM2883_BOARD_KWORLD_HYBRID_A316] = {
+	[EM2883_BOARD_KWORLD_HYBRID_330U] = {
 		.name         = "Kworld PlusTV HD Hybrid 330",
 		.tuner_type   = TUNER_XC2028,
 		.tuner_gpio   = default_tuner_gpio,
 		.decoder      = EM28XX_TVP5150,
 		.mts_firmware = 1,
 		.has_dvb      = 1,
-		.dvb_gpio     = default_digital,
+		.dvb_gpio     = kworld_330u_digital,
+		.xclk             = EM28XX_XCLK_FREQUENCY_12MHZ,
+		.i2c_speed        = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_EEPROM_ON_BOARD | EM28XX_I2C_EEPROM_KEY_VALID,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = TVP5150_COMPOSITE0,
 			.amux     = EM28XX_AMUX_VIDEO,
-			.gpio     = default_analog,
+			.gpio     = kworld_330u_analog,
+			.aout     = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
 		}, {
 			.type     = EM28XX_VMUX_COMPOSITE1,
 			.vmux     = TVP5150_COMPOSITE1,
 			.amux     = EM28XX_AMUX_LINE_IN,
-			.gpio     = hauppauge_wintv_hvr_900_analog,
+			.gpio     = kworld_330u_analog,
+			.aout     = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
 		}, {
 			.type     = EM28XX_VMUX_SVIDEO,
 			.vmux     = TVP5150_SVIDEO,
 			.amux     = EM28XX_AMUX_LINE_IN,
-			.gpio     = hauppauge_wintv_hvr_900_analog,
+			.gpio     = kworld_330u_analog,
 		} },
 	},
 	[EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
@@ -1249,7 +1265,7 @@ struct usb_device_id em28xx_id_table [] = {
 	{ USB_DEVICE(0xeb1a, 0xe310),
 			.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
 	{ USB_DEVICE(0xeb1a, 0xa316),
-			.driver_info = EM2883_BOARD_KWORLD_HYBRID_A316 },
+			.driver_info = EM2883_BOARD_KWORLD_HYBRID_330U },
 	{ USB_DEVICE(0xeb1a, 0xe320),
 			.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II },
 	{ USB_DEVICE(0xeb1a, 0xe323),
@@ -1526,6 +1542,10 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
 		/* FIXME: Better to specify the needed IF */
 		ctl->demod = XC3028_FE_DEFAULT;
 		break;
+	case EM2883_BOARD_KWORLD_HYBRID_330U:
+		ctl->demod = XC3028_FE_CHINA;
+		ctl->fname = XC2028_DEFAULT_FIRMWARE;
+		break;
 	default:
 		ctl->demod = XC3028_FE_OREN538;
 	}
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index eb5fb05fab22..94fb1b639a2e 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -438,6 +438,10 @@ int em28xx_audio_analog_set(struct em28xx *dev)
 	if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
 		int vol;
 
+		em28xx_write_ac97(dev, AC97_POWER_DOWN_CTRL, 0x4200);
+		em28xx_write_ac97(dev, AC97_EXT_AUD_CTRL, 0x0031);
+		em28xx_write_ac97(dev, AC97_PCM_IN_SRATE, 0xbb80);
+
 		/* LSB: left channel - both channels with the same level */
 		vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8);
 
@@ -454,6 +458,15 @@ int em28xx_audio_analog_set(struct em28xx *dev)
 				em28xx_warn("couldn't setup AC97 register %d\n",
 				     outputs[i].reg);
 		}
+
+		if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) {
+			int sel = ac97_return_record_select(dev->ctl_aoutput);
+
+			/* Use the same input for both left and right channels */
+			sel |= (sel << 8);
+
+			em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel);
+		}
 	}
 
 	return ret;
@@ -847,8 +860,11 @@ void em28xx_uninit_isoc(struct em28xx *dev)
 	for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
 		urb = dev->isoc_ctl.urb[i];
 		if (urb) {
-			usb_kill_urb(urb);
-			usb_unlink_urb(urb);
+			if (!irqs_disabled())
+				usb_kill_urb(urb);
+			else
+				usb_unlink_urb(urb);
+
 			if (dev->isoc_ctl.transfer_buffer[i]) {
 				usb_buffer_free(dev->udev,
 					urb->transfer_buffer_length,
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index d38cb21834d9..9ad8527b3fda 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -28,6 +28,7 @@
 
 #include "lgdt330x.h"
 #include "zl10353.h"
+#include "s5h1409.h"
 #ifdef EM28XX_DRX397XD_SUPPORT
 #include "drx397xD.h"
 #endif
@@ -232,6 +233,15 @@ static struct zl10353_config em28xx_zl10353_with_xc3028 = {
 	.if2 = 45600,
 };
 
+static struct s5h1409_config em28xx_s5h1409_with_xc3028 = {
+	.demod_address = 0x32 >> 1,
+	.output_mode   = S5H1409_PARALLEL_OUTPUT,
+	.gpio          = S5H1409_GPIO_OFF,
+	.inversion     = S5H1409_INVERSION_OFF,
+	.status_mode   = S5H1409_DEMODLOCKING,
+	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
+};
+
 #ifdef EM28XX_DRX397XD_SUPPORT
 /* [TODO] djh - not sure yet what the device config needs to contain */
 static struct drx397xD_config em28xx_drx397xD_with_xc3028 = {
@@ -412,7 +422,6 @@ static int dvb_init(struct em28xx *dev)
 	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
 	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
 	case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
-	case EM2883_BOARD_KWORLD_HYBRID_A316:
 	case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
 		dvb->frontend = dvb_attach(lgdt330x_attach,
 					   &em2880_lgdt3303_dev,
@@ -433,6 +442,15 @@ static int dvb_init(struct em28xx *dev)
 			goto out_free;
 		}
 		break;
+	case EM2883_BOARD_KWORLD_HYBRID_330U:
+		dvb->frontend = dvb_attach(s5h1409_attach,
+					   &em28xx_s5h1409_with_xc3028,
+					   &dev->i2c_adap);
+		if (attach_xc3028(0x61, dev) < 0) {
+			result = -EINVAL;
+			goto out_free;
+		}
+		break;
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
 #ifdef EM28XX_DRX397XD_SUPPORT
 		/* We don't have the config structure properly populated, so
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 416b691c33c1..8e61b2ca9167 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -886,10 +886,10 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 	if (0 == INPUT(i)->type)
 		return -EINVAL;
 
-	mutex_lock(&dev->lock);
-
-	video_mux(dev, i);
+	dev->ctl_input = i;
 
+	mutex_lock(&dev->lock);
+	video_mux(dev, dev->ctl_input);
 	mutex_unlock(&dev->lock);
 	return 0;
 }
@@ -939,6 +939,12 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
 	struct em28xx_fh   *fh  = priv;
 	struct em28xx      *dev = fh->dev;
 
+
+	if (a->index >= MAX_EM28XX_INPUT)
+		return -EINVAL;
+	if (0 == INPUT(a->index)->type)
+		return -EINVAL;
+
 	mutex_lock(&dev->lock);
 
 	dev->ctl_ainput = INPUT(a->index)->amux;
@@ -1950,6 +1956,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
 
 int em28xx_register_analog_devices(struct em28xx *dev)
 {
+      u8 val;
 	int ret;
 
 	printk(KERN_INFO "%s: v4l2 driver version %d.%d.%d\n",
@@ -1957,34 +1964,34 @@ int em28xx_register_analog_devices(struct em28xx *dev)
 		(EM28XX_VERSION_CODE >> 16) & 0xff,
 		(EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
 
+	/* set default norm */
+	dev->norm = em28xx_video_template.current_norm;
+	dev->width = norm_maxw(dev);
+	dev->height = norm_maxh(dev);
+	dev->interlaced = EM28XX_INTERLACED_DEFAULT;
+	dev->hscale = 0;
+	dev->vscale = 0;
+	dev->ctl_input = 0;
+
 	/* Analog specific initialization */
 	dev->format = &format[0];
-	video_mux(dev, 0);
+	video_mux(dev, dev->ctl_input);
+
+	/* Audio defaults */
+	dev->mute = 1;
+	dev->volume = 0x1f;
 
 	/* enable vbi capturing */
 
 /*	em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
-/*	em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */
+       val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
+       em28xx_write_reg(dev, EM28XX_R0F_XCLK, (EM28XX_XCLK_AUDIO_UNMUTE | val));
 	em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
 
-	dev->mute = 1;		/* maybe not the right place... */
-	dev->volume = 0x1f;
-
 	em28xx_set_outfmt(dev);
 	em28xx_colorlevels_set_default(dev);
 	em28xx_compression_disable(dev);
 
-	/* set default norm */
-	dev->norm = em28xx_video_template.current_norm;
-	dev->width = norm_maxw(dev);
-	dev->height = norm_maxh(dev);
-	dev->interlaced = EM28XX_INTERLACED_DEFAULT;
-	dev->hscale = 0;
-	dev->vscale = 0;
-
-	/* FIXME: This is a very bad hack! Not all devices have TV on input 2 */
-	dev->ctl_input = 2;
-
 	/* allocate and fill video video_device struct */
 	dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
 	if (!dev->vdev) {
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 6c6b94aa05b2..dd2cd36fb1bb 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -94,7 +94,7 @@
 #define EM2882_BOARD_KWORLD_VS_DVBT		  54
 #define EM2882_BOARD_TERRATEC_HYBRID_XS		  55
 #define EM2882_BOARD_PINNACLE_HYBRID_PRO	  56
-#define EM2883_BOARD_KWORLD_HYBRID_A316		  57
+#define EM2883_BOARD_KWORLD_HYBRID_330U                  57
 #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU	  58
 #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850	  60
 #define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2	  61
@@ -300,13 +300,32 @@ enum em28xx_amux {
 };
 
 enum em28xx_aout {
+	/* AC97 outputs */
 	EM28XX_AOUT_MASTER = 1 << 0,
 	EM28XX_AOUT_LINE   = 1 << 1,
 	EM28XX_AOUT_MONO   = 1 << 2,
 	EM28XX_AOUT_LFE    = 1 << 3,
 	EM28XX_AOUT_SURR   = 1 << 4,
+
+	/* PCM IN Mixer - used by AC97_RECORD_SELECT register */
+	EM28XX_AOUT_PCM_IN = 1 << 7,
+
+	/* Bits 10-8 are used to indicate the PCM IN record select */
+	EM28XX_AOUT_PCM_MIC_PCM = 0 << 8,
+	EM28XX_AOUT_PCM_CD	= 1 << 8,
+	EM28XX_AOUT_PCM_VIDEO	= 2 << 8,
+	EM28XX_AOUT_PCM_AUX	= 3 << 8,
+	EM28XX_AOUT_PCM_LINE	= 4 << 8,
+	EM28XX_AOUT_PCM_STEREO	= 5 << 8,
+	EM28XX_AOUT_PCM_MONO	= 6 << 8,
+	EM28XX_AOUT_PCM_PHONE	= 7 << 8,
 };
 
+static inline int ac97_return_record_select(int a_out)
+{
+	return (a_out & 0x700) >> 8;
+}
+
 struct em28xx_reg_seq {
 	int reg;
 	unsigned char val, mask;
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 5e36b9a4ae3e..2ed24527ecd6 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -423,7 +423,8 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
 			break;
 
 		gspca_dev->urb[i] = NULL;
-		usb_kill_urb(urb);
+		if (!gspca_dev->present)
+			usb_kill_urb(urb);
 		if (urb->transfer_buffer != NULL)
 			usb_buffer_free(gspca_dev->dev,
 					urb->transfer_buffer_length,
@@ -1950,7 +1951,6 @@ void gspca_disconnect(struct usb_interface *intf)
 	struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
 
 	gspca_dev->present = 0;
-	gspca_dev->streaming = 0;
 
 	usb_set_intfdata(intf, NULL);
 
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index e8e5921cdc34..c46c990987f9 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -949,8 +949,10 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
 	itv->instance = atomic_inc_return(&ivtv_instance) - 1;
 
 	retval = v4l2_device_register(&dev->dev, &itv->device);
-	if (retval)
+	if (retval) {
+		kfree(itv);
 		return retval;
+	}
 	/* "ivtv + PCI ID" is a bit of a mouthful, so use
 	   "ivtv + instance" instead. */
 	snprintf(itv->device.name, sizeof(itv->device.name),
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 39fbc970f43d..0d810189dd87 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -62,7 +62,6 @@
 #include <linux/poll.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <linux/version.h>
 #include <asm/io.h>
 
 #include "pwc.h"
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index d6848f7a503b..05221d47dd4c 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -149,7 +149,7 @@ static const struct i2c_reg_value saa7127_init_config_common[] = {
 	{ SAA7127_REG_COPYGEN_0, 			0x77 },
 	{ SAA7127_REG_COPYGEN_1, 			0x41 },
 	{ SAA7127_REG_COPYGEN_2, 			0x00 },	/* Macrovision enable/disable */
-	{ SAA7127_REG_OUTPUT_PORT_CONTROL, 		0x9e },
+	{ SAA7127_REG_OUTPUT_PORT_CONTROL, 		0xbf },
 	{ SAA7127_REG_GAIN_LUMINANCE_RGB, 		0x00 },
 	{ SAA7127_REG_GAIN_COLORDIFF_RGB, 		0x00 },
 	{ SAA7127_REG_INPUT_PORT_CONTROL_1, 		0x80 },	/* for color bars */
@@ -488,12 +488,18 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output)
 		break;
 
 	case SAA7127_OUTPUT_TYPE_COMPOSITE:
-		state->reg_2d = 0x08;	/* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
+		if (state->ident == V4L2_IDENT_SAA7129)
+			state->reg_2d = 0x20;	/* CVBS only */
+		else
+			state->reg_2d = 0x08;	/* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
 		state->reg_3a = 0x13;	/* by default switch YUV to RGB-matrix on */
 		break;
 
 	case SAA7127_OUTPUT_TYPE_SVIDEO:
-		state->reg_2d = 0xff;	/* 11111111  croma -> R, luma -> CVBS + G + B */
+		if (state->ident == V4L2_IDENT_SAA7129)
+			state->reg_2d = 0x18;	/* Y + C */
+		else
+			state->reg_2d = 0xff;   /*11111111  croma -> R, luma -> CVBS + G + B */
 		state->reg_3a = 0x13;	/* by default switch YUV to RGB-matrix on */
 		break;
 
@@ -508,7 +514,10 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output)
 		break;
 
 	case SAA7127_OUTPUT_TYPE_BOTH:
-		state->reg_2d = 0xbf;
+		if (state->ident == V4L2_IDENT_SAA7129)
+			state->reg_2d = 0x38;
+		else
+			state->reg_2d = 0xbf;
 		state->reg_3a = 0x13;	/* by default switch YUV to RGB-matrix on */
 		break;
 
@@ -731,24 +740,6 @@ static int saa7127_probe(struct i2c_client *client,
 		return -ENODEV;
 	}
 
-	/* Configure Encoder */
-
-	v4l2_dbg(1, debug, sd, "Configuring encoder\n");
-	saa7127_write_inittab(sd, saa7127_init_config_common);
-	saa7127_set_std(sd, V4L2_STD_NTSC);
-	saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH);
-	saa7127_set_vps(sd, &vbi);
-	saa7127_set_wss(sd, &vbi);
-	saa7127_set_cc(sd, &vbi);
-	saa7127_set_xds(sd, &vbi);
-	if (test_image == 1)
-		/* The Encoder has an internal Colorbar generator */
-		/* This can be used for debugging */
-		saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE);
-	else
-		saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
-	saa7127_set_video_enable(sd, 1);
-
 	if (id->driver_data) {	/* Chip type is already known */
 		state->ident = id->driver_data;
 	} else {		/* Needs detection */
@@ -770,6 +761,23 @@ static int saa7127_probe(struct i2c_client *client,
 
 	v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
 			client->addr << 1, client->adapter->name);
+
+	v4l2_dbg(1, debug, sd, "Configuring encoder\n");
+	saa7127_write_inittab(sd, saa7127_init_config_common);
+	saa7127_set_std(sd, V4L2_STD_NTSC);
+	saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH);
+	saa7127_set_vps(sd, &vbi);
+	saa7127_set_wss(sd, &vbi);
+	saa7127_set_cc(sd, &vbi);
+	saa7127_set_xds(sd, &vbi);
+	if (test_image == 1)
+		/* The Encoder has an internal Colorbar generator */
+		/* This can be used for debugging */
+		saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE);
+	else
+		saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
+	saa7127_set_video_enable(sd, 1);
+
 	if (state->ident == V4L2_IDENT_SAA7129)
 		saa7127_write_inittab(sd, saa7129_init_config_extra);
 	return 0;
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index 26194a0ce927..c750d3dd57d2 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -1089,7 +1089,11 @@ static int saa7134_alsa_init(void)
 
 	list_for_each(list,&saa7134_devlist) {
 		dev = list_entry(list, struct saa7134_dev, devlist);
-		alsa_device_init(dev);
+		if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
+			printk(KERN_INFO "%s/alsa: %s doesn't support digital audio\n",
+				dev->name, saa7134_boards[dev->board].name);
+		else
+			alsa_device_init(dev);
 	}
 
 	if (dev == NULL)
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index dfbe08a9ad9b..99221d726edb 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -660,6 +660,10 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
 
 	saa_writel(SAA7134_IRQ1, 0);
 	saa_writel(SAA7134_IRQ2, 0);
+
+	/* Clear any stale IRQ reports */
+	saa_writel(SAA7134_IRQ_REPORT, saa_readl(SAA7134_IRQ_REPORT));
+
 	mutex_init(&dev->lock);
 	spin_lock_init(&dev->slock);
 
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index 454ad1dd7507..88c5e942f751 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -30,7 +30,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 56f0c0eb500f..00c6cbe06ab0 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -242,7 +242,7 @@ static int tda9875_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 static int tda9875_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
 	struct tda9875 *t = to_state(sd);
-	int chvol=0, volume, balance, left, right;
+	int chvol = 0, volume = 0, balance = 0, left, right;
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_VOLUME:
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 3b0b84c2e451..78277abb733b 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -427,6 +427,9 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
 	const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
 
 	memset(tvee, 0, sizeof(*tvee));
+	tvee->tuner_type = TUNER_ABSENT;
+	tvee->tuner2_type = TUNER_ABSENT;
+
 	done = len = beenhere = 0;
 
 	/* Different eeprom start offsets for em28xx, cx2388x and cx23418 */
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index ac9aa40d09f6..8e23aa53c29a 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -1401,7 +1401,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
 	decoder->pdata = client->dev.platform_data;
 	if (!decoder->pdata) {
-		v4l_err(client, "No platform data\n!!");
+		v4l_err(client, "No platform data!!\n");
 		return -ENODEV;
 	}
 	/*
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index 4f16effb530f..f4522bb08916 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -21,7 +21,6 @@
  */
 
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/i2c.h>
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 4b712f69d1b7..a5fb74bf2407 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -21,7 +21,6 @@
  * 02110-1301, USA.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/i2c.h>
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 9907b9aff2b9..6b66ae4f430f 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -157,7 +157,7 @@ usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
 	struct i2c_msg *pmsg;
 	struct usb_usbvision *usbvision;
 	int i, ret;
-	unsigned char addr;
+	unsigned char addr = 0;
 
 	usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
 
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 2208165aa6f0..d2576f6391c0 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -1,7 +1,7 @@
 /*
  *      uvc_ctrl.c  --  USB Video Class driver - Controls
  *
- *      Copyright (C) 2005-2008
+ *      Copyright (C) 2005-2009
  *          Laurent Pinchart (laurent.pinchart@skynet.be)
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
@@ -29,7 +28,7 @@
 #define UVC_CTRL_DATA_BACKUP	1
 
 /* ------------------------------------------------------------------------
- * Control, formats, ...
+ * Controls
  */
 
 static struct uvc_control_info uvc_ctrls[] = {
@@ -635,7 +634,7 @@ static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping,
 		mask = (1 << bits) - 1;
 	}
 
-	/* Sign-extend the value if needed */
+	/* Sign-extend the value if needed. */
 	if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
 		value |= -(value & (1 << (mapping->size - 1)));
 
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 89d8bd10a852..b12873265cc5 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1,7 +1,7 @@
 /*
  *      uvc_driver.c  --  USB Video Class driver
  *
- *      Copyright (C) 2005-2008
+ *      Copyright (C) 2005-2009
  *          Laurent Pinchart (laurent.pinchart@skynet.be)
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/usb.h>
@@ -49,7 +48,7 @@ static unsigned int uvc_quirks_param;
 unsigned int uvc_trace_param;
 
 /* ------------------------------------------------------------------------
- * Control, formats, ...
+ * Video formats
  */
 
 static struct uvc_format_desc uvc_fmts[] = {
@@ -474,7 +473,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 
 		/* Several UVC chipsets screw up dwMaxVideoFrameBufferSize
 		 * completely. Observed behaviours range from setting the
-		 * value to 1.1x the actual frame size of hardwiring the
+		 * value to 1.1x the actual frame size to hardwiring the
 		 * 16 low bits to 0. This results in a higher than necessary
 		 * memory usage as well as a wrong image size information. For
 		 * uncompressed formats this can be fixed by computing the
@@ -487,7 +486,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 		/* Some bogus devices report dwMinFrameInterval equal to
 		 * dwMaxFrameInterval and have dwFrameIntervalStep set to
 		 * zero. Setting all null intervals to 1 fixes the problem and
-		 * some other divisions by zero which could happen.
+		 * some other divisions by zero that could happen.
 		 */
 		for (i = 0; i < n; ++i) {
 			interval = get_unaligned_le32(&buffer[26+4*i]);
@@ -1200,13 +1199,13 @@ static void uvc_unregister_video(struct uvc_device *dev)
  * Scan the UVC descriptors to locate a chain starting at an Output Terminal
  * and containing the following units:
  *
- * - a USB Streaming Output Terminal
+ * - one Output Terminal (USB Streaming or Display)
  * - zero or one Processing Unit
  * - zero, one or mode single-input Selector Units
  * - zero or one multiple-input Selector Units, provided all inputs are
  *   connected to input terminals
  * - zero, one or mode single-input Extension Units
- * - one Camera Input Terminal, or one or more External terminals.
+ * - one or more Input Terminals (Camera, External or USB Streaming)
  *
  * A side forward scan is made on each detected entity to check for additional
  * extension units.
@@ -1531,10 +1530,6 @@ static int uvc_register_video(struct uvc_device *dev)
 
 	/* Set the driver data before calling video_register_device, otherwise
 	 * uvc_v4l2_open might race us.
-	 *
-	 * FIXME: usb_set_intfdata hasn't been called so far. Is that a
-	 * 	  problem ? Does any function which could be called here get
-	 * 	  a pointer to the usb_interface ?
 	 */
 	dev->video.vdev = vdev;
 	video_set_drvdata(vdev, &dev->video);
@@ -1569,7 +1564,7 @@ void uvc_delete(struct kref *kref)
 	struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
 	struct list_head *p, *n;
 
-	/* Unregister the video device */
+	/* Unregister the video device. */
 	uvc_unregister_video(dev);
 	usb_put_intf(dev->intf);
 	usb_put_dev(dev->udev);
@@ -1612,7 +1607,7 @@ static int uvc_probe(struct usb_interface *intf,
 		uvc_trace(UVC_TRACE_PROBE, "Probing generic UVC device %s\n",
 				udev->devpath);
 
-	/* Allocate memory for the device and initialize it */
+	/* Allocate memory for the device and initialize it. */
 	if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL)
 		return -ENOMEM;
 
@@ -1633,14 +1628,14 @@ static int uvc_probe(struct usb_interface *intf,
 			le16_to_cpu(udev->descriptor.idVendor),
 			le16_to_cpu(udev->descriptor.idProduct));
 
-	/* Parse the Video Class control descriptor */
+	/* Parse the Video Class control descriptor. */
 	if (uvc_parse_control(dev) < 0) {
 		uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC "
 			"descriptors.\n");
 		goto error;
 	}
 
-	uvc_printk(KERN_INFO, "Found UVC %u.%02u device %s (%04x:%04x)\n",
+	uvc_printk(KERN_INFO, "Found UVC %u.%02x device %s (%04x:%04x)\n",
 		dev->uvc_version >> 8, dev->uvc_version & 0xff,
 		udev->product ? udev->product : "<unnamed>",
 		le16_to_cpu(udev->descriptor.idVendor),
@@ -1653,18 +1648,18 @@ static int uvc_probe(struct usb_interface *intf,
 			"linux-uvc-devel mailing list.\n");
 	}
 
-	/* Initialize controls */
+	/* Initialize controls. */
 	if (uvc_ctrl_init_device(dev) < 0)
 		goto error;
 
-	/* Register the video devices */
+	/* Register the video devices. */
 	if (uvc_register_video(dev) < 0)
 		goto error;
 
-	/* Save our data pointer in the interface data */
+	/* Save our data pointer in the interface data. */
 	usb_set_intfdata(intf, dev);
 
-	/* Initialize the interrupt URB */
+	/* Initialize the interrupt URB. */
 	if ((ret = uvc_status_init(dev)) < 0) {
 		uvc_printk(KERN_INFO, "Unable to initialize the status "
 			"endpoint (%d), status interrupt will not be "
@@ -1839,24 +1834,24 @@ static struct usb_device_id uvc_ids[] = {
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0 },
 	/* Apple Built-In iSight */
-	{ .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
 	  .idVendor		= 0x05ac,
 	  .idProduct		= 0x8501,
-	  .bInterfaceClass      = USB_CLASS_VIDEO,
-	  .bInterfaceSubClass   = 1,
-	  .bInterfaceProtocol   = 0,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
 	  .driver_info 		= UVC_QUIRK_PROBE_MINMAX
 				| UVC_QUIRK_BUILTIN_ISIGHT },
 	/* Genesys Logic USB 2.0 PC Camera */
-	{ .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
-	  .idVendor             = 0x05e3,
-	  .idProduct            = 0x0505,
-	  .bInterfaceClass      = USB_CLASS_VIDEO,
-	  .bInterfaceSubClass   = 1,
-	  .bInterfaceProtocol   = 0,
-	  .driver_info          = UVC_QUIRK_STREAM_NO_FID },
+	  .idVendor		= 0x05e3,
+	  .idProduct		= 0x0505,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
 	/* MT6227 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c
index 37bdefdbead5..436f462685a0 100644
--- a/drivers/media/video/uvc/uvc_isight.c
+++ b/drivers/media/video/uvc/uvc_isight.c
@@ -3,6 +3,8 @@
  *
  *	Copyright (C) 2006-2007
  *		Ivan N. Zlatev <contact@i-nz.net>
+ *	Copyright (C) 2008-2009
+ *		Laurent Pinchart <laurent.pinchart@skynet.be>
  *
  *      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
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 42546342e97d..0155752e4a5a 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -1,7 +1,7 @@
 /*
  *      uvc_queue.c  --  USB Video Class driver - Buffers management
  *
- *      Copyright (C) 2005-2008
+ *      Copyright (C) 2005-2009
  *          Laurent Pinchart (laurent.pinchart@skynet.be)
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <linux/module.h>
@@ -37,22 +36,22 @@
  * to user space will return -EBUSY.
  *
  * Video buffers are managed using two queues. However, unlike most USB video
- * drivers which use an in queue and an out queue, we use a main queue which
- * holds all queued buffers (both 'empty' and 'done' buffers), and an irq
- * queue which holds empty buffers. This design (copied from video-buf)
- * minimizes locking in interrupt, as only one queue is shared between
- * interrupt and user contexts.
+ * drivers that use an in queue and an out queue, we use a main queue to hold
+ * all queued buffers (both 'empty' and 'done' buffers), and an irq queue to
+ * hold empty buffers. This design (copied from video-buf) minimizes locking
+ * in interrupt, as only one queue is shared between interrupt and user
+ * contexts.
  *
  * Use cases
  * ---------
  *
- * Unless stated otherwise, all operations which modify the irq buffers queue
+ * Unless stated otherwise, all operations that modify the irq buffers queue
  * are protected by the irq spinlock.
  *
  * 1. The user queues the buffers, starts streaming and dequeues a buffer.
  *
  *    The buffers are added to the main and irq queues. Both operations are
- *    protected by the queue lock, and the latert is protected by the irq
+ *    protected by the queue lock, and the later is protected by the irq
  *    spinlock as well.
  *
  *    The completion handler fetches a buffer from the irq queue and fills it
@@ -60,7 +59,7 @@
  *    returns immediately.
  *
  *    When the buffer is full, the completion handler removes it from the irq
- *    queue, marks it as ready (UVC_BUF_STATE_DONE) and wake its wait queue.
+ *    queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue.
  *    At that point, any process waiting on the buffer will be woken up. If a
  *    process tries to dequeue a buffer after it has been marked ready, the
  *    dequeing will succeed immediately.
@@ -91,8 +90,8 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
 /*
  * Allocate the video buffers.
  *
- * Pages are reserved to make sure they will not be swaped, as they will be
- * filled in URB completion handler.
+ * Pages are reserved to make sure they will not be swapped, as they will be
+ * filled in the URB completion handler.
  *
  * Buffers will be individually mapped, so they must all be page aligned.
  */
@@ -210,8 +209,8 @@ int uvc_query_buffer(struct uvc_video_queue *queue,
 	__uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf);
 
 done:
-       mutex_unlock(&queue->mutex);
-       return ret;
+	mutex_unlock(&queue->mutex);
+	return ret;
 }
 
 /*
@@ -236,7 +235,7 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
 	}
 
 	mutex_lock(&queue->mutex);
-	if (v4l2_buf->index >= queue->count)  {
+	if (v4l2_buf->index >= queue->count) {
 		uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n");
 		ret = -EINVAL;
 		goto done;
@@ -429,7 +428,7 @@ done:
  * Cancel the video buffers queue.
  *
  * Cancelling the queue marks all buffers on the irq queue as erroneous,
- * wakes them up and remove them from the queue.
+ * wakes them up and removes them from the queue.
  *
  * If the disconnect parameter is set, further calls to uvc_queue_buffer will
  * fail with -ENODEV.
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c
index 5d60b264d59a..c1e4ae27c613 100644
--- a/drivers/media/video/uvc/uvc_status.c
+++ b/drivers/media/video/uvc/uvc_status.c
@@ -1,7 +1,7 @@
 /*
  *      uvc_status.c  --  USB Video Class driver - Status endpoint
  *
- *      Copyright (C) 2007-2008
+ *      Copyright (C) 2007-2009
  *          Laurent Pinchart (laurent.pinchart@skynet.be)
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/input.h>
 #include <linux/usb.h>
 #include <linux/usb/input.h>
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index fa150fff2c10..d681519d0c8a 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -1,7 +1,7 @@
 /*
  *      uvc_v4l2.c  --  USB Video Class driver - V4L2 API
  *
- *      Copyright (C) 2005-2008
+ *      Copyright (C) 2005-2009
  *          Laurent Pinchart (laurent.pinchart@skynet.be)
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -37,7 +37,7 @@
  * must be grouped (for instance the Red Balance, Blue Balance and Do White
  * Balance V4L2 controls use the White Balance Component UVC control) or
  * otherwise translated. The approach we take here is to use a translation
- * table for the controls which can be mapped directly, and handle the others
+ * table for the controls that can be mapped directly, and handle the others
  * manually.
  */
 static int uvc_v4l2_query_menu(struct uvc_video_device *video,
@@ -189,7 +189,7 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video,
 		probe->dwMaxVideoFrameSize =
 			video->streaming->ctrl.dwMaxVideoFrameSize;
 
-	/* Probe the device */
+	/* Probe the device. */
 	if ((ret = uvc_probe_video(video, probe)) < 0)
 		goto done;
 
@@ -354,11 +354,11 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
  *
  * Each open instance of a UVC device can either be in a privileged or
  * unprivileged state. Only a single instance can be in a privileged state at
- * a given time. Trying to perform an operation which requires privileges will
+ * a given time. Trying to perform an operation that requires privileges will
  * automatically acquire the required privileges if possible, or return -EBUSY
  * otherwise. Privileges are dismissed when closing the instance.
  *
- * Operations which require privileges are:
+ * Operations that require privileges are:
  *
  * - VIDIOC_S_INPUT
  * - VIDIOC_S_PARM
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index e7c31995527f..9bc4705be78d 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -1,7 +1,7 @@
 /*
  *      uvc_video.c  --  USB Video Class driver - Video handling
  *
- *      Copyright (C) 2005-2008
+ *      Copyright (C) 2005-2009
  *          Laurent Pinchart (laurent.pinchart@skynet.be)
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/usb.h>
@@ -115,7 +114,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
 		ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
 		ret = 0;
 		goto out;
-	} else if (query == GET_DEF && probe == 1) {
+	} else if (query == GET_DEF && probe == 1 && ret != size) {
 		/* Many cameras don't support the GET_DEF request on their
 		 * video probe control. Warn once and return, the caller will
 		 * fall back to GET_CUR.
@@ -160,7 +159,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
 	}
 
 	/* Some broken devices return a null or wrong dwMaxVideoFrameSize.
-	 * Try to get the value from the format and frame descriptor.
+	 * Try to get the value from the format and frame descriptors.
 	 */
 	uvc_fixup_buffer_size(video, ctrl);
 	ret = 0;
@@ -191,9 +190,6 @@ static int uvc_set_video_ctrl(struct uvc_video_device *video,
 	*(__le16 *)&data[12] = cpu_to_le16(ctrl->wCompQuality);
 	*(__le16 *)&data[14] = cpu_to_le16(ctrl->wCompWindowSize);
 	*(__le16 *)&data[16] = cpu_to_le16(ctrl->wDelay);
-	/* Note: Some of the fields below are not required for IN devices (see
-	 * UVC spec, 4.3.1.1), but we still copy them in case support for OUT
-	 * devices is added in the future. */
 	put_unaligned_le32(ctrl->dwMaxVideoFrameSize, &data[18]);
 	put_unaligned_le32(ctrl->dwMaxPayloadTransferSize, &data[22]);
 
@@ -400,7 +396,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
 	 *
 	 * Empty buffers (bytesused == 0) don't trigger end of frame detection
 	 * as it doesn't make sense to return an empty buffer. This also
-	 * avoids detecting and of frame conditions at FID toggling if the
+	 * avoids detecting end of frame conditions at FID toggling if the
 	 * previous payload had the EOF bit set.
 	 */
 	if (fid != video->last_fid && buf->buf.bytesused != 0) {
@@ -453,6 +449,17 @@ static void uvc_video_decode_end(struct uvc_video_device *video,
 	}
 }
 
+/* Video payload encoding is handled by uvc_video_encode_header() and
+ * uvc_video_encode_data(). Only bulk transfers are currently supported.
+ *
+ * uvc_video_encode_header is called at the start of a payload. It adds header
+ * data to the transfer buffer and returns the header size. As the only known
+ * UVC output device transfers a whole frame in a single payload, the EOF bit
+ * is always set in the header.
+ *
+ * uvc_video_encode_data is called for every URB and copies the data from the
+ * video buffer to the transfer buffer.
+ */
 static int uvc_video_encode_header(struct uvc_video_device *video,
 		struct uvc_buffer *buf, __u8 *data, int len)
 {
@@ -953,7 +960,7 @@ int uvc_video_suspend(struct uvc_video_device *video)
 }
 
 /*
- * Reconfigure the video interface and restart streaming if it was enable
+ * Reconfigure the video interface and restart streaming if it was enabled
  * before suspend.
  *
  * If an error occurs, disable the video queue. This will wake all pending
@@ -985,8 +992,8 @@ int uvc_video_resume(struct uvc_video_device *video)
  */
 
 /*
- * Initialize the UVC video device by retrieving the default format and
- * committing it.
+ * Initialize the UVC video device by switching to alternate setting 0 and
+ * retrieve the default format.
  *
  * Some cameras (namely the Fuji Finepix) set the format and frame
  * indexes to zero. The UVC standard doesn't clearly make this a spec
@@ -1014,7 +1021,7 @@ int uvc_video_init(struct uvc_video_device *video)
 	 */
 	usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
 
-	/* Some webcams don't suport GET_DEF request on the probe control. We
+	/* Some webcams don't suport GET_DEF requests on the probe control. We
 	 * fall back to GET_CUR if GET_DEF fails.
 	 */
 	if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 &&
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index bcf4361dc1bc..027947ea9b6e 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -72,149 +72,149 @@ struct uvc_xu_control {
  * UVC constants
  */
 
-#define SC_UNDEFINED                    0x00
-#define SC_VIDEOCONTROL                 0x01
-#define SC_VIDEOSTREAMING               0x02
-#define SC_VIDEO_INTERFACE_COLLECTION   0x03
+#define SC_UNDEFINED			0x00
+#define SC_VIDEOCONTROL			0x01
+#define SC_VIDEOSTREAMING		0x02
+#define SC_VIDEO_INTERFACE_COLLECTION	0x03
 
-#define PC_PROTOCOL_UNDEFINED           0x00
+#define PC_PROTOCOL_UNDEFINED		0x00
 
-#define CS_UNDEFINED                    0x20
-#define CS_DEVICE                       0x21
-#define CS_CONFIGURATION                0x22
-#define CS_STRING                       0x23
-#define CS_INTERFACE                    0x24
-#define CS_ENDPOINT                     0x25
+#define CS_UNDEFINED			0x20
+#define CS_DEVICE			0x21
+#define CS_CONFIGURATION		0x22
+#define CS_STRING			0x23
+#define CS_INTERFACE			0x24
+#define CS_ENDPOINT			0x25
 
 /* VideoControl class specific interface descriptor */
-#define VC_DESCRIPTOR_UNDEFINED         0x00
-#define VC_HEADER                       0x01
-#define VC_INPUT_TERMINAL               0x02
-#define VC_OUTPUT_TERMINAL              0x03
-#define VC_SELECTOR_UNIT                0x04
-#define VC_PROCESSING_UNIT              0x05
-#define VC_EXTENSION_UNIT               0x06
+#define VC_DESCRIPTOR_UNDEFINED		0x00
+#define VC_HEADER			0x01
+#define VC_INPUT_TERMINAL		0x02
+#define VC_OUTPUT_TERMINAL		0x03
+#define VC_SELECTOR_UNIT		0x04
+#define VC_PROCESSING_UNIT		0x05
+#define VC_EXTENSION_UNIT		0x06
 
 /* VideoStreaming class specific interface descriptor */
-#define VS_UNDEFINED                    0x00
-#define VS_INPUT_HEADER                 0x01
-#define VS_OUTPUT_HEADER                0x02
-#define VS_STILL_IMAGE_FRAME            0x03
-#define VS_FORMAT_UNCOMPRESSED          0x04
-#define VS_FRAME_UNCOMPRESSED           0x05
-#define VS_FORMAT_MJPEG                 0x06
-#define VS_FRAME_MJPEG                  0x07
-#define VS_FORMAT_MPEG2TS               0x0a
-#define VS_FORMAT_DV                    0x0c
-#define VS_COLORFORMAT                  0x0d
-#define VS_FORMAT_FRAME_BASED           0x10
-#define VS_FRAME_FRAME_BASED            0x11
-#define VS_FORMAT_STREAM_BASED          0x12
+#define VS_UNDEFINED			0x00
+#define VS_INPUT_HEADER			0x01
+#define VS_OUTPUT_HEADER		0x02
+#define VS_STILL_IMAGE_FRAME		0x03
+#define VS_FORMAT_UNCOMPRESSED		0x04
+#define VS_FRAME_UNCOMPRESSED		0x05
+#define VS_FORMAT_MJPEG			0x06
+#define VS_FRAME_MJPEG			0x07
+#define VS_FORMAT_MPEG2TS		0x0a
+#define VS_FORMAT_DV			0x0c
+#define VS_COLORFORMAT			0x0d
+#define VS_FORMAT_FRAME_BASED		0x10
+#define VS_FRAME_FRAME_BASED		0x11
+#define VS_FORMAT_STREAM_BASED		0x12
 
 /* Endpoint type */
-#define EP_UNDEFINED                    0x00
-#define EP_GENERAL                      0x01
-#define EP_ENDPOINT                     0x02
-#define EP_INTERRUPT                    0x03
+#define EP_UNDEFINED			0x00
+#define EP_GENERAL			0x01
+#define EP_ENDPOINT			0x02
+#define EP_INTERRUPT			0x03
 
 /* Request codes */
-#define RC_UNDEFINED                    0x00
-#define SET_CUR                         0x01
-#define GET_CUR                         0x81
-#define GET_MIN                         0x82
-#define GET_MAX                         0x83
-#define GET_RES                         0x84
-#define GET_LEN                         0x85
-#define GET_INFO                        0x86
-#define GET_DEF                         0x87
+#define RC_UNDEFINED			0x00
+#define SET_CUR				0x01
+#define GET_CUR				0x81
+#define GET_MIN				0x82
+#define GET_MAX				0x83
+#define GET_RES				0x84
+#define GET_LEN				0x85
+#define GET_INFO			0x86
+#define GET_DEF				0x87
 
 /* VideoControl interface controls */
-#define VC_CONTROL_UNDEFINED            0x00
-#define VC_VIDEO_POWER_MODE_CONTROL     0x01
-#define VC_REQUEST_ERROR_CODE_CONTROL   0x02
+#define VC_CONTROL_UNDEFINED		0x00
+#define VC_VIDEO_POWER_MODE_CONTROL	0x01
+#define VC_REQUEST_ERROR_CODE_CONTROL	0x02
 
 /* Terminal controls */
-#define TE_CONTROL_UNDEFINED            0x00
+#define TE_CONTROL_UNDEFINED		0x00
 
 /* Selector Unit controls */
-#define SU_CONTROL_UNDEFINED            0x00
-#define SU_INPUT_SELECT_CONTROL         0x01
+#define SU_CONTROL_UNDEFINED		0x00
+#define SU_INPUT_SELECT_CONTROL		0x01
 
 /* Camera Terminal controls */
-#define CT_CONTROL_UNDEFINED            		0x00
-#define CT_SCANNING_MODE_CONTROL        		0x01
-#define CT_AE_MODE_CONTROL              		0x02
-#define CT_AE_PRIORITY_CONTROL          		0x03
-#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL               0x04
-#define CT_EXPOSURE_TIME_RELATIVE_CONTROL               0x05
-#define CT_FOCUS_ABSOLUTE_CONTROL       		0x06
-#define CT_FOCUS_RELATIVE_CONTROL       		0x07
-#define CT_FOCUS_AUTO_CONTROL           		0x08
-#define CT_IRIS_ABSOLUTE_CONTROL        		0x09
-#define CT_IRIS_RELATIVE_CONTROL        		0x0a
-#define CT_ZOOM_ABSOLUTE_CONTROL        		0x0b
-#define CT_ZOOM_RELATIVE_CONTROL        		0x0c
-#define CT_PANTILT_ABSOLUTE_CONTROL     		0x0d
-#define CT_PANTILT_RELATIVE_CONTROL     		0x0e
-#define CT_ROLL_ABSOLUTE_CONTROL        		0x0f
-#define CT_ROLL_RELATIVE_CONTROL        		0x10
-#define CT_PRIVACY_CONTROL              		0x11
+#define CT_CONTROL_UNDEFINED				0x00
+#define CT_SCANNING_MODE_CONTROL			0x01
+#define CT_AE_MODE_CONTROL				0x02
+#define CT_AE_PRIORITY_CONTROL				0x03
+#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL		0x04
+#define CT_EXPOSURE_TIME_RELATIVE_CONTROL		0x05
+#define CT_FOCUS_ABSOLUTE_CONTROL			0x06
+#define CT_FOCUS_RELATIVE_CONTROL			0x07
+#define CT_FOCUS_AUTO_CONTROL				0x08
+#define CT_IRIS_ABSOLUTE_CONTROL			0x09
+#define CT_IRIS_RELATIVE_CONTROL			0x0a
+#define CT_ZOOM_ABSOLUTE_CONTROL			0x0b
+#define CT_ZOOM_RELATIVE_CONTROL			0x0c
+#define CT_PANTILT_ABSOLUTE_CONTROL			0x0d
+#define CT_PANTILT_RELATIVE_CONTROL			0x0e
+#define CT_ROLL_ABSOLUTE_CONTROL			0x0f
+#define CT_ROLL_RELATIVE_CONTROL			0x10
+#define CT_PRIVACY_CONTROL				0x11
 
 /* Processing Unit controls */
-#define PU_CONTROL_UNDEFINED            		0x00
-#define PU_BACKLIGHT_COMPENSATION_CONTROL               0x01
-#define PU_BRIGHTNESS_CONTROL           		0x02
-#define PU_CONTRAST_CONTROL             		0x03
-#define PU_GAIN_CONTROL                 		0x04
-#define PU_POWER_LINE_FREQUENCY_CONTROL 		0x05
-#define PU_HUE_CONTROL                  		0x06
-#define PU_SATURATION_CONTROL           		0x07
-#define PU_SHARPNESS_CONTROL            		0x08
-#define PU_GAMMA_CONTROL                		0x09
-#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL            0x0a
-#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL       0x0b
-#define PU_WHITE_BALANCE_COMPONENT_CONTROL              0x0c
-#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL         0x0d
-#define PU_DIGITAL_MULTIPLIER_CONTROL   		0x0e
-#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL             0x0f
-#define PU_HUE_AUTO_CONTROL             		0x10
-#define PU_ANALOG_VIDEO_STANDARD_CONTROL                0x11
-#define PU_ANALOG_LOCK_STATUS_CONTROL   		0x12
+#define PU_CONTROL_UNDEFINED				0x00
+#define PU_BACKLIGHT_COMPENSATION_CONTROL		0x01
+#define PU_BRIGHTNESS_CONTROL				0x02
+#define PU_CONTRAST_CONTROL				0x03
+#define PU_GAIN_CONTROL					0x04
+#define PU_POWER_LINE_FREQUENCY_CONTROL			0x05
+#define PU_HUE_CONTROL					0x06
+#define PU_SATURATION_CONTROL				0x07
+#define PU_SHARPNESS_CONTROL				0x08
+#define PU_GAMMA_CONTROL				0x09
+#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL		0x0a
+#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL	0x0b
+#define PU_WHITE_BALANCE_COMPONENT_CONTROL		0x0c
+#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL		0x0d
+#define PU_DIGITAL_MULTIPLIER_CONTROL			0x0e
+#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL		0x0f
+#define PU_HUE_AUTO_CONTROL				0x10
+#define PU_ANALOG_VIDEO_STANDARD_CONTROL		0x11
+#define PU_ANALOG_LOCK_STATUS_CONTROL			0x12
 
 #define LXU_MOTOR_PANTILT_RELATIVE_CONTROL		0x01
 #define LXU_MOTOR_PANTILT_RESET_CONTROL			0x02
 #define LXU_MOTOR_FOCUS_MOTOR_CONTROL			0x03
 
 /* VideoStreaming interface controls */
-#define VS_CONTROL_UNDEFINED            0x00
-#define VS_PROBE_CONTROL                0x01
-#define VS_COMMIT_CONTROL               0x02
-#define VS_STILL_PROBE_CONTROL          0x03
-#define VS_STILL_COMMIT_CONTROL         0x04
-#define VS_STILL_IMAGE_TRIGGER_CONTROL  0x05
-#define VS_STREAM_ERROR_CODE_CONTROL    0x06
-#define VS_GENERATE_KEY_FRAME_CONTROL   0x07
-#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
-#define VS_SYNC_DELAY_CONTROL           0x09
-
-#define TT_VENDOR_SPECIFIC              0x0100
-#define TT_STREAMING                    0x0101
+#define VS_CONTROL_UNDEFINED		0x00
+#define VS_PROBE_CONTROL		0x01
+#define VS_COMMIT_CONTROL		0x02
+#define VS_STILL_PROBE_CONTROL		0x03
+#define VS_STILL_COMMIT_CONTROL		0x04
+#define VS_STILL_IMAGE_TRIGGER_CONTROL	0x05
+#define VS_STREAM_ERROR_CODE_CONTROL	0x06
+#define VS_GENERATE_KEY_FRAME_CONTROL	0x07
+#define VS_UPDATE_FRAME_SEGMENT_CONTROL	0x08
+#define VS_SYNC_DELAY_CONTROL		0x09
+
+#define TT_VENDOR_SPECIFIC		0x0100
+#define TT_STREAMING			0x0101
 
 /* Input Terminal types */
-#define ITT_VENDOR_SPECIFIC             0x0200
-#define ITT_CAMERA                      0x0201
-#define ITT_MEDIA_TRANSPORT_INPUT       0x0202
+#define ITT_VENDOR_SPECIFIC		0x0200
+#define ITT_CAMERA			0x0201
+#define ITT_MEDIA_TRANSPORT_INPUT	0x0202
 
 /* Output Terminal types */
-#define OTT_VENDOR_SPECIFIC             0x0300
-#define OTT_DISPLAY                     0x0301
-#define OTT_MEDIA_TRANSPORT_OUTPUT      0x0302
+#define OTT_VENDOR_SPECIFIC		0x0300
+#define OTT_DISPLAY			0x0301
+#define OTT_MEDIA_TRANSPORT_OUTPUT	0x0302
 
 /* External Terminal types */
-#define EXTERNAL_VENDOR_SPECIFIC        0x0400
-#define COMPOSITE_CONNECTOR             0x0401
-#define SVIDEO_CONNECTOR                0x0402
-#define COMPONENT_CONNECTOR             0x0403
+#define EXTERNAL_VENDOR_SPECIFIC	0x0400
+#define COMPOSITE_CONNECTOR		0x0401
+#define SVIDEO_CONNECTOR		0x0402
+#define COMPONENT_CONNECTOR		0x0403
 
 #define UVC_TERM_INPUT			0x0000
 #define UVC_TERM_OUTPUT			0x8000
@@ -541,11 +541,11 @@ struct uvc_streaming {
 };
 
 enum uvc_buffer_state {
-	UVC_BUF_STATE_IDLE       = 0,
-	UVC_BUF_STATE_QUEUED     = 1,
-	UVC_BUF_STATE_ACTIVE     = 2,
-	UVC_BUF_STATE_DONE       = 3,
-	UVC_BUF_STATE_ERROR      = 4,
+	UVC_BUF_STATE_IDLE	= 0,
+	UVC_BUF_STATE_QUEUED	= 1,
+	UVC_BUF_STATE_ACTIVE	= 2,
+	UVC_BUF_STATE_DONE	= 3,
+	UVC_BUF_STATE_ERROR	= 4,
 };
 
 struct uvc_buffer {
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index fbe9cc0d433a..21208805ea9b 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/video/v4l2-subdev.c
@@ -28,13 +28,13 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg)
 {
 	switch (cmd) {
 	case VIDIOC_QUERYCTRL:
-		return v4l2_subdev_call(sd, core, querymenu, arg);
+		return v4l2_subdev_call(sd, core, queryctrl, arg);
 	case VIDIOC_G_CTRL:
 		return v4l2_subdev_call(sd, core, g_ctrl, arg);
 	case VIDIOC_S_CTRL:
 		return v4l2_subdev_call(sd, core, s_ctrl, arg);
 	case VIDIOC_QUERYMENU:
-		return v4l2_subdev_call(sd, core, queryctrl, arg);
+		return v4l2_subdev_call(sd, core, querymenu, arg);
 	case VIDIOC_LOG_STATUS:
 		return v4l2_subdev_call(sd, core, log_status);
 	case VIDIOC_DBG_G_CHIP_IDENT:
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h
index 46b7ad477ceb..e873a916250f 100644
--- a/drivers/media/video/zoran/zoran.h
+++ b/drivers/media/video/zoran/zoran.h
@@ -349,7 +349,6 @@ struct card_info {
 	u16 i2c_decoder, i2c_encoder;			/* I2C types */
 	u16 video_vfe, video_codec;			/* videocodec types */
 	u16 audio_chip;					/* audio type */
-	u16 vendor_id, device_id;	/* subsystem vendor/device ID */
 
 	int inputs;		/* number of video inputs */
 	struct input {
@@ -401,7 +400,6 @@ struct zoran {
 	char name[32];		/* name of this device */
 	struct pci_dev *pci_dev;	/* PCI device */
 	unsigned char revision;	/* revision of zr36057 */
-	unsigned int zr36057_adr;	/* bus address of IO mem returned by PCI BIOS */
 	unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */
 
 	spinlock_t spinlock;	/* Spinlock */
@@ -490,16 +488,10 @@ struct zoran {
 	wait_queue_head_t test_q;
 };
 
-/*The following should be done in more portable way. It depends on define
-  of _ALPHA_BUZ in the Makefile.*/
-
-#ifdef _ALPHA_BUZ
-#define btwrite(dat,adr)    writel((dat), zr->zr36057_adr+(adr))
-#define btread(adr)         readl(zr->zr36057_adr+(adr))
-#else
+/* There was something called _ALPHA_BUZ that used the PCI address instead of
+ * the kernel iomapped address for btread/btwrite.  */
 #define btwrite(dat,adr)    writel((dat), zr->zr36057_mem+(adr))
 #define btread(adr)         readl(zr->zr36057_mem+(adr))
-#endif
 
 #define btand(dat,adr)      btwrite((dat) & btread(adr), adr)
 #define btor(dat,adr)       btwrite((dat) | btread(adr), adr)
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 05f39195372e..5d2f090aa0f8 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -61,17 +61,17 @@
 
 extern const struct zoran_format zoran_formats[];
 
-static int card[BUZ_MAX] = { -1, -1, -1, -1 };
+static int card[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
 module_param_array(card, int, NULL, 0444);
-MODULE_PARM_DESC(card, "The type of card");
+MODULE_PARM_DESC(card, "Card type");
 
-static int encoder[BUZ_MAX] = { -1, -1, -1, -1 };
+static int encoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
 module_param_array(encoder, int, NULL, 0444);
-MODULE_PARM_DESC(encoder, "i2c TV encoder");
+MODULE_PARM_DESC(encoder, "Video encoder chip");
 
-static int decoder[BUZ_MAX] = { -1, -1, -1, -1 };
+static int decoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
 module_param_array(decoder, int, NULL, 0444);
-MODULE_PARM_DESC(decoder, "i2c TV decoder");
+MODULE_PARM_DESC(decoder, "Video decoder chip");
 
 /*
    The video mem address of the video card.
@@ -104,9 +104,9 @@ module_param(default_norm, int, 0444);
 MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
 
 /* /dev/videoN, -1 for autodetect */
-static int video_nr[BUZ_MAX] = {-1, -1, -1, -1};
+static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
 module_param_array(video_nr, int, NULL, 0444);
-MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)");
+MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
 
 /*
    Number and size of grab buffers for Video 4 Linux
@@ -153,9 +153,21 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
 MODULE_AUTHOR("Serguei Miridonov");
 MODULE_LICENSE("GPL");
 
+#define ZR_DEVICE(subven, subdev, data)	{ \
+	.vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \
+	.subvendor = (subven), .subdevice = (subdev), .driver_data = (data) }
+
+static struct pci_device_id zr36067_pci_tbl[] = {
+	ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10plus),
+	ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30plus),
+	ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10),
+	ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ),
+	ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS),
+	{0}
+};
+MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
 
-int zoran_num;			/* number of Buzs in use */
-struct zoran *zoran[BUZ_MAX];
+static unsigned int zoran_num;		/* number of cards found */
 
 /* videocodec bus functions ZR36060 */
 static u32
@@ -472,8 +484,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
 	}, {
 		.type = DC10plus,
 		.name = "DC10plus",
-		.vendor_id = PCI_VENDOR_ID_MIRO,
-		.device_id = PCI_DEVICE_ID_MIRO_DC10PLUS,
 		.i2c_decoder = I2C_DRIVERID_SAA7110,
 		.i2c_encoder = I2C_DRIVERID_ADV7175,
 		.video_codec = CODEC_TYPE_ZR36060,
@@ -531,8 +541,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
 	}, {
 		.type = DC30plus,
 		.name = "DC30plus",
-		.vendor_id = PCI_VENDOR_ID_MIRO,
-		.device_id = PCI_DEVICE_ID_MIRO_DC30PLUS,
 		.i2c_decoder = I2C_DRIVERID_VPX3220,
 		.i2c_encoder = I2C_DRIVERID_ADV7175,
 		.video_codec = CODEC_TYPE_ZR36050,
@@ -589,8 +597,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
 	}, {
 		.type = LML33R10,
 		.name = "LML33R10",
-		.vendor_id = PCI_VENDOR_ID_ELECTRONICDESIGNGMBH,
-		.device_id = PCI_DEVICE_ID_LML_33R10,
 		.i2c_decoder = I2C_DRIVERID_SAA7114,
 		.i2c_encoder = I2C_DRIVERID_ADV7170,
 		.video_codec = CODEC_TYPE_ZR36060,
@@ -618,8 +624,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
 	}, {
 		.type = BUZ,
 		.name = "Buz",
-		.vendor_id = PCI_VENDOR_ID_IOMEGA,
-		.device_id = PCI_DEVICE_ID_IOMEGA_BUZ,
 		.i2c_decoder = I2C_DRIVERID_SAA7111A,
 		.i2c_encoder = I2C_DRIVERID_SAA7185B,
 		.video_codec = CODEC_TYPE_ZR36060,
@@ -649,8 +653,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
 		.name = "6-Eyes",
 		/* AverMedia chose not to brand the 6-Eyes. Thus it
 		   can't be autodetected, and requires card=x. */
-		.vendor_id = -1,
-		.device_id = -1,
 		.i2c_decoder = I2C_DRIVERID_KS0127,
 		.i2c_encoder = I2C_DRIVERID_BT866,
 		.video_codec = CODEC_TYPE_ZR36060,
@@ -1138,7 +1140,8 @@ zr36057_init (struct zoran *zr)
 	strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
 	err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
 	if (err < 0)
-		goto exit_unregister;
+		goto exit_free;
+	video_set_drvdata(zr->video_dev, zr);
 
 	zoran_init_hardware(zr);
 	if (zr36067_debug > 2)
@@ -1153,19 +1156,19 @@ zr36057_init (struct zoran *zr)
 	zr->initialized = 1;
 	return 0;
 
-exit_unregister:
-	zoran_unregister_i2c(zr);
 exit_free:
 	kfree(zr->stat_com);
 	kfree(zr->video_dev);
 	return err;
 }
 
-static void
-zoran_release (struct zoran *zr)
+static void __devexit zoran_remove(struct pci_dev *pdev)
 {
+	struct zoran *zr = pci_get_drvdata(pdev);
+
 	if (!zr->initialized)
 		goto exit_free;
+
 	/* unregister videocodec bus */
 	if (zr->codec) {
 		struct videocodec_master *master = zr->codec->master_data;
@@ -1194,6 +1197,7 @@ zoran_release (struct zoran *zr)
 	pci_disable_device(zr->pci_dev);
 	video_unregister_device(zr->video_dev);
 exit_free:
+	pci_set_drvdata(pdev, NULL);
 	kfree(zr);
 }
 
@@ -1256,338 +1260,329 @@ zoran_setup_videocodec (struct zoran *zr,
  *   Scan for a Buz card (actually for the PCI controller ZR36057),
  *   request the irq and map the io memory
  */
-static int __devinit
-find_zr36057 (void)
+static int __devinit zoran_probe(struct pci_dev *pdev,
+				 const struct pci_device_id *ent)
 {
 	unsigned char latency, need_latency;
 	struct zoran *zr;
-	struct pci_dev *dev = NULL;
 	int result;
 	struct videocodec_master *master_vfe = NULL;
 	struct videocodec_master *master_codec = NULL;
 	int card_num;
 	char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name;
+	unsigned int nr;
 
-	zoran_num = 0;
-	while (zoran_num < BUZ_MAX &&
-	       (dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) {
-		card_num = card[zoran_num];
-		zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
-		if (!zr) {
-			dprintk(1,
-				KERN_ERR
-				"%s: find_zr36057() - kzalloc failed\n",
-				ZORAN_NAME);
-			continue;
-		}
-		zr->pci_dev = dev;
-		//zr->zr36057_mem = NULL;
-		zr->id = zoran_num;
-		snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
-		spin_lock_init(&zr->spinlock);
-		mutex_init(&zr->resource_lock);
-		if (pci_enable_device(dev))
-			goto zr_free_mem;
-		zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0);
-		pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION,
-				     &zr->revision);
-		if (zr->revision < 2) {
-			dprintk(1,
-				KERN_INFO
-				"%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n",
-				ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
-				zr->zr36057_adr);
 
-			if (card_num == -1) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - no card specified, please use the card=X insmod option\n",
-					ZR_DEVNAME(zr));
-				goto zr_free_mem;
-			}
-		} else {
-			int i;
-			unsigned short ss_vendor, ss_device;
+	nr = zoran_num++;
+	if (nr >= BUZ_MAX) {
+		dprintk(1,
+			KERN_ERR
+			"%s: driver limited to %d card(s) maximum\n",
+			ZORAN_NAME, BUZ_MAX);
+		return -ENOENT;
+	}
 
-			ss_vendor = zr->pci_dev->subsystem_vendor;
-			ss_device = zr->pci_dev->subsystem_device;
+	zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
+	if (!zr) {
+		dprintk(1,
+			KERN_ERR
+			"%s: find_zr36057() - kzalloc failed\n",
+			ZORAN_NAME);
+		return -ENOMEM;
+	}
+	zr->pci_dev = pdev;
+	zr->id = nr;
+	snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
+	spin_lock_init(&zr->spinlock);
+	mutex_init(&zr->resource_lock);
+	if (pci_enable_device(pdev))
+		goto zr_free_mem;
+	pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
+
+	dprintk(1,
+		KERN_INFO
+		"%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n",
+		ZR_DEVNAME(zr), zr->revision < 2 ? '5' : '6', zr->revision,
+		zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0));
+	if (zr->revision >= 2) {
+		dprintk(1,
+			KERN_INFO
+			"%s: Subsystem vendor=0x%04x id=0x%04x\n",
+			ZR_DEVNAME(zr), zr->pci_dev->subsystem_vendor,
+			zr->pci_dev->subsystem_device);
+	}
+
+	/* Use auto-detected card type? */
+	if (card[nr] == -1) {
+		if (zr->revision < 2) {
 			dprintk(1,
-				KERN_INFO
-				"%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n",
-				ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
-				zr->zr36057_adr);
+				KERN_ERR
+				"%s: No card type specified, please use the card=X module parameter\n",
+				ZR_DEVNAME(zr));
 			dprintk(1,
-				KERN_INFO
-				"%s: subsystem vendor=0x%04x id=0x%04x\n",
-				ZR_DEVNAME(zr), ss_vendor, ss_device);
-			if (card_num == -1) {
-				dprintk(3,
-					KERN_DEBUG
-					"%s: find_zr36057() - trying to autodetect card type\n",
-					ZR_DEVNAME(zr));
-				for (i=0;i<NUM_CARDS;i++) {
-					if (ss_vendor == zoran_cards[i].vendor_id &&
-					    ss_device == zoran_cards[i].device_id) {
-						dprintk(3,
-							KERN_DEBUG
-							"%s: find_zr36057() - card %s detected\n",
-							ZR_DEVNAME(zr),
-							zoran_cards[i].name);
-						card_num = i;
-						break;
-					}
-				}
-				if (i == NUM_CARDS) {
-					dprintk(1,
-						KERN_ERR
-						"%s: find_zr36057() - unknown card\n",
-						ZR_DEVNAME(zr));
-					goto zr_free_mem;
-				}
-			}
-		}
-
-		if (card_num < 0 || card_num >= NUM_CARDS) {
-			dprintk(2,
 				KERN_ERR
-				"%s: find_zr36057() - invalid cardnum %d\n",
-				ZR_DEVNAME(zr), card_num);
+				"%s: It is not possible to auto-detect ZR36057 based cards\n",
+				ZR_DEVNAME(zr));
 			goto zr_free_mem;
 		}
 
-		/* even though we make this a non pointer and thus
-		 * theoretically allow for making changes to this struct
-		 * on a per-individual card basis at runtime, this is
-		 * strongly discouraged. This structure is intended to
-		 * keep general card information, no settings or anything */
-		zr->card = zoran_cards[card_num];
-		snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
-			 "%s[%u]", zr->card.name, zr->id);
-
-		zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000);
-		if (!zr->zr36057_mem) {
+		card_num = ent->driver_data;
+		if (card_num >= NUM_CARDS) {
 			dprintk(1,
 				KERN_ERR
-				"%s: find_zr36057() - ioremap failed\n",
+				"%s: Unknown card, try specifying card=X module parameter\n",
 				ZR_DEVNAME(zr));
 			goto zr_free_mem;
 		}
-
-		result = request_irq(zr->pci_dev->irq,
-				     zoran_irq,
-				     IRQF_SHARED | IRQF_DISABLED,
-				     ZR_DEVNAME(zr),
-				     (void *) zr);
-		if (result < 0) {
-			if (result == -EINVAL) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - bad irq number or handler\n",
-					ZR_DEVNAME(zr));
-			} else if (result == -EBUSY) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
-					ZR_DEVNAME(zr), zr->pci_dev->irq);
-			} else {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - can't assign irq, error code %d\n",
-					ZR_DEVNAME(zr), result);
-			}
-			goto zr_unmap;
-		}
-
-		/* set PCI latency timer */
-		pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
-				     &latency);
-		need_latency = zr->revision > 1 ? 32 : 48;
-		if (latency != need_latency) {
-			dprintk(2,
-				KERN_INFO
-				"%s: Changing PCI latency from %d to %d.\n",
-				ZR_DEVNAME(zr), latency, need_latency);
-			pci_write_config_byte(zr->pci_dev,
-					      PCI_LATENCY_TIMER,
-					      need_latency);
+		dprintk(3,
+			KERN_DEBUG
+			"%s: %s() - card %s detected\n",
+			ZR_DEVNAME(zr), __func__, zoran_cards[card_num].name);
+	} else {
+		card_num = card[nr];
+		if (card_num >= NUM_CARDS || card_num < 0) {
+			dprintk(1,
+				KERN_ERR
+				"%s: User specified card type %d out of range (0 .. %d)\n",
+				ZR_DEVNAME(zr), card_num, NUM_CARDS - 1);
+			goto zr_free_mem;
 		}
+	}
 
-		zr36057_restart(zr);
-		/* i2c */
-		dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
-			ZR_DEVNAME(zr));
+	/* even though we make this a non pointer and thus
+	 * theoretically allow for making changes to this struct
+	 * on a per-individual card basis at runtime, this is
+	 * strongly discouraged. This structure is intended to
+	 * keep general card information, no settings or anything */
+	zr->card = zoran_cards[card_num];
+	snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
+		 "%s[%u]", zr->card.name, zr->id);
+
+	zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0);
+	if (!zr->zr36057_mem) {
+		dprintk(1,
+			KERN_ERR
+			"%s: %s() - ioremap failed\n",
+			ZR_DEVNAME(zr), __func__);
+		goto zr_free_mem;
+	}
 
-		/* i2c decoder */
-		if (decoder[zr->id] != -1) {
-			i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
-			zr->card.i2c_decoder = decoder[zr->id];
-		} else if (zr->card.i2c_decoder != 0) {
-			i2c_dec_name =
-				i2cid_to_modulename(zr->card.i2c_decoder);
+	result = request_irq(zr->pci_dev->irq, zoran_irq,
+			     IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr);
+	if (result < 0) {
+		if (result == -EINVAL) {
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() - bad irq number or handler\n",
+				ZR_DEVNAME(zr));
+		} else if (result == -EBUSY) {
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
+				ZR_DEVNAME(zr), zr->pci_dev->irq);
 		} else {
-			i2c_dec_name = NULL;
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() - can't assign irq, error code %d\n",
+				ZR_DEVNAME(zr), result);
 		}
+		goto zr_unmap;
+	}
 
-		if (i2c_dec_name) {
-			if ((result = request_module(i2c_dec_name)) < 0) {
-				dprintk(1,
-					KERN_ERR
-					"%s: failed to load module %s: %d\n",
-					ZR_DEVNAME(zr), i2c_dec_name, result);
-			}
-		}
+	/* set PCI latency timer */
+	pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
+			     &latency);
+	need_latency = zr->revision > 1 ? 32 : 48;
+	if (latency != need_latency) {
+		dprintk(2,
+			KERN_INFO
+			"%s: Changing PCI latency from %d to %d\n",
+			ZR_DEVNAME(zr), latency, need_latency);
+		pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
+				      need_latency);
+	}
 
-		/* i2c encoder */
-		if (encoder[zr->id] != -1) {
-			i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
-			zr->card.i2c_encoder = encoder[zr->id];
-		} else if (zr->card.i2c_encoder != 0) {
-			i2c_enc_name =
-				i2cid_to_modulename(zr->card.i2c_encoder);
-		} else {
-			i2c_enc_name = NULL;
-		}
+	zr36057_restart(zr);
+	/* i2c */
+	dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
+		ZR_DEVNAME(zr));
+
+	/* i2c decoder */
+	if (decoder[zr->id] != -1) {
+		i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
+		zr->card.i2c_decoder = decoder[zr->id];
+	} else if (zr->card.i2c_decoder != 0) {
+		i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder);
+	} else {
+		i2c_dec_name = NULL;
+	}
 
-		if (i2c_enc_name) {
-			if ((result = request_module(i2c_enc_name)) < 0) {
-				dprintk(1,
-					KERN_ERR
-					"%s: failed to load module %s: %d\n",
-					ZR_DEVNAME(zr), i2c_enc_name, result);
-			}
+	if (i2c_dec_name) {
+		result = request_module(i2c_dec_name);
+		if (result < 0) {
+			dprintk(1,
+				KERN_ERR
+				"%s: failed to load module %s: %d\n",
+				ZR_DEVNAME(zr), i2c_dec_name, result);
 		}
+	}
+
+	/* i2c encoder */
+	if (encoder[zr->id] != -1) {
+		i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
+		zr->card.i2c_encoder = encoder[zr->id];
+	} else if (zr->card.i2c_encoder != 0) {
+		i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder);
+	} else {
+		i2c_enc_name = NULL;
+	}
 
-		if (zoran_register_i2c(zr) < 0) {
+	if (i2c_enc_name) {
+		result = request_module(i2c_enc_name);
+		if (result < 0) {
 			dprintk(1,
 				KERN_ERR
-				"%s: find_zr36057() - can't initialize i2c bus\n",
-				ZR_DEVNAME(zr));
-			goto zr_free_irq;
+				"%s: failed to load module %s: %d\n",
+				ZR_DEVNAME(zr), i2c_enc_name, result);
 		}
+	}
 
-		dprintk(2,
-			KERN_INFO "%s: Initializing videocodec bus...\n",
+	if (zoran_register_i2c(zr) < 0) {
+		dprintk(1,
+			KERN_ERR
+			"%s: find_zr36057() - can't initialize i2c bus\n",
 			ZR_DEVNAME(zr));
+		goto zr_free_irq;
+	}
 
-		if (zr->card.video_codec != 0 &&
-		    (codec_name =
-		     codecid_to_modulename(zr->card.video_codec)) != NULL) {
-			if ((result = request_module(codec_name)) < 0) {
+	dprintk(2,
+		KERN_INFO "%s: Initializing videocodec bus...\n",
+		ZR_DEVNAME(zr));
+
+	if (zr->card.video_codec) {
+		codec_name = codecid_to_modulename(zr->card.video_codec);
+		if (codec_name) {
+			result = request_module(codec_name);
+			if (result) {
 				dprintk(1,
 					KERN_ERR
 					"%s: failed to load modules %s: %d\n",
 					ZR_DEVNAME(zr), codec_name, result);
 			}
 		}
-		if (zr->card.video_vfe != 0 &&
-		    (vfe_name =
-		     codecid_to_modulename(zr->card.video_vfe)) != NULL) {
-			if ((result = request_module(vfe_name)) < 0) {
+	}
+	if (zr->card.video_vfe) {
+		vfe_name = codecid_to_modulename(zr->card.video_vfe);
+		if (vfe_name) {
+			result = request_module(vfe_name);
+			if (result < 0) {
 				dprintk(1,
 					KERN_ERR
 					"%s: failed to load modules %s: %d\n",
 					ZR_DEVNAME(zr), vfe_name, result);
 			}
 		}
+	}
 
-		/* reset JPEG codec */
-		jpeg_codec_sleep(zr, 1);
-		jpeg_codec_reset(zr);
-		/* video bus enabled */
-		/* display codec revision */
-		if (zr->card.video_codec != 0) {
-			master_codec = zoran_setup_videocodec(zr,
-							      zr->card.video_codec);
-			if (!master_codec)
-				goto zr_unreg_i2c;
-			zr->codec = videocodec_attach(master_codec);
-			if (!zr->codec) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - no codec found\n",
-					ZR_DEVNAME(zr));
-				goto zr_free_codec;
-			}
-			if (zr->codec->type != zr->card.video_codec) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - wrong codec\n",
-					ZR_DEVNAME(zr));
-				goto zr_detach_codec;
-			}
+	/* reset JPEG codec */
+	jpeg_codec_sleep(zr, 1);
+	jpeg_codec_reset(zr);
+	/* video bus enabled */
+	/* display codec revision */
+	if (zr->card.video_codec != 0) {
+		master_codec = zoran_setup_videocodec(zr, zr->card.video_codec);
+		if (!master_codec)
+			goto zr_unreg_i2c;
+		zr->codec = videocodec_attach(master_codec);
+		if (!zr->codec) {
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() - no codec found\n",
+				ZR_DEVNAME(zr));
+			goto zr_free_codec;
 		}
-		if (zr->card.video_vfe != 0) {
-			master_vfe = zoran_setup_videocodec(zr,
-							    zr->card.video_vfe);
-			if (!master_vfe)
-				goto zr_detach_codec;
-			zr->vfe = videocodec_attach(master_vfe);
-			if (!zr->vfe) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - no VFE found\n",
-					ZR_DEVNAME(zr));
-				goto zr_free_vfe;
-			}
-			if (zr->vfe->type != zr->card.video_vfe) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() = wrong VFE\n",
-					ZR_DEVNAME(zr));
-				goto zr_detach_vfe;
-			}
+		if (zr->codec->type != zr->card.video_codec) {
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() - wrong codec\n",
+				ZR_DEVNAME(zr));
+			goto zr_detach_codec;
+		}
+	}
+	if (zr->card.video_vfe != 0) {
+		master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe);
+		if (!master_vfe)
+			goto zr_detach_codec;
+		zr->vfe = videocodec_attach(master_vfe);
+		if (!zr->vfe) {
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() - no VFE found\n",
+				ZR_DEVNAME(zr));
+			goto zr_free_vfe;
+		}
+		if (zr->vfe->type != zr->card.video_vfe) {
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() = wrong VFE\n",
+				ZR_DEVNAME(zr));
+			goto zr_detach_vfe;
 		}
-		/* Success so keep the pci_dev referenced */
-		pci_dev_get(zr->pci_dev);
-		zoran[zoran_num++] = zr;
-		continue;
-
-		// Init errors
-	      zr_detach_vfe:
-		videocodec_detach(zr->vfe);
-	      zr_free_vfe:
-		kfree(master_vfe);
-	      zr_detach_codec:
-		videocodec_detach(zr->codec);
-	      zr_free_codec:
-		kfree(master_codec);
-	      zr_unreg_i2c:
-		zoran_unregister_i2c(zr);
-	      zr_free_irq:
-		btwrite(0, ZR36057_SPGPPCR);
-		free_irq(zr->pci_dev->irq, zr);
-	      zr_unmap:
-		iounmap(zr->zr36057_mem);
-	      zr_free_mem:
-		kfree(zr);
-		continue;
 	}
-	if (dev)	/* Clean up ref count on early exit */
-		pci_dev_put(dev);
 
-	if (zoran_num == 0) {
-		dprintk(1, KERN_INFO "No known MJPEG cards found.\n");
+	/* take care of Natoma chipset and a revision 1 zr36057 */
+	if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
+		zr->jpg_buffers.need_contiguous = 1;
+		dprintk(1,
+			KERN_INFO
+			"%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
+			ZR_DEVNAME(zr));
 	}
-	return zoran_num;
+
+	if (zr36057_init(zr) < 0)
+		goto zr_detach_vfe;
+
+	zoran_proc_init(zr);
+
+	pci_set_drvdata(pdev, zr);
+
+	return 0;
+
+zr_detach_vfe:
+	videocodec_detach(zr->vfe);
+zr_free_vfe:
+	kfree(master_vfe);
+zr_detach_codec:
+	videocodec_detach(zr->codec);
+zr_free_codec:
+	kfree(master_codec);
+zr_unreg_i2c:
+	zoran_unregister_i2c(zr);
+zr_free_irq:
+	btwrite(0, ZR36057_SPGPPCR);
+	free_irq(zr->pci_dev->irq, zr);
+zr_unmap:
+	iounmap(zr->zr36057_mem);
+zr_free_mem:
+	kfree(zr);
+
+	return -ENODEV;
 }
 
-static int __init
-init_dc10_cards (void)
+static struct pci_driver zoran_driver = {
+	.name = "zr36067",
+	.id_table = zr36067_pci_tbl,
+	.probe = zoran_probe,
+	.remove = zoran_remove,
+};
+
+static int __init zoran_init(void)
 {
-	int i;
+	int res;
 
-	memset(zoran, 0, sizeof(zoran));
 	printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n",
 	       MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION);
 
-	/* Look for cards */
-	if (find_zr36057() < 0) {
-		return -EIO;
-	}
-	if (zoran_num == 0)
-		return -ENODEV;
-	dprintk(1, KERN_INFO "%s: %d card(s) found\n", ZORAN_NAME,
-		zoran_num);
 	/* check the parameters we have been given, adjust if necessary */
 	if (v4l_nbufs < 2)
 		v4l_nbufs = 2;
@@ -1629,37 +1624,22 @@ init_dc10_cards (void)
 			ZORAN_NAME);
 	}
 
-	/* take care of Natoma chipset and a revision 1 zr36057 */
-	for (i = 0; i < zoran_num; i++) {
-		struct zoran *zr = zoran[i];
-
-		if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
-			zr->jpg_buffers.need_contiguous = 1;
-			dprintk(1,
-				KERN_INFO
-				"%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
-				ZR_DEVNAME(zr));
-		}
-
-		if (zr36057_init(zr) < 0) {
-			for (i = 0; i < zoran_num; i++)
-				zoran_release(zoran[i]);
-			return -EIO;
-		}
-		zoran_proc_init(zr);
+	res = pci_register_driver(&zoran_driver);
+	if (res) {
+		dprintk(1,
+			KERN_ERR
+			"%s: Unable to register ZR36057 driver\n",
+			ZORAN_NAME);
+		return res;
 	}
 
 	return 0;
 }
 
-static void __exit
-unload_dc10_cards (void)
+static void __exit zoran_exit(void)
 {
-	int i;
-
-	for (i = 0; i < zoran_num; i++)
-		zoran_release(zoran[i]);
+	pci_unregister_driver(&zoran_driver);
 }
 
-module_init(init_dc10_cards);
-module_exit(unload_dc10_cards);
+module_init(zoran_init);
+module_exit(zoran_exit);
diff --git a/drivers/media/video/zoran/zoran_card.h b/drivers/media/video/zoran/zoran_card.h
index e4dc9d29b404..4507bdc5e338 100644
--- a/drivers/media/video/zoran/zoran_card.h
+++ b/drivers/media/video/zoran/zoran_card.h
@@ -40,8 +40,6 @@ extern int zr36067_debug;
 
 /* Anybody who uses more than four? */
 #define BUZ_MAX 4
-extern int zoran_num;
-extern struct zoran *zoran[BUZ_MAX];
 
 extern struct video_device zoran_template;
 
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index b58b9dda715c..120ef235e63d 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -1196,83 +1196,54 @@ zoran_close_end_session (struct file *file)
  *   Open a zoran card. Right now the flags stuff is just playing
  */
 
-static int
-zoran_open(struct file  *file)
+static int zoran_open(struct file *file)
 {
-	unsigned int minor = video_devdata(file)->minor;
-	struct zoran *zr = NULL;
+	struct zoran *zr = video_drvdata(file);
 	struct zoran_fh *fh;
-	int i, res, first_open = 0, have_module_locks = 0;
+	int res, first_open = 0;
 
-	lock_kernel();
-	/* find the device */
-	for (i = 0; i < zoran_num; i++) {
-		if (zoran[i]->video_dev->minor == minor) {
-			zr = zoran[i];
-			break;
-		}
-	}
+	dprintk(2, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
+		ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user + 1);
 
-	if (!zr) {
-		dprintk(1, KERN_ERR "%s: device not found!\n", ZORAN_NAME);
-		res = -ENODEV;
-		goto open_unlock_and_return;
-	}
+	lock_kernel();
 
 	/* see fs/device.c - the kernel already locks during open(),
 	 * so locking ourselves only causes deadlocks */
 	/*mutex_lock(&zr->resource_lock);*/
 
+	if (zr->user >= 2048) {
+		dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
+			ZR_DEVNAME(zr), zr->user);
+		res = -EBUSY;
+		goto fail_unlock;
+	}
+
 	if (!zr->decoder) {
 		dprintk(1,
 			KERN_ERR "%s: no TV decoder loaded for device!\n",
 			ZR_DEVNAME(zr));
 		res = -EIO;
-		goto open_unlock_and_return;
+		goto fail_unlock;
 	}
 
-	/* try to grab a module lock */
-	if (!try_module_get(THIS_MODULE)) {
-		dprintk(1,
-			KERN_ERR
-			"%s: failed to acquire my own lock! PANIC!\n",
-			ZR_DEVNAME(zr));
-		res = -ENODEV;
-		goto open_unlock_and_return;
-	}
 	if (!try_module_get(zr->decoder->driver->driver.owner)) {
 		dprintk(1,
 			KERN_ERR
-			"%s: failed to grab ownership of i2c decoder\n",
+			"%s: failed to grab ownership of video decoder\n",
 			ZR_DEVNAME(zr));
 		res = -EIO;
-		module_put(THIS_MODULE);
-		goto open_unlock_and_return;
+		goto fail_unlock;
 	}
 	if (zr->encoder &&
 	    !try_module_get(zr->encoder->driver->driver.owner)) {
 		dprintk(1,
 			KERN_ERR
-			"%s: failed to grab ownership of i2c encoder\n",
+			"%s: failed to grab ownership of video encoder\n",
 			ZR_DEVNAME(zr));
 		res = -EIO;
-		module_put(zr->decoder->driver->driver.owner);
-		module_put(THIS_MODULE);
-		goto open_unlock_and_return;
+		goto fail_decoder;
 	}
 
-	have_module_locks = 1;
-
-	if (zr->user >= 2048) {
-		dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
-			ZR_DEVNAME(zr), zr->user);
-		res = -EBUSY;
-		goto open_unlock_and_return;
-	}
-
-	dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
-		ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
-
 	/* now, create the open()-specific file_ops struct */
 	fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
 	if (!fh) {
@@ -1281,7 +1252,7 @@ zoran_open(struct file  *file)
 			"%s: zoran_open() - allocation of zoran_fh failed\n",
 			ZR_DEVNAME(zr));
 		res = -ENOMEM;
-		goto open_unlock_and_return;
+		goto fail_encoder;
 	}
 	/* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows
 	 * on norm-change! */
@@ -1292,9 +1263,8 @@ zoran_open(struct file  *file)
 			KERN_ERR
 			"%s: zoran_open() - allocation of overlay_mask failed\n",
 			ZR_DEVNAME(zr));
-		kfree(fh);
 		res = -ENOMEM;
-		goto open_unlock_and_return;
+		goto fail_fh;
 	}
 
 	if (zr->user++ == 0)
@@ -1319,22 +1289,19 @@ zoran_open(struct file  *file)
 
 	return 0;
 
-open_unlock_and_return:
-	/* if we grabbed locks, release them accordingly */
-	if (have_module_locks) {
-		module_put(zr->decoder->driver->driver.owner);
-		if (zr->encoder) {
-			module_put(zr->encoder->driver->driver.owner);
-		}
-		module_put(THIS_MODULE);
-	}
-
-	/* if there's no device found, we didn't obtain the lock either */
-	if (zr) {
-		/*mutex_unlock(&zr->resource_lock);*/
-	}
+fail_fh:
+	kfree(fh);
+fail_encoder:
+	if (zr->encoder)
+		module_put(zr->encoder->driver->driver.owner);
+fail_decoder:
+	module_put(zr->decoder->driver->driver.owner);
+fail_unlock:
 	unlock_kernel();
 
+	dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n",
+		ZR_DEVNAME(zr), res, zr->user);
+
 	return res;
 }
 
@@ -1344,8 +1311,8 @@ zoran_close(struct file  *file)
 	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 
-	dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
-		ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
+	dprintk(2, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
+		ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user - 1);
 
 	/* kernel locks (fs/device.c), so don't do that ourselves
 	 * (prevents deadlocks) */
@@ -1391,10 +1358,8 @@ zoran_close(struct file  *file)
 
 	/* release locks on the i2c modules */
 	module_put(zr->decoder->driver->driver.owner);
-	if (zr->encoder) {
-		 module_put(zr->encoder->driver->driver.owner);
-	}
-	module_put(THIS_MODULE);
+	if (zr->encoder)
+		module_put(zr->encoder->driver->driver.owner);
 
 	/*mutex_unlock(&zr->resource_lock);*/
 
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 24508e28e3fb..ea9488e7ad6d 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -626,7 +626,6 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
 	}
 
 	if (client->irq) {
-		set_irq_handler(client->irq, handle_level_irq);
 		ret = request_irq(client->irq, pcf50633_irq,
 				IRQF_TRIGGER_LOW, "pcf50633", pcf);
 
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 396d935012f2..1c484084ed4f 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -217,6 +217,7 @@ config DELL_LAPTOP
 	depends on EXPERIMENTAL
 	depends on BACKLIGHT_CLASS_DEVICE
 	depends on RFKILL
+	depends on POWER_SUPPLY
 	default n
 	---help---
 	This driver adds support for rfkill and backlight control to Dell
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
index bf5e4d065436..558bf3f2c276 100644
--- a/drivers/misc/atmel-ssc.c
+++ b/drivers/misc/atmel-ssc.c
@@ -35,7 +35,7 @@ struct ssc_device *ssc_request(unsigned int ssc_num)
 
 	if (!ssc_valid) {
 		spin_unlock(&user_lock);
-		dev_dbg(&ssc->pdev->dev, "could not find requested device\n");
+		pr_err("ssc: ssc%d platform device is missing\n", ssc_num);
 		return ERR_PTR(-ENODEV);
 	}
 
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
index 10c421b73eaf..f26667a7abf7 100644
--- a/drivers/misc/hpilo.c
+++ b/drivers/misc/hpilo.c
@@ -207,7 +207,7 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data)
 		  &device_ccb->recv_ctrl);
 
 	/* give iLO some time to process stop request */
-	for (retries = 1000; retries > 0; retries--) {
+	for (retries = MAX_WAIT; retries > 0; retries--) {
 		doorbell_set(driver_ccb);
 		udelay(1);
 		if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A))
@@ -309,7 +309,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
 	doorbell_clr(driver_ccb);
 
 	/* make sure iLO is really handling requests */
-	for (i = 1000; i > 0; i--) {
+	for (i = MAX_WAIT; i > 0; i--) {
 		if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL))
 			break;
 		udelay(1);
@@ -326,7 +326,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
 
 	return 0;
 free:
-	pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa);
+	ilo_ccb_close(pdev, data);
 out:
 	return error;
 }
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h
index a281207696c1..b64a20ef07e3 100644
--- a/drivers/misc/hpilo.h
+++ b/drivers/misc/hpilo.h
@@ -19,6 +19,8 @@
 #define MAX_ILO_DEV	1
 /* max number of files */
 #define MAX_OPEN	(MAX_CCB * MAX_ILO_DEV)
+/* spin counter for open/close delay */
+#define MAX_WAIT	10000
 
 /*
  * Per device, used to track global memory allocations.
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
index a5bd658c2e83..275b78896a73 100644
--- a/drivers/misc/sgi-xp/xpc.h
+++ b/drivers/misc/sgi-xp/xpc.h
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2004-2008 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2004-2009 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 /*
@@ -514,7 +514,8 @@ struct xpc_channel_uv {
 						/* partition's notify mq */
 
 	struct xpc_send_msg_slot_uv *send_msg_slots;
-	struct xpc_notify_mq_msg_uv *recv_msg_slots;
+	void *recv_msg_slots;	/* each slot will hold a xpc_notify_mq_msg_uv */
+				/* structure plus the user's payload */
 
 	struct xpc_fifo_head_uv msg_slot_free_list;
 	struct xpc_fifo_head_uv recv_msg_list;	/* deliverable payloads */
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
index f17f7d40ea2c..29c0502a96b2 100644
--- a/drivers/misc/sgi-xp/xpc_uv.c
+++ b/drivers/misc/sgi-xp/xpc_uv.c
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2008-2009 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 /*
@@ -1010,8 +1010,8 @@ xpc_allocate_recv_msg_slot_uv(struct xpc_channel *ch)
 			continue;
 
 		for (entry = 0; entry < nentries; entry++) {
-			msg_slot = ch_uv->recv_msg_slots + entry *
-			    ch->entry_size;
+			msg_slot = ch_uv->recv_msg_slots +
+			    entry * ch->entry_size;
 
 			msg_slot->hdr.msg_slot_number = entry;
 		}
@@ -1308,9 +1308,8 @@ xpc_handle_notify_mq_msg_uv(struct xpc_partition *part,
 	/* we're dealing with a normal message sent via the notify_mq */
 	ch_uv = &ch->sn.uv;
 
-	msg_slot = (struct xpc_notify_mq_msg_uv *)((u64)ch_uv->recv_msg_slots +
-		    (msg->hdr.msg_slot_number % ch->remote_nentries) *
-		    ch->entry_size);
+	msg_slot = ch_uv->recv_msg_slots +
+	    (msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size;
 
 	BUG_ON(msg->hdr.msg_slot_number != msg_slot->hdr.msg_slot_number);
 	BUG_ON(msg_slot->hdr.size != 0);
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c
index 7957f525b2f4..6faefcffcb53 100644
--- a/drivers/misc/sgi-xp/xpnet.c
+++ b/drivers/misc/sgi-xp/xpnet.c
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1999-2008 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1999-2009 Silicon Graphics, Inc. All rights reserved.
  */
 
 /*
@@ -551,6 +551,7 @@ xpnet_init(void)
 
 	netif_carrier_off(xpnet_device);
 
+	xpnet_device->netdev_ops = &xpnet_netdev_ops;
 	xpnet_device->mtu = XPNET_DEF_MTU;
 
 	/*
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 0efa390978bd..99d4b28d52ed 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -145,6 +145,16 @@ config MMC_IMX
 
 	  If unsure, say N.
 
+config MMC_MXC
+	tristate "Freescale i.MX2/3 Multimedia Card Interface support"
+	depends on ARCH_MXC
+	help
+	  This selects the Freescale i.MX2/3 Multimedia card Interface.
+	  If you have a i.MX platform with a Multimedia Card slot,
+	  say Y or M here.
+
+	  If unsure, say N.
+
 config MMC_TIFM_SD
 	tristate "TI Flash Media MMC/SD Interface support  (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 98cab84829b8..dedec55861d9 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -9,6 +9,7 @@ endif
 obj-$(CONFIG_MMC_ARMMMCI)	+= mmci.o
 obj-$(CONFIG_MMC_PXA)		+= pxamci.o
 obj-$(CONFIG_MMC_IMX)		+= imxmmc.o
+obj-$(CONFIG_MMC_MXC)		+= mxcmmc.o
 obj-$(CONFIG_MMC_SDHCI)		+= sdhci.o
 obj-$(CONFIG_MMC_SDHCI_PCI)	+= sdhci-pci.o
 obj-$(CONFIG_MMC_RICOH_MMC)	+= ricoh_mmc.o
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 1bcbdd6763ac..2909bbc8ad00 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -430,6 +430,8 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 				clk = 255;
 			host->cclk = host->mclk / (2 * (clk + 1));
 		}
+		if (host->hw_designer == 0x80)
+			clk |= MCI_FCEN; /* Bug fix in ST IP block */
 		clk |= MCI_CLK_ENABLE;
 	}
 
@@ -440,15 +442,27 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	case MMC_POWER_OFF:
 		break;
 	case MMC_POWER_UP:
-		pwr |= MCI_PWR_UP;
-		break;
+		/* The ST version does not have this, fall through to POWER_ON */
+		if (host->hw_designer != 0x80) {
+			pwr |= MCI_PWR_UP;
+			break;
+		}
 	case MMC_POWER_ON:
 		pwr |= MCI_PWR_ON;
 		break;
 	}
 
-	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
-		pwr |= MCI_ROD;
+	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
+		if (host->hw_designer != 0x80)
+			pwr |= MCI_ROD;
+		else {
+			/*
+			 * The ST Micro variant use the ROD bit for something
+			 * else and only has OD (Open Drain).
+			 */
+			pwr |= MCI_OD;
+		}
+	}
 
 	writel(clk, host->base + MMCICLOCK);
 
@@ -500,6 +514,12 @@ static int mmci_probe(struct amba_device *dev, void *id)
 	}
 
 	host = mmc_priv(mmc);
+	/* Bits 12 thru 19 is the designer */
+	host->hw_designer = (dev->periphid >> 12) & 0xff;
+	/* Bits 20 thru 23 is the revison */
+	host->hw_revision = (dev->periphid >> 20) & 0xf;
+	DBG(host, "designer ID = 0x%02x\n", host->hw_designer);
+	DBG(host, "revision = 0x%01x\n", host->hw_revision);
 	host->clk = clk_get(&dev->dev, NULL);
 	if (IS_ERR(host->clk)) {
 		ret = PTR_ERR(host->clk);
@@ -693,6 +713,15 @@ static struct amba_id mmci_ids[] = {
 		.id	= 0x00041181,
 		.mask	= 0x000fffff,
 	},
+	/* ST Micro variants */
+	{
+		.id     = 0x00180180,
+		.mask   = 0x00ffffff,
+	},
+	{
+		.id     = 0x00280180,
+		.mask   = 0x00ffffff,
+	},
 	{ 0, 0 },
 };
 
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 0f39c490f022..0441bac1c0ec 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -11,13 +11,23 @@
 #define MCI_PWR_OFF		0x00
 #define MCI_PWR_UP		0x02
 #define MCI_PWR_ON		0x03
+#define MCI_DATA2DIREN		(1 << 2)
+#define MCI_CMDDIREN		(1 << 3)
+#define MCI_DATA0DIREN		(1 << 4)
+#define MCI_DATA31DIREN		(1 << 5)
 #define MCI_OD			(1 << 6)
 #define MCI_ROD			(1 << 7)
+/* The ST Micro version does not have ROD */
+#define MCI_FBCLKEN		(1 << 7)
+#define MCI_DATA74DIREN		(1 << 8)
 
 #define MMCICLOCK		0x004
 #define MCI_CLK_ENABLE		(1 << 8)
 #define MCI_CLK_PWRSAVE		(1 << 9)
 #define MCI_CLK_BYPASS		(1 << 10)
+#define MCI_WIDE_BUS		(1 << 11)
+/* HW flow control on the ST Micro version */
+#define MCI_FCEN		(1 << 13)
 
 #define MMCIARGUMENT		0x008
 #define MMCICOMMAND		0x00c
@@ -26,6 +36,10 @@
 #define MCI_CPSM_INTERRUPT	(1 << 8)
 #define MCI_CPSM_PENDING	(1 << 9)
 #define MCI_CPSM_ENABLE		(1 << 10)
+#define MCI_SDIO_SUSP		(1 << 11)
+#define MCI_ENCMD_COMPL		(1 << 12)
+#define MCI_NIEN		(1 << 13)
+#define MCI_CE_ATACMD		(1 << 14)
 
 #define MMCIRESPCMD		0x010
 #define MMCIRESPONSE0		0x014
@@ -39,6 +53,11 @@
 #define MCI_DPSM_DIRECTION	(1 << 1)
 #define MCI_DPSM_MODE		(1 << 2)
 #define MCI_DPSM_DMAENABLE	(1 << 3)
+#define MCI_DPSM_BLOCKSIZE	(1 << 4)
+#define MCI_DPSM_RWSTART	(1 << 8)
+#define MCI_DPSM_RWSTOP		(1 << 9)
+#define MCI_DPSM_RWMOD		(1 << 10)
+#define MCI_DPSM_SDIOEN		(1 << 11)
 
 #define MMCIDATACNT		0x030
 #define MMCISTATUS		0x034
@@ -63,6 +82,8 @@
 #define MCI_RXFIFOEMPTY		(1 << 19)
 #define MCI_TXDATAAVLBL		(1 << 20)
 #define MCI_RXDATAAVLBL		(1 << 21)
+#define MCI_SDIOIT		(1 << 22)
+#define MCI_CEATAEND		(1 << 23)
 
 #define MMCICLEAR		0x038
 #define MCI_CMDCRCFAILCLR	(1 << 0)
@@ -75,6 +96,8 @@
 #define MCI_CMDSENTCLR		(1 << 7)
 #define MCI_DATAENDCLR		(1 << 8)
 #define MCI_DATABLOCKENDCLR	(1 << 10)
+#define MCI_SDIOITC		(1 << 22)
+#define MCI_CEATAENDC		(1 << 23)
 
 #define MMCIMASK0		0x03c
 #define MCI_CMDCRCFAILMASK	(1 << 0)
@@ -98,6 +121,8 @@
 #define MCI_RXFIFOEMPTYMASK	(1 << 19)
 #define MCI_TXDATAAVLBLMASK	(1 << 20)
 #define MCI_RXDATAAVLBLMASK	(1 << 21)
+#define MCI_SDIOITMASK		(1 << 22)
+#define MCI_CEATAENDMASK	(1 << 23)
 
 #define MMCIMASK1		0x040
 #define MMCIFIFOCNT		0x048
@@ -136,6 +161,9 @@ struct mmci_host {
 	u32			pwr;
 	struct mmc_platform_data *plat;
 
+	u8			hw_designer;
+	u8			hw_revision:4;
+
 	struct timer_list	timer;
 	unsigned int		oldstat;
 
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
new file mode 100644
index 000000000000..dda0be4e25dc
--- /dev/null
+++ b/drivers/mmc/host/mxcmmc.c
@@ -0,0 +1,880 @@
+/*
+ *  linux/drivers/mmc/host/mxcmmc.c - Freescale i.MX MMCI driver
+ *
+ *  This is a driver for the SDHC controller found in Freescale MX2/MX3
+ *  SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
+ *  Unlike the hardware found on MX1, this hardware just works and does
+ *  not need all the quirks found in imxmmc.c, hence the seperate driver.
+ *
+ *  Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *  Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
+ *
+ *  derived from pxamci.c by 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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/blkdev.h>
+#include <linux/dma-mapping.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <mach/mmc.h>
+
+#ifdef CONFIG_ARCH_MX2
+#include <mach/dma-mx1-mx2.h>
+#define HAS_DMA
+#endif
+
+#define DRIVER_NAME "imx-mmc"
+
+#define MMC_REG_STR_STP_CLK		0x00
+#define MMC_REG_STATUS			0x04
+#define MMC_REG_CLK_RATE		0x08
+#define MMC_REG_CMD_DAT_CONT		0x0C
+#define MMC_REG_RES_TO			0x10
+#define MMC_REG_READ_TO			0x14
+#define MMC_REG_BLK_LEN			0x18
+#define MMC_REG_NOB			0x1C
+#define MMC_REG_REV_NO			0x20
+#define MMC_REG_INT_CNTR		0x24
+#define MMC_REG_CMD			0x28
+#define MMC_REG_ARG			0x2C
+#define MMC_REG_RES_FIFO		0x34
+#define MMC_REG_BUFFER_ACCESS		0x38
+
+#define STR_STP_CLK_RESET               (1 << 3)
+#define STR_STP_CLK_START_CLK           (1 << 1)
+#define STR_STP_CLK_STOP_CLK            (1 << 0)
+
+#define STATUS_CARD_INSERTION		(1 << 31)
+#define STATUS_CARD_REMOVAL		(1 << 30)
+#define STATUS_YBUF_EMPTY		(1 << 29)
+#define STATUS_XBUF_EMPTY		(1 << 28)
+#define STATUS_YBUF_FULL		(1 << 27)
+#define STATUS_XBUF_FULL		(1 << 26)
+#define STATUS_BUF_UND_RUN		(1 << 25)
+#define STATUS_BUF_OVFL			(1 << 24)
+#define STATUS_SDIO_INT_ACTIVE		(1 << 14)
+#define STATUS_END_CMD_RESP		(1 << 13)
+#define STATUS_WRITE_OP_DONE		(1 << 12)
+#define STATUS_DATA_TRANS_DONE		(1 << 11)
+#define STATUS_READ_OP_DONE		(1 << 11)
+#define STATUS_WR_CRC_ERROR_CODE_MASK	(3 << 10)
+#define STATUS_CARD_BUS_CLK_RUN		(1 << 8)
+#define STATUS_BUF_READ_RDY		(1 << 7)
+#define STATUS_BUF_WRITE_RDY		(1 << 6)
+#define STATUS_RESP_CRC_ERR		(1 << 5)
+#define STATUS_CRC_READ_ERR		(1 << 3)
+#define STATUS_CRC_WRITE_ERR		(1 << 2)
+#define STATUS_TIME_OUT_RESP		(1 << 1)
+#define STATUS_TIME_OUT_READ		(1 << 0)
+#define STATUS_ERR_MASK			0x2f
+
+#define CMD_DAT_CONT_CMD_RESP_LONG_OFF	(1 << 12)
+#define CMD_DAT_CONT_STOP_READWAIT	(1 << 11)
+#define CMD_DAT_CONT_START_READWAIT	(1 << 10)
+#define CMD_DAT_CONT_BUS_WIDTH_4	(2 << 8)
+#define CMD_DAT_CONT_INIT		(1 << 7)
+#define CMD_DAT_CONT_WRITE		(1 << 4)
+#define CMD_DAT_CONT_DATA_ENABLE	(1 << 3)
+#define CMD_DAT_CONT_RESPONSE_48BIT_CRC	(1 << 0)
+#define CMD_DAT_CONT_RESPONSE_136BIT	(2 << 0)
+#define CMD_DAT_CONT_RESPONSE_48BIT	(3 << 0)
+
+#define INT_SDIO_INT_WKP_EN		(1 << 18)
+#define INT_CARD_INSERTION_WKP_EN	(1 << 17)
+#define INT_CARD_REMOVAL_WKP_EN		(1 << 16)
+#define INT_CARD_INSERTION_EN		(1 << 15)
+#define INT_CARD_REMOVAL_EN		(1 << 14)
+#define INT_SDIO_IRQ_EN			(1 << 13)
+#define INT_DAT0_EN			(1 << 12)
+#define INT_BUF_READ_EN			(1 << 4)
+#define INT_BUF_WRITE_EN		(1 << 3)
+#define INT_END_CMD_RES_EN		(1 << 2)
+#define INT_WRITE_OP_DONE_EN		(1 << 1)
+#define INT_READ_OP_EN			(1 << 0)
+
+struct mxcmci_host {
+	struct mmc_host		*mmc;
+	struct resource		*res;
+	void __iomem		*base;
+	int			irq;
+	int			detect_irq;
+	int			dma;
+	int			do_dma;
+	unsigned int		power_mode;
+	struct imxmmc_platform_data *pdata;
+
+	struct mmc_request	*req;
+	struct mmc_command	*cmd;
+	struct mmc_data		*data;
+
+	unsigned int		dma_nents;
+	unsigned int		datasize;
+	unsigned int		dma_dir;
+
+	u16			rev_no;
+	unsigned int		cmdat;
+
+	struct clk		*clk;
+
+	int			clock;
+
+	struct work_struct	datawork;
+};
+
+static inline int mxcmci_use_dma(struct mxcmci_host *host)
+{
+	return host->do_dma;
+}
+
+static void mxcmci_softreset(struct mxcmci_host *host)
+{
+	int i;
+
+	/* reset sequence */
+	writew(STR_STP_CLK_RESET, host->base + MMC_REG_STR_STP_CLK);
+	writew(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
+			host->base + MMC_REG_STR_STP_CLK);
+
+	for (i = 0; i < 8; i++)
+		writew(STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK);
+
+	writew(0xff, host->base + MMC_REG_RES_TO);
+}
+
+static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
+{
+	unsigned int nob = data->blocks;
+	unsigned int blksz = data->blksz;
+	unsigned int datasize = nob * blksz;
+#ifdef HAS_DMA
+	struct scatterlist *sg;
+	int i;
+#endif
+	if (data->flags & MMC_DATA_STREAM)
+		nob = 0xffff;
+
+	host->data = data;
+	data->bytes_xfered = 0;
+
+	writew(nob, host->base + MMC_REG_NOB);
+	writew(blksz, host->base + MMC_REG_BLK_LEN);
+	host->datasize = datasize;
+
+#ifdef HAS_DMA
+	for_each_sg(data->sg, sg, data->sg_len, i) {
+		if (sg->offset & 3 || sg->length & 3) {
+			host->do_dma = 0;
+			return;
+		}
+	}
+
+	if (data->flags & MMC_DATA_READ) {
+		host->dma_dir = DMA_FROM_DEVICE;
+		host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
+					     data->sg_len,  host->dma_dir);
+
+		imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,
+				 host->res->start + MMC_REG_BUFFER_ACCESS,
+				 DMA_MODE_READ);
+	} else {
+		host->dma_dir = DMA_TO_DEVICE;
+		host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
+					     data->sg_len,  host->dma_dir);
+
+		imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,
+				 host->res->start + MMC_REG_BUFFER_ACCESS,
+				 DMA_MODE_WRITE);
+	}
+
+	wmb();
+
+	imx_dma_enable(host->dma);
+#endif /* HAS_DMA */
+}
+
+static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
+		unsigned int cmdat)
+{
+	WARN_ON(host->cmd != NULL);
+	host->cmd = cmd;
+
+	switch (mmc_resp_type(cmd)) {
+	case MMC_RSP_R1: /* short CRC, OPCODE */
+	case MMC_RSP_R1B:/* short CRC, OPCODE, BUSY */
+		cmdat |= CMD_DAT_CONT_RESPONSE_48BIT_CRC;
+		break;
+	case MMC_RSP_R2: /* long 136 bit + CRC */
+		cmdat |= CMD_DAT_CONT_RESPONSE_136BIT;
+		break;
+	case MMC_RSP_R3: /* short */
+		cmdat |= CMD_DAT_CONT_RESPONSE_48BIT;
+		break;
+	case MMC_RSP_NONE:
+		break;
+	default:
+		dev_err(mmc_dev(host->mmc), "unhandled response type 0x%x\n",
+				mmc_resp_type(cmd));
+		cmd->error = -EINVAL;
+		return -EINVAL;
+	}
+
+	if (mxcmci_use_dma(host))
+		writel(INT_READ_OP_EN | INT_WRITE_OP_DONE_EN |
+				INT_END_CMD_RES_EN,
+				host->base + MMC_REG_INT_CNTR);
+	else
+		writel(INT_END_CMD_RES_EN, host->base + MMC_REG_INT_CNTR);
+
+	writew(cmd->opcode, host->base + MMC_REG_CMD);
+	writel(cmd->arg, host->base + MMC_REG_ARG);
+	writew(cmdat, host->base + MMC_REG_CMD_DAT_CONT);
+
+	return 0;
+}
+
+static void mxcmci_finish_request(struct mxcmci_host *host,
+		struct mmc_request *req)
+{
+	writel(0, host->base + MMC_REG_INT_CNTR);
+
+	host->req = NULL;
+	host->cmd = NULL;
+	host->data = NULL;
+
+	mmc_request_done(host->mmc, req);
+}
+
+static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
+{
+	struct mmc_data *data = host->data;
+	int data_error;
+
+#ifdef HAS_DMA
+	if (mxcmci_use_dma(host)) {
+		imx_dma_disable(host->dma);
+		dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents,
+				host->dma_dir);
+	}
+#endif
+
+	if (stat & STATUS_ERR_MASK) {
+		dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
+				stat);
+		if (stat & STATUS_CRC_READ_ERR) {
+			data->error = -EILSEQ;
+		} else if (stat & STATUS_CRC_WRITE_ERR) {
+			u32 err_code = (stat >> 9) & 0x3;
+			if (err_code == 2) /* No CRC response */
+				data->error = -ETIMEDOUT;
+			else
+				data->error = -EILSEQ;
+		} else if (stat & STATUS_TIME_OUT_READ) {
+			data->error = -ETIMEDOUT;
+		} else {
+			data->error = -EIO;
+		}
+	} else {
+		data->bytes_xfered = host->datasize;
+	}
+
+	data_error = data->error;
+
+	host->data = NULL;
+
+	return data_error;
+}
+
+static void mxcmci_read_response(struct mxcmci_host *host, unsigned int stat)
+{
+	struct mmc_command *cmd = host->cmd;
+	int i;
+	u32 a, b, c;
+
+	if (!cmd)
+		return;
+
+	if (stat & STATUS_TIME_OUT_RESP) {
+		dev_dbg(mmc_dev(host->mmc), "CMD TIMEOUT\n");
+		cmd->error = -ETIMEDOUT;
+	} else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
+		dev_dbg(mmc_dev(host->mmc), "cmd crc error\n");
+		cmd->error = -EILSEQ;
+	}
+
+	if (cmd->flags & MMC_RSP_PRESENT) {
+		if (cmd->flags & MMC_RSP_136) {
+			for (i = 0; i < 4; i++) {
+				a = readw(host->base + MMC_REG_RES_FIFO);
+				b = readw(host->base + MMC_REG_RES_FIFO);
+				cmd->resp[i] = a << 16 | b;
+			}
+		} else {
+			a = readw(host->base + MMC_REG_RES_FIFO);
+			b = readw(host->base + MMC_REG_RES_FIFO);
+			c = readw(host->base + MMC_REG_RES_FIFO);
+			cmd->resp[0] = a << 24 | b << 8 | c >> 8;
+		}
+	}
+}
+
+static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask)
+{
+	u32 stat;
+	unsigned long timeout = jiffies + HZ;
+
+	do {
+		stat = readl(host->base + MMC_REG_STATUS);
+		if (stat & STATUS_ERR_MASK)
+			return stat;
+		if (time_after(jiffies, timeout))
+			return STATUS_TIME_OUT_READ;
+		if (stat & mask)
+			return 0;
+		cpu_relax();
+	} while (1);
+}
+
+static int mxcmci_pull(struct mxcmci_host *host, void *_buf, int bytes)
+{
+	unsigned int stat;
+	u32 *buf = _buf;
+
+	while (bytes > 3) {
+		stat = mxcmci_poll_status(host,
+				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
+		if (stat)
+			return stat;
+		*buf++ = readl(host->base + MMC_REG_BUFFER_ACCESS);
+		bytes -= 4;
+	}
+
+	if (bytes) {
+		u8 *b = (u8 *)buf;
+		u32 tmp;
+
+		stat = mxcmci_poll_status(host,
+				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
+		if (stat)
+			return stat;
+		tmp = readl(host->base + MMC_REG_BUFFER_ACCESS);
+		memcpy(b, &tmp, bytes);
+	}
+
+	return 0;
+}
+
+static int mxcmci_push(struct mxcmci_host *host, void *_buf, int bytes)
+{
+	unsigned int stat;
+	u32 *buf = _buf;
+
+	while (bytes > 3) {
+		stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+		if (stat)
+			return stat;
+		writel(*buf++, host->base + MMC_REG_BUFFER_ACCESS);
+		bytes -= 4;
+	}
+
+	if (bytes) {
+		u8 *b = (u8 *)buf;
+		u32 tmp;
+
+		stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+		if (stat)
+			return stat;
+
+		memcpy(&tmp, b, bytes);
+		writel(tmp, host->base + MMC_REG_BUFFER_ACCESS);
+	}
+
+	stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+	if (stat)
+		return stat;
+
+	return 0;
+}
+
+static int mxcmci_transfer_data(struct mxcmci_host *host)
+{
+	struct mmc_data *data = host->req->data;
+	struct scatterlist *sg;
+	int stat, i;
+
+	host->datasize = 0;
+
+	host->data = data;
+	host->datasize = 0;
+
+	if (data->flags & MMC_DATA_READ) {
+		for_each_sg(data->sg, sg, data->sg_len, i) {
+			stat = mxcmci_pull(host, sg_virt(sg), sg->length);
+			if (stat)
+				return stat;
+			host->datasize += sg->length;
+		}
+	} else {
+		for_each_sg(data->sg, sg, data->sg_len, i) {
+			stat = mxcmci_push(host, sg_virt(sg), sg->length);
+			if (stat)
+				return stat;
+			host->datasize += sg->length;
+		}
+		stat = mxcmci_poll_status(host, STATUS_WRITE_OP_DONE);
+		if (stat)
+			return stat;
+	}
+	return 0;
+}
+
+static void mxcmci_datawork(struct work_struct *work)
+{
+	struct mxcmci_host *host = container_of(work, struct mxcmci_host,
+						  datawork);
+	int datastat = mxcmci_transfer_data(host);
+	mxcmci_finish_data(host, datastat);
+
+	if (host->req->stop) {
+		if (mxcmci_start_cmd(host, host->req->stop, 0)) {
+			mxcmci_finish_request(host, host->req);
+			return;
+		}
+	} else {
+		mxcmci_finish_request(host, host->req);
+	}
+}
+
+#ifdef HAS_DMA
+static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat)
+{
+	struct mmc_data *data = host->data;
+	int data_error;
+
+	if (!data)
+		return;
+
+	data_error = mxcmci_finish_data(host, stat);
+
+	mxcmci_read_response(host, stat);
+	host->cmd = NULL;
+
+	if (host->req->stop) {
+		if (mxcmci_start_cmd(host, host->req->stop, 0)) {
+			mxcmci_finish_request(host, host->req);
+			return;
+		}
+	} else {
+		mxcmci_finish_request(host, host->req);
+	}
+}
+#endif /* HAS_DMA */
+
+static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)
+{
+	mxcmci_read_response(host, stat);
+	host->cmd = NULL;
+
+	if (!host->data && host->req) {
+		mxcmci_finish_request(host, host->req);
+		return;
+	}
+
+	/* For the DMA case the DMA engine handles the data transfer
+	 * automatically. For non DMA we have to to it ourselves.
+	 * Don't do it in interrupt context though.
+	 */
+	if (!mxcmci_use_dma(host) && host->data)
+		schedule_work(&host->datawork);
+
+}
+
+static irqreturn_t mxcmci_irq(int irq, void *devid)
+{
+	struct mxcmci_host *host = devid;
+	u32 stat;
+
+	stat = readl(host->base + MMC_REG_STATUS);
+	writel(stat, host->base + MMC_REG_STATUS);
+
+	dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);
+
+	if (stat & STATUS_END_CMD_RESP)
+		mxcmci_cmd_done(host, stat);
+#ifdef HAS_DMA
+	if (mxcmci_use_dma(host) &&
+		  (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
+		mxcmci_data_done(host, stat);
+#endif
+	return IRQ_HANDLED;
+}
+
+static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
+{
+	struct mxcmci_host *host = mmc_priv(mmc);
+	unsigned int cmdat = host->cmdat;
+
+	WARN_ON(host->req != NULL);
+
+	host->req = req;
+	host->cmdat &= ~CMD_DAT_CONT_INIT;
+#ifdef HAS_DMA
+	host->do_dma = 1;
+#endif
+	if (req->data) {
+		mxcmci_setup_data(host, req->data);
+
+		cmdat |= CMD_DAT_CONT_DATA_ENABLE;
+
+		if (req->data->flags & MMC_DATA_WRITE)
+			cmdat |= CMD_DAT_CONT_WRITE;
+	}
+
+	if (mxcmci_start_cmd(host, req->cmd, cmdat))
+		mxcmci_finish_request(host, req);
+}
+
+static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
+{
+	unsigned int divider;
+	int prescaler = 0;
+	unsigned int clk_in = clk_get_rate(host->clk);
+
+	while (prescaler <= 0x800) {
+		for (divider = 1; divider <= 0xF; divider++) {
+			int x;
+
+			x = (clk_in / (divider + 1));
+
+			if (prescaler)
+				x /= (prescaler * 2);
+
+			if (x <= clk_ios)
+				break;
+		}
+		if (divider < 0x10)
+			break;
+
+		if (prescaler == 0)
+			prescaler = 1;
+		else
+			prescaler <<= 1;
+	}
+
+	writew((prescaler << 4) | divider, host->base + MMC_REG_CLK_RATE);
+
+	dev_dbg(mmc_dev(host->mmc), "scaler: %d divider: %d in: %d out: %d\n",
+			prescaler, divider, clk_in, clk_ios);
+}
+
+static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct mxcmci_host *host = mmc_priv(mmc);
+#ifdef HAS_DMA
+	unsigned int blen;
+	/*
+	 * use burstlen of 64 in 4 bit mode (--> reg value  0)
+	 * use burstlen of 16 in 1 bit mode (--> reg value 16)
+	 */
+	if (ios->bus_width == MMC_BUS_WIDTH_4)
+		blen = 0;
+	else
+		blen = 16;
+
+	imx_dma_config_burstlen(host->dma, blen);
+#endif
+	if (ios->bus_width == MMC_BUS_WIDTH_4)
+		host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;
+	else
+		host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4;
+
+	if (host->power_mode != ios->power_mode) {
+		if (host->pdata && host->pdata->setpower)
+			host->pdata->setpower(mmc_dev(mmc), ios->vdd);
+		host->power_mode = ios->power_mode;
+		if (ios->power_mode == MMC_POWER_ON)
+			host->cmdat |= CMD_DAT_CONT_INIT;
+	}
+
+	if (ios->clock) {
+		mxcmci_set_clk_rate(host, ios->clock);
+		writew(STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK);
+	} else {
+		writew(STR_STP_CLK_STOP_CLK, host->base + MMC_REG_STR_STP_CLK);
+	}
+
+	host->clock = ios->clock;
+}
+
+static irqreturn_t mxcmci_detect_irq(int irq, void *data)
+{
+	struct mmc_host *mmc = data;
+
+	dev_dbg(mmc_dev(mmc), "%s\n", __func__);
+
+	mmc_detect_change(mmc, msecs_to_jiffies(250));
+	return IRQ_HANDLED;
+}
+
+static int mxcmci_get_ro(struct mmc_host *mmc)
+{
+	struct mxcmci_host *host = mmc_priv(mmc);
+
+	if (host->pdata && host->pdata->get_ro)
+		return !!host->pdata->get_ro(mmc_dev(mmc));
+	/*
+	 * Board doesn't support read only detection; let the mmc core
+	 * decide what to do.
+	 */
+	return -ENOSYS;
+}
+
+
+static const struct mmc_host_ops mxcmci_ops = {
+	.request	= mxcmci_request,
+	.set_ios	= mxcmci_set_ios,
+	.get_ro		= mxcmci_get_ro,
+};
+
+static int mxcmci_probe(struct platform_device *pdev)
+{
+	struct mmc_host *mmc;
+	struct mxcmci_host *host = NULL;
+	struct resource *r;
+	int ret = 0, irq;
+
+	printk(KERN_INFO "i.MX SDHC driver\n");
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (!r || irq < 0)
+		return -EINVAL;
+
+	r = request_mem_region(r->start, resource_size(r), pdev->name);
+	if (!r)
+		return -EBUSY;
+
+	mmc = mmc_alloc_host(sizeof(struct mxcmci_host), &pdev->dev);
+	if (!mmc) {
+		ret = -ENOMEM;
+		goto out_release_mem;
+	}
+
+	mmc->ops = &mxcmci_ops;
+	mmc->caps = MMC_CAP_4_BIT_DATA;
+
+	/* MMC core transfer sizes tunable parameters */
+	mmc->max_hw_segs = 64;
+	mmc->max_phys_segs = 64;
+	mmc->max_blk_size = 2048;
+	mmc->max_blk_count = 65535;
+	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+	mmc->max_seg_size = mmc->max_seg_size;
+
+	host = mmc_priv(mmc);
+	host->base = ioremap(r->start, resource_size(r));
+	if (!host->base) {
+		ret = -ENOMEM;
+		goto out_free;
+	}
+
+	host->mmc = mmc;
+	host->pdata = pdev->dev.platform_data;
+
+	if (host->pdata && host->pdata->ocr_avail)
+		mmc->ocr_avail = host->pdata->ocr_avail;
+	else
+		mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+	host->res = r;
+	host->irq = irq;
+
+	host->clk = clk_get(&pdev->dev, "sdhc_clk");
+	if (IS_ERR(host->clk)) {
+		ret = PTR_ERR(host->clk);
+		goto out_iounmap;
+	}
+	clk_enable(host->clk);
+
+	mxcmci_softreset(host);
+
+	host->rev_no = readw(host->base + MMC_REG_REV_NO);
+	if (host->rev_no != 0x400) {
+		ret = -ENODEV;
+		dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n",
+			host->rev_no);
+		goto out_clk_put;
+	}
+
+	mmc->f_min = clk_get_rate(host->clk) >> 7;
+	mmc->f_max = clk_get_rate(host->clk) >> 1;
+
+	/* recommended in data sheet */
+	writew(0x2db4, host->base + MMC_REG_READ_TO);
+
+	writel(0, host->base + MMC_REG_INT_CNTR);
+
+#ifdef HAS_DMA
+	host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW);
+	if (host->dma < 0) {
+		dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n");
+		ret = -EBUSY;
+		goto out_clk_put;
+	}
+
+	r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+	if (!r) {
+		ret = -EINVAL;
+		goto out_free_dma;
+	}
+
+	ret = imx_dma_config_channel(host->dma,
+				     IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_FIFO,
+				     IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
+				     r->start, 0);
+	if (ret) {
+		dev_err(mmc_dev(host->mmc), "failed to config DMA channel\n");
+		goto out_free_dma;
+	}
+#endif
+	INIT_WORK(&host->datawork, mxcmci_datawork);
+
+	ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host);
+	if (ret)
+		goto out_free_dma;
+
+	platform_set_drvdata(pdev, mmc);
+
+	if (host->pdata && host->pdata->init) {
+		ret = host->pdata->init(&pdev->dev, mxcmci_detect_irq,
+				host->mmc);
+		if (ret)
+			goto out_free_irq;
+	}
+
+	mmc_add_host(mmc);
+
+	return 0;
+
+out_free_irq:
+	free_irq(host->irq, host);
+out_free_dma:
+#ifdef HAS_DMA
+	imx_dma_free(host->dma);
+#endif
+out_clk_put:
+	clk_disable(host->clk);
+	clk_put(host->clk);
+out_iounmap:
+	iounmap(host->base);
+out_free:
+	mmc_free_host(mmc);
+out_release_mem:
+	release_mem_region(host->res->start, resource_size(host->res));
+	return ret;
+}
+
+static int mxcmci_remove(struct platform_device *pdev)
+{
+	struct mmc_host *mmc = platform_get_drvdata(pdev);
+	struct mxcmci_host *host = mmc_priv(mmc);
+
+	platform_set_drvdata(pdev, NULL);
+
+	mmc_remove_host(mmc);
+
+	if (host->pdata && host->pdata->exit)
+		host->pdata->exit(&pdev->dev, mmc);
+
+	free_irq(host->irq, host);
+	iounmap(host->base);
+#ifdef HAS_DMA
+	imx_dma_free(host->dma);
+#endif
+	clk_disable(host->clk);
+	clk_put(host->clk);
+
+	release_mem_region(host->res->start, resource_size(host->res));
+	release_resource(host->res);
+
+	mmc_free_host(mmc);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int mxcmci_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct mmc_host *mmc = platform_get_drvdata(dev);
+	int ret = 0;
+
+	if (mmc)
+		ret = mmc_suspend_host(mmc, state);
+
+	return ret;
+}
+
+static int mxcmci_resume(struct platform_device *dev)
+{
+	struct mmc_host *mmc = platform_get_drvdata(dev);
+	struct mxcmci_host *host;
+	int ret = 0;
+
+	if (mmc) {
+		host = mmc_priv(mmc);
+		ret = mmc_resume_host(mmc);
+	}
+
+	return ret;
+}
+#else
+#define mxcmci_suspend  NULL
+#define mxcmci_resume   NULL
+#endif /* CONFIG_PM */
+
+static struct platform_driver mxcmci_driver = {
+	.probe		= mxcmci_probe,
+	.remove		= mxcmci_remove,
+	.suspend	= mxcmci_suspend,
+	.resume		= mxcmci_resume,
+	.driver		= {
+		.name		= DRIVER_NAME,
+		.owner		= THIS_MODULE,
+	}
+};
+
+static int __init mxcmci_init(void)
+{
+	return platform_driver_register(&mxcmci_driver);
+}
+
+static void __exit mxcmci_exit(void)
+{
+	platform_driver_unregister(&mxcmci_driver);
+}
+
+module_init(mxcmci_init);
+module_exit(mxcmci_exit);
+
+MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
+MODULE_AUTHOR("Sascha Hauer, Pengutronix");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-mmc");
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 3c5483b75da4..9702ad3774cf 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -180,7 +180,15 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
 	else
 		DALGN &= ~(1 << host->dma);
 	DDADR(host->dma) = host->sg_dma;
-	DCSR(host->dma) = DCSR_RUN;
+
+	/*
+	 * workaround for erratum #91:
+	 * only start DMA now if we are doing a read,
+	 * otherwise we wait until CMD/RESP has finished
+	 * before starting DMA.
+	 */
+	if (!cpu_is_pxa27x() || data->flags & MMC_DATA_READ)
+		DCSR(host->dma) = DCSR_RUN;
 }
 
 static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat)
@@ -251,23 +259,28 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat)
 	if (stat & STAT_TIME_OUT_RESPONSE) {
 		cmd->error = -ETIMEDOUT;
 	} else if (stat & STAT_RES_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
-#ifdef CONFIG_PXA27x
 		/*
 		 * workaround for erratum #42:
 		 * Intel PXA27x Family Processor Specification Update Rev 001
 		 * A bogus CRC error can appear if the msb of a 136 bit
 		 * response is a one.
 		 */
-		if (cmd->flags & MMC_RSP_136 && cmd->resp[0] & 0x80000000) {
+		if (cpu_is_pxa27x() &&
+		    (cmd->flags & MMC_RSP_136 && cmd->resp[0] & 0x80000000))
 			pr_debug("ignoring CRC from command %d - *risky*\n", cmd->opcode);
-		} else
-#endif
-		cmd->error = -EILSEQ;
+		else
+			cmd->error = -EILSEQ;
 	}
 
 	pxamci_disable_irq(host, END_CMD_RES);
 	if (host->data && !cmd->error) {
 		pxamci_enable_irq(host, DATA_TRAN_DONE);
+		/*
+		 * workaround for erratum #91, if doing write
+		 * enable DMA late
+		 */
+		if (cpu_is_pxa27x() && host->data->flags & MMC_DATA_WRITE)
+			DCSR(host->dma) = DCSR_RUN;
 	} else {
 		pxamci_finish_request(host, host->mrq);
 	}
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c
index be9e7b32b34e..f62790513322 100644
--- a/drivers/mmc/host/ricoh_mmc.c
+++ b/drivers/mmc/host/ricoh_mmc.c
@@ -196,7 +196,7 @@ static void __devexit ricoh_mmc_remove(struct pci_dev *pdev)
 	pci_set_drvdata(pdev, NULL);
 }
 
-static int ricoh_mmc_suspend(struct pci_dev *pdev, pm_message_t state)
+static int ricoh_mmc_suspend_late(struct pci_dev *pdev, pm_message_t state)
 {
 	struct pci_dev *fw_dev = NULL;
 
@@ -210,7 +210,7 @@ static int ricoh_mmc_suspend(struct pci_dev *pdev, pm_message_t state)
 	return 0;
 }
 
-static int ricoh_mmc_resume(struct pci_dev *pdev)
+static int ricoh_mmc_resume_early(struct pci_dev *pdev)
 {
 	struct pci_dev *fw_dev = NULL;
 
@@ -229,8 +229,8 @@ static struct pci_driver ricoh_mmc_driver = {
 	.id_table =	pci_ids,
 	.probe = 	ricoh_mmc_probe,
 	.remove =	__devexit_p(ricoh_mmc_remove),
-	.suspend =	ricoh_mmc_suspend,
-	.resume =	ricoh_mmc_resume,
+	.suspend_late =	ricoh_mmc_suspend_late,
+	.resume_early =	ricoh_mmc_resume_early,
 };
 
 /*****************************************************************************\
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 7df6bbf0e4d9..6f6a0f6dafd6 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -453,7 +453,7 @@ static struct platform_driver sa1100_mtd_driver = {
 	.resume		= sa1100_mtd_resume,
 	.shutdown	= sa1100_mtd_shutdown,
 	.driver		= {
-		.name	= "flash",
+		.name	= "sa1100-mtd",
 		.owner	= THIS_MODULE,
 	},
 };
@@ -474,4 +474,4 @@ module_exit(sa1100_mtd_exit);
 MODULE_AUTHOR("Nicolas Pitre");
 MODULE_DESCRIPTION("SA1100 CFI map driver");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:flash");
+MODULE_ALIAS("platform:sa1100-mtd");
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
index d15d8b79d8e5..54b52e5b1821 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/arm/etherh.c
@@ -646,7 +646,7 @@ static const struct net_device_ops etherh_netdev_ops = {
 	.ndo_get_stats		= ei_get_stats,
 	.ndo_set_multicast_list = ei_set_multicast_list,
 	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_mac_address	= eth_set_mac_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
 	.ndo_change_mtu		= eth_change_mtu,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= ei_poll,
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 840b3d1a22f5..bbbc3bb08aa5 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -806,7 +806,7 @@ static int cas_reset_mii_phy(struct cas *cp)
 
 	cas_phy_write(cp, MII_BMCR, BMCR_RESET);
 	udelay(100);
-	while (limit--) {
+	while (--limit) {
 		val = cas_phy_read(cp, MII_BMCR);
 		if ((val & BMCR_RESET) == 0)
 			break;
@@ -979,7 +979,7 @@ static void cas_phy_init(struct cas *cp)
 		writel(val, cp->regs + REG_PCS_MII_CTRL);
 
 		limit = STOP_TRIES;
-		while (limit-- > 0) {
+		while (--limit > 0) {
 			udelay(10);
 			if ((readl(cp->regs + REG_PCS_MII_CTRL) &
 			     PCS_MII_RESET) == 0)
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 379a1324db4e..d31791f60292 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -2276,8 +2276,7 @@ no_mem:
 		} else if ((len = ntohl(r->len_cq)) != 0) {
 			struct sge_fl *fl;
 
-			if (eth)
-				lro = qs->lro_enabled && is_eth_tcp(rss_hi);
+			lro &= eth && is_eth_tcp(rss_hi);
 
 			fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0];
 			if (fl->use_pages) {
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index c986978ce761..6bd63cc67b3e 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -940,7 +940,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 		err = pci_enable_device(pdev);
 	} else {
 		bars = pci_select_bars(pdev, IORESOURCE_MEM);
-		err = pci_enable_device(pdev);
+		err = pci_enable_device_mem(pdev);
 	}
 	if (err)
 		return err;
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 3f7eab42aef1..acae2d8cd688 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -351,6 +351,9 @@ static int gfar_probe(struct of_device *ofdev,
 	/* Reset MAC layer */
 	gfar_write(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
 
+	/* We need to delay at least 3 TX clocks */
+	udelay(2);
+
 	tempval = (MACCFG1_TX_FLOW | MACCFG1_RX_FLOW);
 	gfar_write(&priv->regs->maccfg1, tempval);
 
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index b1a83344acc7..eaa86897f5c3 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -312,7 +312,7 @@ extern const char gfar_driver_version[];
 #define ATTRELI_EI(x) (x)
 
 #define BD_LFLAG(flags) ((flags) << 16)
-#define BD_LENGTH_MASK		0x00ff
+#define BD_LENGTH_MASK		0x0000ffff
 
 /* TxBD status field bits */
 #define TXBD_READY		0x8000
diff --git a/drivers/net/ibm_newemac/phy.c b/drivers/net/ibm_newemac/phy.c
index c40cd8df2212..ac9d964e59ec 100644
--- a/drivers/net/ibm_newemac/phy.c
+++ b/drivers/net/ibm_newemac/phy.c
@@ -60,7 +60,7 @@ int emac_mii_reset_phy(struct mii_phy *phy)
 
 	udelay(300);
 
-	while (limit--) {
+	while (--limit) {
 		val = phy_read(phy, MII_BMCR);
 		if (val >= 0 && (val & BMCR_RESET) == 0)
 			break;
@@ -84,7 +84,7 @@ int emac_mii_reset_gpcs(struct mii_phy *phy)
 
 	udelay(300);
 
-	while (limit--) {
+	while (--limit) {
 		val = gpcs_phy_read(phy, MII_BMCR);
 		if (val >= 0 && (val & BMCR_RESET) == 0)
 			break;
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index f5e2e7235fcb..13ca73f96ec6 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -699,11 +699,18 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw)
 
 	/* SGMII link check is done through the PCS register. */
 	if ((hw->phy.media_type != e1000_media_type_copper) ||
-	    (igb_sgmii_active_82575(hw)))
+	    (igb_sgmii_active_82575(hw))) {
 		ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed,
 		                                             &duplex);
-	else
+		/*
+		 * Use this flag to determine if link needs to be checked or
+		 * not.  If  we have link clear the flag so that we do not
+		 * continue to check for link.
+		 */
+		hw->mac.get_link_status = !hw->mac.serdes_has_link;
+	} else {
 		ret_val = igb_check_for_copper_link(hw);
+	}
 
 	return ret_val;
 }
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 5a27825cc48a..aebef8e48e76 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -300,11 +300,10 @@ struct igb_adapter {
 
 #define IGB_FLAG_HAS_MSI           (1 << 0)
 #define IGB_FLAG_MSI_ENABLE        (1 << 1)
-#define IGB_FLAG_HAS_DCA           (1 << 2)
-#define IGB_FLAG_DCA_ENABLED       (1 << 3)
-#define IGB_FLAG_IN_NETPOLL        (1 << 5)
-#define IGB_FLAG_QUAD_PORT_A       (1 << 6)
-#define IGB_FLAG_NEED_CTX_IDX      (1 << 7)
+#define IGB_FLAG_DCA_ENABLED       (1 << 2)
+#define IGB_FLAG_IN_NETPOLL        (1 << 3)
+#define IGB_FLAG_QUAD_PORT_A       (1 << 4)
+#define IGB_FLAG_NEED_CTX_IDX      (1 << 5)
 
 enum e1000_state_t {
 	__IGB_TESTING,
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index b82b0fb2056c..a50db5398fa5 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -206,10 +206,11 @@ static int __init igb_init_module(void)
 
 	global_quad_port_a = 0;
 
-	ret = pci_register_driver(&igb_driver);
 #ifdef CONFIG_IGB_DCA
 	dca_register_notify(&dca_notifier);
 #endif
+
+	ret = pci_register_driver(&igb_driver);
 	return ret;
 }
 
@@ -1156,11 +1157,10 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 
 	/* set flags */
 	switch (hw->mac.type) {
-	case e1000_82576:
 	case e1000_82575:
-		adapter->flags |= IGB_FLAG_HAS_DCA;
 		adapter->flags |= IGB_FLAG_NEED_CTX_IDX;
 		break;
+	case e1000_82576:
 	default:
 		break;
 	}
@@ -1310,8 +1310,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 		goto err_register;
 
 #ifdef CONFIG_IGB_DCA
-	if ((adapter->flags & IGB_FLAG_HAS_DCA) &&
-	    (dca_add_requester(&pdev->dev) == 0)) {
+	if (dca_add_requester(&pdev->dev) == 0) {
 		adapter->flags |= IGB_FLAG_DCA_ENABLED;
 		dev_info(&pdev->dev, "DCA enabled\n");
 		/* Always use CB2 mode, difference is masked
@@ -1835,11 +1834,11 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
 	rctl |= E1000_RCTL_SECRC;
 
 	/*
-	 * disable store bad packets, long packet enable, and clear size bits.
+	 * disable store bad packets and clear size bits.
 	 */
-	rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_LPE | E1000_RCTL_SZ_256);
+	rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_SZ_256);
 
-	if (adapter->netdev->mtu > ETH_DATA_LEN)
+	/* enable LPE when to prevent packets larger than max_frame_size */
 		rctl |= E1000_RCTL_LPE;
 
 	/* Setup buffer sizes */
@@ -1865,7 +1864,7 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
 	 */
 	/* allocations using alloc_page take too long for regular MTU
 	 * so only enable packet split for jumbo frames */
-	if (rctl & E1000_RCTL_LPE) {
+	if (adapter->netdev->mtu > ETH_DATA_LEN) {
 		adapter->rx_ps_hdr_size = IGB_RXBUFFER_128;
 		srrctl |= adapter->rx_ps_hdr_size <<
 			 E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
@@ -3473,19 +3472,16 @@ static int __igb_notify_dca(struct device *dev, void *data)
 	struct e1000_hw *hw = &adapter->hw;
 	unsigned long event = *(unsigned long *)data;
 
-	if (!(adapter->flags & IGB_FLAG_HAS_DCA))
-		goto out;
-
 	switch (event) {
 	case DCA_PROVIDER_ADD:
 		/* if already enabled, don't do it again */
 		if (adapter->flags & IGB_FLAG_DCA_ENABLED)
 			break;
-		adapter->flags |= IGB_FLAG_DCA_ENABLED;
 		/* Always use CB2 mode, difference is masked
 		 * in the CB driver. */
 		wr32(E1000_DCA_CTRL, 2);
 		if (dca_add_requester(dev) == 0) {
+			adapter->flags |= IGB_FLAG_DCA_ENABLED;
 			dev_info(&adapter->pdev->dev, "DCA enabled\n");
 			igb_setup_dca(adapter);
 			break;
@@ -3502,7 +3498,7 @@ static int __igb_notify_dca(struct device *dev, void *data)
 		}
 		break;
 	}
-out:
+
 	return 0;
 }
 
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index c38ed777f0a8..a6999403f37b 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -586,7 +586,7 @@ static int pcnet_config(struct pcmcia_device *link)
     }
 
     if ((link->conf.ConfigBase == 0x03c0)
-	&& (link->manf_id == 0x149) && (link->card_id = 0xc1ab)) {
+	&& (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
 	printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n");
 	printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n");
 	goto failed;
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index ec2314246682..335da4831ab3 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -2168,7 +2168,7 @@ static void gelic_wl_connected_event(struct gelic_wl_info *wl,
 		complete(&wl->assoc_done);
 		netif_carrier_on(port_to_netdev(wl_port(wl)));
 	} else
-		pr_debug("%s: event %#lx under wpa\n",
+		pr_debug("%s: event %#llx under wpa\n",
 				 __func__, event);
 }
 
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index c1dadadfab18..e6fdce9206cc 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -787,12 +787,12 @@ struct mbox_params {
 
 struct flash_params {
 	u8 dev_id_str[4];
-	u16 size;
-	u16 csum;
-	u16 ver;
-	u16 sub_dev_id;
+	__le16 size;
+	__le16 csum;
+	__le16 ver;
+	__le16 sub_dev_id;
 	u8 mac_addr[6];
-	u16 res;
+	__le16 res;
 };
 
 
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 45421c8b6010..3d1d7b6e55aa 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -641,7 +641,7 @@ static void ql_enable_all_completion_interrupts(struct ql_adapter *qdev)
 
 }
 
-static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data)
+static int ql_read_flash_word(struct ql_adapter *qdev, int offset, __le32 *data)
 {
 	int status = 0;
 	/* wait for reg to come ready */
@@ -656,8 +656,11 @@ static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data)
 			FLASH_ADDR, FLASH_ADDR_RDY, FLASH_ADDR_ERR);
 	if (status)
 		goto exit;
-	/* get the data */
-	*data = ql_read32(qdev, FLASH_DATA);
+	 /* This data is stored on flash as an array of
+	 * __le32.  Since ql_read32() returns cpu endian
+	 * we need to swap it back.
+	 */
+	*data = cpu_to_le32(ql_read32(qdev, FLASH_DATA));
 exit:
 	return status;
 }
@@ -666,13 +669,20 @@ static int ql_get_flash_params(struct ql_adapter *qdev)
 {
 	int i;
 	int status;
-	u32 *p = (u32 *)&qdev->flash;
+	__le32 *p = (__le32 *)&qdev->flash;
+	u32 offset = 0;
+
+	/* Second function's parameters follow the first
+	 * function's.
+	 */
+	if (qdev->func)
+		offset = sizeof(qdev->flash) / sizeof(u32);
 
 	if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
 		return -ETIMEDOUT;
 
 	for (i = 0; i < sizeof(qdev->flash) / sizeof(u32); i++, p++) {
-		status = ql_read_flash_word(qdev, i, p);
+		status = ql_read_flash_word(qdev, i+offset, p);
 		if (status) {
 			QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n");
 			goto exit;
@@ -3826,7 +3836,7 @@ static int qlge_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *ndev = pci_get_drvdata(pdev);
 	struct ql_adapter *qdev = netdev_priv(ndev);
-	int err;
+	int err, i;
 
 	netif_device_detach(ndev);
 
@@ -3836,6 +3846,9 @@ static int qlge_suspend(struct pci_dev *pdev, pm_message_t state)
 			return err;
 	}
 
+	for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++)
+		netif_napi_del(&qdev->rx_ring[i].napi);
+
 	err = pci_save_state(pdev);
 	if (err)
 		return err;
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 101c00a7bb73..847e9bb0098f 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -676,9 +676,8 @@ static int efx_init_port(struct efx_nic *efx)
 	rc = efx->phy_op->init(efx);
 	if (rc)
 		return rc;
-	efx->phy_op->reconfigure(efx);
-
 	mutex_lock(&efx->mac_lock);
+	efx->phy_op->reconfigure(efx);
 	rc = falcon_switch_mac(efx);
 	mutex_unlock(&efx->mac_lock);
 	if (rc)
@@ -686,7 +685,7 @@ static int efx_init_port(struct efx_nic *efx)
 	efx->mac_op->reconfigure(efx);
 
 	efx->port_initialized = true;
-	efx->stats_enabled = true;
+	efx_stats_enable(efx);
 	return 0;
 
 fail:
@@ -735,6 +734,7 @@ static void efx_fini_port(struct efx_nic *efx)
 	if (!efx->port_initialized)
 		return;
 
+	efx_stats_disable(efx);
 	efx->phy_op->fini(efx);
 	efx->port_initialized = false;
 
@@ -1368,6 +1368,20 @@ static int efx_net_stop(struct net_device *net_dev)
 	return 0;
 }
 
+void efx_stats_disable(struct efx_nic *efx)
+{
+	spin_lock(&efx->stats_lock);
+	++efx->stats_disable_count;
+	spin_unlock(&efx->stats_lock);
+}
+
+void efx_stats_enable(struct efx_nic *efx)
+{
+	spin_lock(&efx->stats_lock);
+	--efx->stats_disable_count;
+	spin_unlock(&efx->stats_lock);
+}
+
 /* Context: process, dev_base_lock or RTNL held, non-blocking. */
 static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
 {
@@ -1376,12 +1390,12 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
 	struct net_device_stats *stats = &net_dev->stats;
 
 	/* Update stats if possible, but do not wait if another thread
-	 * is updating them (or resetting the NIC); slightly stale
-	 * stats are acceptable.
+	 * is updating them or if MAC stats fetches are temporarily
+	 * disabled; slightly stale stats are acceptable.
 	 */
 	if (!spin_trylock(&efx->stats_lock))
 		return stats;
-	if (efx->stats_enabled) {
+	if (!efx->stats_disable_count) {
 		efx->mac_op->update_stats(efx);
 		falcon_update_nic_stats(efx);
 	}
@@ -1629,16 +1643,12 @@ static void efx_unregister_netdev(struct efx_nic *efx)
 
 /* Tears down the entire software state and most of the hardware state
  * before reset.  */
-void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+void efx_reset_down(struct efx_nic *efx, enum reset_type method,
+		    struct ethtool_cmd *ecmd)
 {
 	EFX_ASSERT_RESET_SERIALISED(efx);
 
-	/* The net_dev->get_stats handler is quite slow, and will fail
-	 * if a fetch is pending over reset. Serialise against it. */
-	spin_lock(&efx->stats_lock);
-	efx->stats_enabled = false;
-	spin_unlock(&efx->stats_lock);
-
+	efx_stats_disable(efx);
 	efx_stop_all(efx);
 	mutex_lock(&efx->mac_lock);
 	mutex_lock(&efx->spi_lock);
@@ -1646,6 +1656,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 	efx->phy_op->get_settings(efx, ecmd);
 
 	efx_fini_channels(efx);
+	if (efx->port_initialized && method != RESET_TYPE_INVISIBLE)
+		efx->phy_op->fini(efx);
 }
 
 /* This function will always ensure that the locks acquired in
@@ -1653,7 +1665,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
  * that we were unable to reinitialise the hardware, and the
  * driver should be disabled. If ok is false, then the rx and tx
  * engines are not restarted, pending a RESET_DISABLE. */
-int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
+int efx_reset_up(struct efx_nic *efx, enum reset_type method,
+		 struct ethtool_cmd *ecmd, bool ok)
 {
 	int rc;
 
@@ -1665,6 +1678,15 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
 		ok = false;
 	}
 
+	if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) {
+		if (ok) {
+			rc = efx->phy_op->init(efx);
+			if (rc)
+				ok = false;
+		} else
+			efx->port_initialized = false;
+	}
+
 	if (ok) {
 		efx_init_channels(efx);
 
@@ -1677,7 +1699,7 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
 
 	if (ok) {
 		efx_start_all(efx);
-		efx->stats_enabled = true;
+		efx_stats_enable(efx);
 	}
 	return rc;
 }
@@ -1709,7 +1731,7 @@ static int efx_reset(struct efx_nic *efx)
 
 	EFX_INFO(efx, "resetting (%d)\n", method);
 
-	efx_reset_down(efx, &ecmd);
+	efx_reset_down(efx, method, &ecmd);
 
 	rc = falcon_reset_hw(efx, method);
 	if (rc) {
@@ -1728,10 +1750,10 @@ static int efx_reset(struct efx_nic *efx)
 
 	/* Leave device stopped if necessary */
 	if (method == RESET_TYPE_DISABLE) {
-		efx_reset_up(efx, &ecmd, false);
+		efx_reset_up(efx, method, &ecmd, false);
 		rc = -EIO;
 	} else {
-		rc = efx_reset_up(efx, &ecmd, true);
+		rc = efx_reset_up(efx, method, &ecmd, true);
 	}
 
 out_disable:
@@ -1883,6 +1905,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
 	efx->rx_checksum_enabled = true;
 	spin_lock_init(&efx->netif_stop_lock);
 	spin_lock_init(&efx->stats_lock);
+	efx->stats_disable_count = 1;
 	mutex_init(&efx->mac_lock);
 	efx->mac_op = &efx_dummy_mac_operations;
 	efx->phy_op = &efx_dummy_phy_operations;
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 0dd7a532c78a..55d0f131b0e9 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -36,13 +36,16 @@ extern void efx_process_channel_now(struct efx_channel *channel);
 extern void efx_flush_queues(struct efx_nic *efx);
 
 /* Ports */
+extern void efx_stats_disable(struct efx_nic *efx);
+extern void efx_stats_enable(struct efx_nic *efx);
 extern void efx_reconfigure_port(struct efx_nic *efx);
 extern void __efx_reconfigure_port(struct efx_nic *efx);
 
 /* Reset handling */
-extern void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd);
-extern int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd,
-			bool ok);
+extern void efx_reset_down(struct efx_nic *efx, enum reset_type method,
+			   struct ethtool_cmd *ecmd);
+extern int efx_reset_up(struct efx_nic *efx, enum reset_type method,
+			struct ethtool_cmd *ecmd, bool ok);
 
 /* Global */
 extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 53d259e90187..7b5924c039b3 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -219,9 +219,6 @@ int efx_ethtool_set_settings(struct net_device *net_dev,
 	struct efx_nic *efx = netdev_priv(net_dev);
 	int rc;
 
-	if (EFX_WORKAROUND_13963(efx) && !ecmd->autoneg)
-		return -EINVAL;
-
 	/* Falcon GMAC does not support 1000Mbps HD */
 	if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) {
 		EFX_LOG(efx, "rejecting unsupported 1000Mbps HD"
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 5b9f2d9cc4ed..d5378e60fcdd 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -824,10 +824,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
 			    rx_ev_pause_frm ? " [PAUSE]" : "");
 	}
 #endif
-
-	if (unlikely(rx_ev_eth_crc_err && EFX_WORKAROUND_10750(efx) &&
-		     efx->phy_type == PHY_TYPE_SFX7101))
-		tenxpress_crc_err(efx);
 }
 
 /* Handle receive events that are not in-order. */
@@ -1887,7 +1883,7 @@ static int falcon_reset_macs(struct efx_nic *efx)
 
 	/* MAC stats will fail whilst the TX fifo is draining. Serialise
 	 * the drain sequence with the statistics fetch */
-	spin_lock(&efx->stats_lock);
+	efx_stats_disable(efx);
 
 	falcon_read(efx, &reg, MAC0_CTRL_REG_KER);
 	EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1);
@@ -1917,7 +1913,7 @@ static int falcon_reset_macs(struct efx_nic *efx)
 		udelay(10);
 	}
 
-	spin_unlock(&efx->stats_lock);
+	efx_stats_enable(efx);
 
 	/* If we've reset the EM block and the link is up, then
 	 * we'll have to kick the XAUI link so the PHY can recover */
@@ -2277,6 +2273,10 @@ int falcon_switch_mac(struct efx_nic *efx)
 	struct efx_mac_operations *old_mac_op = efx->mac_op;
 	efx_oword_t nic_stat;
 	unsigned strap_val;
+	int rc = 0;
+
+	/* Don't try to fetch MAC stats while we're switching MACs */
+	efx_stats_disable(efx);
 
 	/* Internal loopbacks override the phy speed setting */
 	if (efx->loopback_mode == LOOPBACK_GMAC) {
@@ -2287,16 +2287,12 @@ int falcon_switch_mac(struct efx_nic *efx)
 		efx->link_fd = true;
 	}
 
+	WARN_ON(!mutex_is_locked(&efx->mac_lock));
 	efx->mac_op = (EFX_IS10G(efx) ?
 		       &falcon_xmac_operations : &falcon_gmac_operations);
-	if (old_mac_op == efx->mac_op)
-		return 0;
-
-	WARN_ON(!mutex_is_locked(&efx->mac_lock));
-
-	/* Not all macs support a mac-level link state */
-	efx->mac_up = true;
 
+	/* Always push the NIC_STAT_REG setting even if the mac hasn't
+	 * changed, because this function is run post online reset */
 	falcon_read(efx, &nic_stat, NIC_STAT_REG);
 	strap_val = EFX_IS10G(efx) ? 5 : 3;
 	if (falcon_rev(efx) >= FALCON_REV_B0) {
@@ -2309,9 +2305,17 @@ int falcon_switch_mac(struct efx_nic *efx)
 		BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val);
 	}
 
+	if (old_mac_op == efx->mac_op)
+		goto out;
 
 	EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G');
-	return falcon_reset_macs(efx);
+	/* Not all macs support a mac-level link state */
+	efx->mac_up = true;
+
+	rc = falcon_reset_macs(efx);
+out:
+	efx_stats_enable(efx);
+	return rc;
 }
 
 /* This call is responsible for hooking in the MAC and PHY operations */
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index f6a16428113d..f9e2f95c3b48 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -15,6 +15,7 @@
 #include "net_driver.h"
 #include "mdio_10g.h"
 #include "boards.h"
+#include "workarounds.h"
 
 int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
 			    int spins, int spintime)
@@ -179,17 +180,12 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
 		return false;
 	else if (efx_phy_mode_disabled(efx->phy_mode))
 		return false;
-	else if (efx->loopback_mode == LOOPBACK_PHYXS) {
+	else if (efx->loopback_mode == LOOPBACK_PHYXS)
 		mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS |
 			      MDIO_MMDREG_DEVS_PCS |
 			      MDIO_MMDREG_DEVS_PMAPMD |
 			      MDIO_MMDREG_DEVS_AN);
-		if (!mmd_mask) {
-			reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
-						 MDIO_PHYXS_STATUS2);
-			return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
-		}
-	} else if (efx->loopback_mode == LOOPBACK_PCS)
+	else if (efx->loopback_mode == LOOPBACK_PCS)
 		mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS |
 			      MDIO_MMDREG_DEVS_PMAPMD |
 			      MDIO_MMDREG_DEVS_AN);
@@ -197,6 +193,13 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
 		mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD |
 			      MDIO_MMDREG_DEVS_AN);
 
+	if (!mmd_mask) {
+		/* Use presence of XGMII faults in leui of link state */
+		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
+					 MDIO_PHYXS_STATUS2);
+		return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
+	}
+
 	while (mmd_mask) {
 		if (mmd_mask & 1) {
 			/* Double reads because link state is latched, and a
@@ -263,7 +266,7 @@ void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
 	}
 }
 
-static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp)
+static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr)
 {
 	int phy_id = efx->mii.phy_id;
 	u32 result = 0;
@@ -278,9 +281,6 @@ static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp)
 		result |= ADVERTISED_100baseT_Half;
 	if (reg & ADVERTISE_100FULL)
 		result |= ADVERTISED_100baseT_Full;
-	if (reg & LPA_RESV)
-		result |= xnp;
-
 	return result;
 }
 
@@ -310,7 +310,7 @@ void mdio_clause45_get_settings(struct efx_nic *efx,
  */
 void mdio_clause45_get_settings_ext(struct efx_nic *efx,
 				    struct ethtool_cmd *ecmd,
-				    u32 xnp, u32 xnp_lpa)
+				    u32 npage_adv, u32 npage_lpa)
 {
 	int phy_id = efx->mii.phy_id;
 	int reg;
@@ -361,8 +361,8 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx,
 			ecmd->autoneg = AUTONEG_ENABLE;
 			ecmd->advertising |=
 				ADVERTISED_Autoneg |
-				mdio_clause45_get_an(efx,
-						     MDIO_AN_ADVERTISE, xnp);
+				mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) |
+				npage_adv;
 		} else
 			ecmd->autoneg = AUTONEG_DISABLE;
 	} else
@@ -371,27 +371,30 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx,
 	if (ecmd->autoneg) {
 		/* If AN is complete, report best common mode,
 		 * otherwise report best advertised mode. */
-		u32 common = ecmd->advertising;
+		u32 modes = 0;
 		if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
 				       MDIO_MMDREG_STAT1) &
-		    (1 << MDIO_AN_STATUS_AN_DONE_LBN)) {
-			common &= mdio_clause45_get_an(efx, MDIO_AN_LPA,
-						       xnp_lpa);
-		}
-		if (common & ADVERTISED_10000baseT_Full) {
+		    (1 << MDIO_AN_STATUS_AN_DONE_LBN))
+			modes = (ecmd->advertising &
+				 (mdio_clause45_get_an(efx, MDIO_AN_LPA) |
+				  npage_lpa));
+		if (modes == 0)
+			modes = ecmd->advertising;
+
+		if (modes & ADVERTISED_10000baseT_Full) {
 			ecmd->speed = SPEED_10000;
 			ecmd->duplex = DUPLEX_FULL;
-		} else if (common & (ADVERTISED_1000baseT_Full |
-				     ADVERTISED_1000baseT_Half)) {
+		} else if (modes & (ADVERTISED_1000baseT_Full |
+				    ADVERTISED_1000baseT_Half)) {
 			ecmd->speed = SPEED_1000;
-			ecmd->duplex = !!(common & ADVERTISED_1000baseT_Full);
-		} else if (common & (ADVERTISED_100baseT_Full |
-				     ADVERTISED_100baseT_Half)) {
+			ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full);
+		} else if (modes & (ADVERTISED_100baseT_Full |
+				    ADVERTISED_100baseT_Half)) {
 			ecmd->speed = SPEED_100;
-			ecmd->duplex = !!(common & ADVERTISED_100baseT_Full);
+			ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
 		} else {
 			ecmd->speed = SPEED_10;
-			ecmd->duplex = !!(common & ADVERTISED_10baseT_Full);
+			ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
 		}
 	} else {
 		/* Report forced settings */
@@ -415,7 +418,7 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
 	int phy_id = efx->mii.phy_id;
 	struct ethtool_cmd prev;
 	u32 required;
-	int ctrl1_bits, reg;
+	int reg;
 
 	efx->phy_op->get_settings(efx, &prev);
 
@@ -430,99 +433,83 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
 	if (prev.port != PORT_TP || ecmd->port != PORT_TP)
 		return -EINVAL;
 
-	/* Check that PHY supports these settings and work out the
-	 * basic control bits */
-	if (ecmd->duplex) {
+	/* Check that PHY supports these settings */
+	if (ecmd->autoneg) {
+		required = SUPPORTED_Autoneg;
+	} else if (ecmd->duplex) {
 		switch (ecmd->speed) {
-		case SPEED_10:
-			ctrl1_bits = BMCR_FULLDPLX;
-			required = SUPPORTED_10baseT_Full;
-			break;
-		case SPEED_100:
-			ctrl1_bits = BMCR_SPEED100 | BMCR_FULLDPLX;
-			required = SUPPORTED_100baseT_Full;
-			break;
-		case SPEED_1000:
-			ctrl1_bits = BMCR_SPEED1000 | BMCR_FULLDPLX;
-			required = SUPPORTED_1000baseT_Full;
-			break;
-		case SPEED_10000:
-			ctrl1_bits = (BMCR_SPEED1000 | BMCR_SPEED100 |
-				      BMCR_FULLDPLX);
-			required = SUPPORTED_10000baseT_Full;
-			break;
-		default:
-			return -EINVAL;
+		case SPEED_10:  required = SUPPORTED_10baseT_Full;  break;
+		case SPEED_100: required = SUPPORTED_100baseT_Full; break;
+		default:        return -EINVAL;
 		}
 	} else {
 		switch (ecmd->speed) {
-		case SPEED_10:
-			ctrl1_bits = 0;
-			required = SUPPORTED_10baseT_Half;
-			break;
-		case SPEED_100:
-			ctrl1_bits = BMCR_SPEED100;
-			required = SUPPORTED_100baseT_Half;
-			break;
-		case SPEED_1000:
-			ctrl1_bits = BMCR_SPEED1000;
-			required = SUPPORTED_1000baseT_Half;
-			break;
-		default:
-			return -EINVAL;
+		case SPEED_10:  required = SUPPORTED_10baseT_Half;  break;
+		case SPEED_100: required = SUPPORTED_100baseT_Half; break;
+		default:        return -EINVAL;
 		}
 	}
-	if (ecmd->autoneg)
-		required |= SUPPORTED_Autoneg;
 	required |= ecmd->advertising;
 	if (required & ~prev.supported)
 		return -EINVAL;
 
-	/* Set the basic control bits */
-	reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-				 MDIO_MMDREG_CTRL1);
-	reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | 0x003c);
-	reg |= ctrl1_bits;
-	mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL1,
-			    reg);
-
-	/* Set the AN registers */
-	if (ecmd->autoneg != prev.autoneg ||
-	    ecmd->advertising != prev.advertising) {
-		bool xnp = false;
-
-		if (efx->phy_op->set_xnp_advertise)
-			xnp = efx->phy_op->set_xnp_advertise(efx,
-							     ecmd->advertising);
-
-		if (ecmd->autoneg) {
-			reg = 0;
-			if (ecmd->advertising & ADVERTISED_10baseT_Half)
-				reg |= ADVERTISE_10HALF;
-			if (ecmd->advertising & ADVERTISED_10baseT_Full)
-				reg |= ADVERTISE_10FULL;
-			if (ecmd->advertising & ADVERTISED_100baseT_Half)
-				reg |= ADVERTISE_100HALF;
-			if (ecmd->advertising & ADVERTISED_100baseT_Full)
-				reg |= ADVERTISE_100FULL;
-			if (xnp)
-				reg |= ADVERTISE_RESV;
-			mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
-					    MDIO_AN_ADVERTISE, reg);
-		}
+	if (ecmd->autoneg) {
+		bool xnp = (ecmd->advertising & ADVERTISED_10000baseT_Full
+			    || EFX_WORKAROUND_13204(efx));
+
+		/* Set up the base page */
+		reg = ADVERTISE_CSMA;
+		if (ecmd->advertising & ADVERTISED_10baseT_Half)
+			reg |= ADVERTISE_10HALF;
+		if (ecmd->advertising & ADVERTISED_10baseT_Full)
+			reg |= ADVERTISE_10FULL;
+		if (ecmd->advertising & ADVERTISED_100baseT_Half)
+			reg |= ADVERTISE_100HALF;
+		if (ecmd->advertising & ADVERTISED_100baseT_Full)
+			reg |= ADVERTISE_100FULL;
+		if (xnp)
+			reg |= ADVERTISE_RESV;
+		else if (ecmd->advertising & (ADVERTISED_1000baseT_Half |
+					      ADVERTISED_1000baseT_Full))
+			reg |= ADVERTISE_NPAGE;
+		reg |= efx_fc_advertise(efx->wanted_fc);
+		mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
+				    MDIO_AN_ADVERTISE, reg);
+
+		/* Set up the (extended) next page if necessary */
+		if (efx->phy_op->set_npage_adv)
+			efx->phy_op->set_npage_adv(efx, ecmd->advertising);
 
+		/* Enable and restart AN */
 		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
 					 MDIO_MMDREG_CTRL1);
-		if (ecmd->autoneg)
-			reg |= BMCR_ANENABLE | BMCR_ANRESTART;
-		else
-			reg &= ~BMCR_ANENABLE;
+		reg |= BMCR_ANENABLE;
+		if (!(EFX_WORKAROUND_15195(efx) &&
+		      LOOPBACK_MASK(efx) & efx->phy_op->loopbacks))
+			reg |= BMCR_ANRESTART;
 		if (xnp)
 			reg |= 1 << MDIO_AN_CTRL_XNP_LBN;
 		else
 			reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN);
 		mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
 				    MDIO_MMDREG_CTRL1, reg);
+	} else {
+		/* Disable AN */
+		mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
+				       MDIO_MMDREG_CTRL1,
+				       __ffs(BMCR_ANENABLE), false);
+
+		/* Set the basic control bits */
+		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
+					 MDIO_MMDREG_CTRL1);
+		reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX |
+			 0x003c);
+		if (ecmd->speed == SPEED_100)
+			reg |= BMCR_SPEED100;
+		if (ecmd->duplex)
+			reg |= BMCR_FULLDPLX;
+		mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
+				    MDIO_MMDREG_CTRL1, reg);
 	}
 
 	return 0;
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 09bf801d0569..8ba49773ce7e 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -155,7 +155,8 @@
 #define MDIO_AN_XNP			22
 #define MDIO_AN_LPA_XNP			25
 
-#define MDIO_AN_10GBT_ADVERTISE		32
+#define MDIO_AN_10GBT_CTRL		32
+#define MDIO_AN_10GBT_CTRL_ADV_10G_LBN	12
 #define MDIO_AN_10GBT_STATUS		(33)
 #define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */
 #define MDIO_AN_10GBT_STATUS_MS_LBN     (14) /* MASTER/SLAVE config */
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 5f255f75754e..e019ad1fb9a0 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -566,7 +566,7 @@ struct efx_mac_operations {
  * @poll: Poll for hardware state. Serialised by the mac_lock.
  * @get_settings: Get ethtool settings. Serialised by the mac_lock.
  * @set_settings: Set ethtool settings. Serialised by the mac_lock.
- * @set_xnp_advertise: Set abilities advertised in Extended Next Page
+ * @set_npage_adv: Set abilities advertised in (Extended) Next Page
  *	(only needed where AN bit is set in mmds)
  * @num_tests: Number of PHY-specific tests/results
  * @test_names: Names of the tests/results
@@ -586,7 +586,7 @@ struct efx_phy_operations {
 			      struct ethtool_cmd *ecmd);
 	int (*set_settings) (struct efx_nic *efx,
 			     struct ethtool_cmd *ecmd);
-	bool (*set_xnp_advertise) (struct efx_nic *efx, u32);
+	void (*set_npage_adv) (struct efx_nic *efx, u32);
 	u32 num_tests;
 	const char *const *test_names;
 	int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags);
@@ -754,8 +754,7 @@ union efx_multicast_hash {
  *	&struct net_device_stats.
  * @stats_buffer: DMA buffer for statistics
  * @stats_lock: Statistics update lock. Serialises statistics fetches
- * @stats_enabled: Temporarily disable statistics fetches.
- *	Serialised by @stats_lock
+ * @stats_disable_count: Nest count for disabling statistics fetches
  * @mac_op: MAC interface
  * @mac_address: Permanent MAC address
  * @phy_type: PHY type
@@ -837,7 +836,7 @@ struct efx_nic {
 	struct efx_mac_stats mac_stats;
 	struct efx_buffer stats_buffer;
 	spinlock_t stats_lock;
-	bool stats_enabled;
+	unsigned int stats_disable_count;
 
 	struct efx_mac_operations *mac_op;
 	unsigned char mac_address[ETH_ALEN];
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index 58c493ef81bb..07e855c148bc 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -17,7 +17,6 @@ extern struct efx_phy_operations falcon_sfx7101_phy_ops;
 extern struct efx_phy_operations falcon_sft9001_phy_ops;
 
 extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
-extern void tenxpress_crc_err(struct efx_nic *efx);
 
 /****************************************************************************
  * Exported functions from the driver for XFP optical PHYs
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index dba0d64d50cd..0a598084c513 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -665,6 +665,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
 {
 	enum efx_loopback_mode loopback_mode = efx->loopback_mode;
 	int phy_mode = efx->phy_mode;
+	enum reset_type reset_method = RESET_TYPE_INVISIBLE;
 	struct ethtool_cmd ecmd;
 	struct efx_channel *channel;
 	int rc_test = 0, rc_reset = 0, rc;
@@ -718,21 +719,21 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
 	mutex_unlock(&efx->mac_lock);
 
 	/* free up all consumers of SRAM (including all the queues) */
-	efx_reset_down(efx, &ecmd);
+	efx_reset_down(efx, reset_method, &ecmd);
 
 	rc = efx_test_chip(efx, tests);
 	if (rc && !rc_test)
 		rc_test = rc;
 
 	/* reset the chip to recover from the register test */
-	rc_reset = falcon_reset_hw(efx, RESET_TYPE_ALL);
+	rc_reset = falcon_reset_hw(efx, reset_method);
 
 	/* Ensure that the phy is powered and out of loopback
 	 * for the bist and loopback tests */
 	efx->phy_mode &= ~PHY_MODE_LOW_POWER;
 	efx->loopback_mode = LOOPBACK_NONE;
 
-	rc = efx_reset_up(efx, &ecmd, rc_reset == 0);
+	rc = efx_reset_up(efx, reset_method, &ecmd, rc_reset == 0);
 	if (rc && !rc_reset)
 		rc_reset = rc;
 
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index 16b80acb9992..cb25ae5b257a 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -186,19 +186,22 @@ static int sfn4111t_reset(struct efx_nic *efx)
 {
 	efx_oword_t reg;
 
-	/* GPIO pins are also used for I2C, so block that temporarily */
+	/* GPIO 3 and the GPIO register are shared with I2C, so block that */
 	mutex_lock(&efx->i2c_adap.bus_lock);
 
+	/* Pull RST_N (GPIO 2) low then let it up again, setting the
+	 * FLASH_CFG_1 strap (GPIO 3) appropriately.  Only change the
+	 * output enables; the output levels should always be 0 (low)
+	 * and we rely on external pull-ups. */
 	falcon_read(efx, &reg, GPIO_CTL_REG_KER);
 	EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true);
-	EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, false);
 	falcon_write(efx, &reg, GPIO_CTL_REG_KER);
 	msleep(1000);
-	EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, true);
-	EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, true);
-	EFX_SET_OWORD_FIELD(reg, GPIO3_OUT,
-			    !(efx->phy_mode & PHY_MODE_SPECIAL));
+	EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, false);
+	EFX_SET_OWORD_FIELD(reg, GPIO3_OEN,
+			    !!(efx->phy_mode & PHY_MODE_SPECIAL));
 	falcon_write(efx, &reg, GPIO_CTL_REG_KER);
+	msleep(1);
 
 	mutex_unlock(&efx->i2c_adap.bus_lock);
 
@@ -232,12 +235,18 @@ static ssize_t set_phy_flash_cfg(struct device *dev,
 	} else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
 		err = -EBUSY;
 	} else {
+		/* Reset the PHY, reconfigure the MAC and enable/disable
+		 * MAC stats accordingly. */
 		efx->phy_mode = new_mode;
+		if (new_mode & PHY_MODE_SPECIAL)
+			efx_stats_disable(efx);
 		if (efx->board_info.type == EFX_BOARD_SFE4001)
 			err = sfe4001_poweron(efx);
 		else
 			err = sfn4111t_reset(efx);
 		efx_reconfigure_port(efx);
+		if (!(new_mode & PHY_MODE_SPECIAL))
+			efx_stats_enable(efx);
 	}
 	rtnl_unlock();
 
@@ -326,6 +335,11 @@ int sfe4001_init(struct efx_nic *efx)
 	efx->board_info.monitor = sfe4001_check_hw;
 	efx->board_info.fini = sfe4001_fini;
 
+	if (efx->phy_mode & PHY_MODE_SPECIAL) {
+		/* PHY won't generate a 156.25 MHz clock and MAC stats fetch
+		 * will fail. */
+		efx_stats_disable(efx);
+	}
 	rc = sfe4001_poweron(efx);
 	if (rc)
 		goto fail_ioexp;
@@ -372,17 +386,25 @@ static void sfn4111t_fini(struct efx_nic *efx)
 	i2c_unregister_device(efx->board_info.hwmon_client);
 }
 
-static struct i2c_board_info sfn4111t_hwmon_info = {
+static struct i2c_board_info sfn4111t_a0_hwmon_info = {
 	I2C_BOARD_INFO("max6647", 0x4e),
 	.irq		= -1,
 };
 
+static struct i2c_board_info sfn4111t_r5_hwmon_info = {
+	I2C_BOARD_INFO("max6646", 0x4d),
+	.irq		= -1,
+};
+
 int sfn4111t_init(struct efx_nic *efx)
 {
 	int rc;
 
 	efx->board_info.hwmon_client =
-		i2c_new_device(&efx->i2c_adap, &sfn4111t_hwmon_info);
+		i2c_new_device(&efx->i2c_adap,
+			       (efx->board_info.minor < 5) ?
+			       &sfn4111t_a0_hwmon_info :
+			       &sfn4111t_r5_hwmon_info);
 	if (!efx->board_info.hwmon_client)
 		return -EIO;
 
@@ -394,8 +416,10 @@ int sfn4111t_init(struct efx_nic *efx)
 	if (rc)
 		goto fail_hwmon;
 
-	if (efx->phy_mode & PHY_MODE_SPECIAL)
+	if (efx->phy_mode & PHY_MODE_SPECIAL) {
+		efx_stats_disable(efx);
 		sfn4111t_reset(efx);
+	}
 
 	return 0;
 
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 9ecb77da9545..f0efd246962c 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -67,6 +67,8 @@
 #define PMA_PMD_EXT_CLK312_WIDTH 1
 #define PMA_PMD_EXT_LPOWER_LBN  12
 #define PMA_PMD_EXT_LPOWER_WIDTH 1
+#define PMA_PMD_EXT_ROBUST_LBN	14
+#define PMA_PMD_EXT_ROBUST_WIDTH 1
 #define PMA_PMD_EXT_SSR_LBN	15
 #define PMA_PMD_EXT_SSR_WIDTH	1
 
@@ -177,35 +179,24 @@
 #define C22EXT_STATUS_LINK_LBN  2
 #define C22EXT_STATUS_LINK_WIDTH 1
 
-#define C22EXT_MSTSLV_REG       49162
-#define C22EXT_MSTSLV_1000_HD_LBN 10
-#define C22EXT_MSTSLV_1000_HD_WIDTH 1
-#define C22EXT_MSTSLV_1000_FD_LBN 11
-#define C22EXT_MSTSLV_1000_FD_WIDTH 1
+#define C22EXT_MSTSLV_CTRL			49161
+#define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN	8
+#define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN	9
+
+#define C22EXT_MSTSLV_STATUS			49162
+#define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN	10
+#define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN	11
 
 /* Time to wait between powering down the LNPGA and turning off the power
  * rails */
 #define LNPGA_PDOWN_WAIT	(HZ / 5)
 
-static int crc_error_reset_threshold = 100;
-module_param(crc_error_reset_threshold, int, 0644);
-MODULE_PARM_DESC(crc_error_reset_threshold,
-		 "Max number of CRC errors before XAUI reset");
-
 struct tenxpress_phy_data {
 	enum efx_loopback_mode loopback_mode;
-	atomic_t bad_crc_count;
 	enum efx_phy_mode phy_mode;
 	int bad_lp_tries;
 };
 
-void tenxpress_crc_err(struct efx_nic *efx)
-{
-	struct tenxpress_phy_data *phy_data = efx->phy_data;
-	if (phy_data != NULL)
-		atomic_inc(&phy_data->bad_crc_count);
-}
-
 static ssize_t show_phy_short_reach(struct device *dev,
 				    struct device_attribute *attr, char *buf)
 {
@@ -284,7 +275,9 @@ static int tenxpress_init(struct efx_nic *efx)
 					 PMA_PMD_XCONTROL_REG);
 		reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) |
 			(1 << PMA_PMD_EXT_CLK_OUT_LBN) |
-			(1 << PMA_PMD_EXT_CLK312_LBN));
+			(1 << PMA_PMD_EXT_CLK312_LBN) |
+			(1 << PMA_PMD_EXT_ROBUST_LBN));
+
 		mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
 				    PMA_PMD_XCONTROL_REG, reg);
 		mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
@@ -346,6 +339,7 @@ static int tenxpress_phy_init(struct efx_nic *efx)
 	rc = tenxpress_init(efx);
 	if (rc < 0)
 		goto fail;
+	mdio_clause45_set_pause(efx);
 
 	if (efx->phy_type == PHY_TYPE_SFT9001B) {
 		rc = device_create_file(&efx->pci_dev->dev,
@@ -376,8 +370,8 @@ static int tenxpress_special_reset(struct efx_nic *efx)
 
 	/* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
 	 * a special software reset can glitch the XGMAC sufficiently for stats
-	 * requests to fail. Since we don't often special_reset, just lock. */
-	spin_lock(&efx->stats_lock);
+	 * requests to fail. */
+	efx_stats_disable(efx);
 
 	/* Initiate reset */
 	reg = mdio_clause45_read(efx, efx->mii.phy_id,
@@ -392,17 +386,17 @@ static int tenxpress_special_reset(struct efx_nic *efx)
 	rc = mdio_clause45_wait_reset_mmds(efx,
 					   TENXPRESS_REQUIRED_DEVS);
 	if (rc < 0)
-		goto unlock;
+		goto out;
 
 	/* Try and reconfigure the device */
 	rc = tenxpress_init(efx);
 	if (rc < 0)
-		goto unlock;
+		goto out;
 
 	/* Wait for the XGXS state machine to churn */
 	mdelay(10);
-unlock:
-	spin_unlock(&efx->stats_lock);
+out:
+	efx_stats_enable(efx);
 	return rc;
 }
 
@@ -520,7 +514,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
 {
 	struct tenxpress_phy_data *phy_data = efx->phy_data;
 	struct ethtool_cmd ecmd;
-	bool phy_mode_change, loop_reset, loop_toggle, loopback;
+	bool phy_mode_change, loop_reset;
 
 	if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
 		phy_data->phy_mode = efx->phy_mode;
@@ -531,12 +525,10 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
 
 	phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
 			   phy_data->phy_mode != PHY_MODE_NORMAL);
-	loopback = LOOPBACK_MASK(efx) & efx->phy_op->loopbacks;
-	loop_toggle = LOOPBACK_CHANGED(phy_data, efx, efx->phy_op->loopbacks);
 	loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) ||
 		      LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
 
-	if (loop_reset || loop_toggle || loopback || phy_mode_change) {
+	if (loop_reset || phy_mode_change) {
 		int rc;
 
 		efx->phy_op->get_settings(efx, &ecmd);
@@ -551,20 +543,6 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
 				falcon_reset_xaui(efx);
 		}
 
-		if (efx->phy_type != PHY_TYPE_SFX7101) {
-			/* Only change autoneg once, on coming out or
-			 * going into loopback */
-			if (loop_toggle)
-				ecmd.autoneg = !loopback;
-			if (loopback) {
-				ecmd.duplex = DUPLEX_FULL;
-				if (efx->loopback_mode == LOOPBACK_GPHY)
-					ecmd.speed = SPEED_1000;
-				else
-					ecmd.speed = SPEED_10000;
-			}
-		}
-
 		rc = efx->phy_op->set_settings(efx, &ecmd);
 		WARN_ON(rc);
 	}
@@ -623,13 +601,6 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
 
 	if (phy_data->phy_mode != PHY_MODE_NORMAL)
 		return;
-
-	if (EFX_WORKAROUND_10750(efx) &&
-	    atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) {
-		EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n");
-		falcon_reset_xaui(efx);
-		atomic_set(&phy_data->bad_crc_count, 0);
-	}
 }
 
 static void tenxpress_phy_fini(struct efx_nic *efx)
@@ -772,107 +743,76 @@ reset:
 	return rc;
 }
 
-static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx)
+static void
+tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 {
-	int phy = efx->mii.phy_id;
-	u32 lpa = 0;
+	int phy_id = efx->mii.phy_id;
+	u32 adv = 0, lpa = 0;
 	int reg;
 
 	if (efx->phy_type != PHY_TYPE_SFX7101) {
-		reg = mdio_clause45_read(efx, phy, MDIO_MMD_C22EXT,
-					 C22EXT_MSTSLV_REG);
-		if (reg & (1 << C22EXT_MSTSLV_1000_HD_LBN))
+		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
+					 C22EXT_MSTSLV_CTRL);
+		if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN))
+			adv |= ADVERTISED_1000baseT_Full;
+		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
+					 C22EXT_MSTSLV_STATUS);
+		if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN))
 			lpa |= ADVERTISED_1000baseT_Half;
-		if (reg & (1 << C22EXT_MSTSLV_1000_FD_LBN))
+		if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN))
 			lpa |= ADVERTISED_1000baseT_Full;
 	}
-	reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS);
+	reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
+				 MDIO_AN_10GBT_CTRL);
+	if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN))
+		adv |= ADVERTISED_10000baseT_Full;
+	reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
+				 MDIO_AN_10GBT_STATUS);
 	if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN))
 		lpa |= ADVERTISED_10000baseT_Full;
-	return lpa;
-}
 
-static void sfx7101_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
-{
-	mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full,
-				       tenxpress_get_xnp_lpa(efx));
-	ecmd->supported |= SUPPORTED_10000baseT_Full;
-	ecmd->advertising |= ADVERTISED_10000baseT_Full;
+	mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa);
+
+	if (efx->phy_type != PHY_TYPE_SFX7101)
+		ecmd->supported |= (SUPPORTED_100baseT_Full |
+				    SUPPORTED_1000baseT_Full);
+
+	/* In loopback, the PHY automatically brings up the correct interface,
+	 * but doesn't advertise the correct speed. So override it */
+	if (efx->loopback_mode == LOOPBACK_GPHY)
+		ecmd->speed = SPEED_1000;
+	else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)
+		ecmd->speed = SPEED_10000;
 }
 
-static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 {
-	int phy_id = efx->mii.phy_id;
-	u32 xnp_adv = 0;
-	int reg;
-
-	reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-				 PMA_PMD_SPEED_ENABLE_REG);
-	if (EFX_WORKAROUND_13204(efx) && (reg & (1 << PMA_PMD_100TX_ADV_LBN)))
-		xnp_adv |= ADVERTISED_100baseT_Full;
-	if (reg & (1 << PMA_PMD_1000T_ADV_LBN))
-		xnp_adv |= ADVERTISED_1000baseT_Full;
-	if (reg & (1 << PMA_PMD_10000T_ADV_LBN))
-		xnp_adv |= ADVERTISED_10000baseT_Full;
-
-	mdio_clause45_get_settings_ext(efx, ecmd, xnp_adv,
-				       tenxpress_get_xnp_lpa(efx));
-
-	ecmd->supported |= (SUPPORTED_100baseT_Half |
-			    SUPPORTED_100baseT_Full |
-			    SUPPORTED_1000baseT_Full);
+	if (!ecmd->autoneg)
+		return -EINVAL;
 
-	/* Use the vendor defined C22ext register for duplex settings */
-	if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) {
-		reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
-					 GPHY_XCONTROL_REG);
-		ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ?
-				DUPLEX_FULL : DUPLEX_HALF);
-	}
+	return mdio_clause45_set_settings(efx, ecmd);
 }
 
-static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
 {
-	int phy_id = efx->mii.phy_id;
-	int rc;
-
-	rc = mdio_clause45_set_settings(efx, ecmd);
-	if (rc)
-		return rc;
-
-	if (ecmd->speed != SPEED_10000 && !ecmd->autoneg)
-		mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
-				       GPHY_XCONTROL_REG, GPHY_DUPLEX_LBN,
-				       ecmd->duplex == DUPLEX_FULL);
-
-	return rc;
+	mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
+			       MDIO_AN_10GBT_CTRL,
+			       MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
+			       advertising & ADVERTISED_10000baseT_Full);
 }
 
-static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising)
+static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising)
 {
-	int phy = efx->mii.phy_id;
-	int reg = mdio_clause45_read(efx, phy, MDIO_MMD_PMAPMD,
-				     PMA_PMD_SPEED_ENABLE_REG);
-	bool enabled;
-
-	reg &= ~((1 << 2) | (1 << 3));
-	if (EFX_WORKAROUND_13204(efx) &&
-	    (advertising & ADVERTISED_100baseT_Full))
-		reg |= 1 << PMA_PMD_100TX_ADV_LBN;
-	if (advertising & ADVERTISED_1000baseT_Full)
-		reg |= 1 << PMA_PMD_1000T_ADV_LBN;
-	if (advertising & ADVERTISED_10000baseT_Full)
-		reg |= 1 << PMA_PMD_10000T_ADV_LBN;
-	mdio_clause45_write(efx, phy, MDIO_MMD_PMAPMD,
-			    PMA_PMD_SPEED_ENABLE_REG, reg);
-
-	enabled = (advertising &
-		   (ADVERTISED_1000baseT_Half |
-		    ADVERTISED_1000baseT_Full |
-		    ADVERTISED_10000baseT_Full));
-	if (EFX_WORKAROUND_13204(efx))
-		enabled |= (advertising & ADVERTISED_100baseT_Full);
-	return enabled;
+	int phy_id = efx->mii.phy_id;
+
+	mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
+			       C22EXT_MSTSLV_CTRL,
+			       C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
+			       advertising & ADVERTISED_1000baseT_Full);
+	mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
+			       MDIO_AN_10GBT_CTRL,
+			       MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
+			       advertising & ADVERTISED_10000baseT_Full);
 }
 
 struct efx_phy_operations falcon_sfx7101_phy_ops = {
@@ -882,8 +822,9 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = {
 	.poll             = tenxpress_phy_poll,
 	.fini             = tenxpress_phy_fini,
 	.clear_interrupt  = efx_port_dummy_op_void,
-	.get_settings	  = sfx7101_get_settings,
-	.set_settings	  = mdio_clause45_set_settings,
+	.get_settings	  = tenxpress_get_settings,
+	.set_settings	  = tenxpress_set_settings,
+	.set_npage_adv    = sfx7101_set_npage_adv,
 	.num_tests	  = ARRAY_SIZE(sfx7101_test_names),
 	.test_names	  = sfx7101_test_names,
 	.run_tests	  = sfx7101_run_tests,
@@ -898,9 +839,9 @@ struct efx_phy_operations falcon_sft9001_phy_ops = {
 	.poll             = tenxpress_phy_poll,
 	.fini             = tenxpress_phy_fini,
 	.clear_interrupt  = efx_port_dummy_op_void,
-	.get_settings	  = sft9001_get_settings,
-	.set_settings	  = sft9001_set_settings,
-	.set_xnp_advertise = sft9001_set_xnp_advertise,
+	.get_settings	  = tenxpress_get_settings,
+	.set_settings	  = tenxpress_set_settings,
+	.set_npage_adv    = sft9001_set_npage_adv,
 	.num_tests	  = ARRAY_SIZE(sft9001_test_names),
 	.test_names	  = sft9001_test_names,
 	.run_tests	  = sft9001_run_tests,
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index 82e03e1d7371..78de68f4a95b 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -18,8 +18,8 @@
 #define EFX_WORKAROUND_ALWAYS(efx) 1
 #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1)
 #define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx)
-#define EFX_WORKAROUND_SFX7101(efx) ((efx)->phy_type == PHY_TYPE_SFX7101)
-#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A)
+#define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \
+				     (efx)->phy_type == PHY_TYPE_SFT9001B)
 
 /* XAUI resets if link not detected */
 #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS
@@ -29,8 +29,6 @@
 #define EFX_WORKAROUND_7884 EFX_WORKAROUND_10G
 /* TX pkt parser problem with <= 16 byte TXes */
 #define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS
-/* Low rate CRC errors require XAUI reset */
-#define EFX_WORKAROUND_10750 EFX_WORKAROUND_SFX7101
 /* TX_EV_PKT_ERR can be caused by a dangling TX descriptor
  * or a PCIe error (bug 11028) */
 #define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS
@@ -55,8 +53,8 @@
 #define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A
 
 /* Need to send XNP pages for 100BaseT */
-#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001A
-/* Need to keep AN enabled */
-#define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A
+#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001
+/* Don't restart AN in near-side loopback */
+#define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001
 
 #endif /* EFX_WORKAROUNDS_H */
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 3668e81e474d..994703cc0db3 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1403,9 +1403,6 @@ static int sky2_up(struct net_device *dev)
 
  	}
 
-	if (netif_msg_ifup(sky2))
-		printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
-
 	netif_carrier_off(dev);
 
 	/* must be power of 2 */
@@ -1484,6 +1481,9 @@ static int sky2_up(struct net_device *dev)
 	sky2_write32(hw, B0_IMSK, imask);
 
 	sky2_set_multicast(dev);
+
+	if (netif_msg_ifup(sky2))
+		printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
 	return 0;
 
 err_out:
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index bf3aa2a1effe..223cde0d43be 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -220,9 +220,9 @@ static void smc911x_reset(struct net_device *dev)
 
 	/* make sure EEPROM has finished loading before setting GPIO_CFG */
 	timeout=1000;
-	while ( timeout-- && (SMC_GET_E2P_CMD(lp) & E2P_CMD_EPC_BUSY_)) {
+	while (--timeout && (SMC_GET_E2P_CMD(lp) & E2P_CMD_EPC_BUSY_))
 		udelay(10);
-	}
+
 	if (timeout == 0){
 		PRINTK("%s: smc911x_reset timeout waiting for EEPROM busy\n", dev->name);
 		return;
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index d801900a5036..a1e4b3895b33 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -498,7 +498,7 @@ static void smsc9420_check_mac_address(struct net_device *dev)
 static void smsc9420_stop_tx(struct smsc9420_pdata *pd)
 {
 	u32 dmac_control, mac_cr, dma_intr_ena;
-	int timeOut = 1000;
+	int timeout = 1000;
 
 	/* disable TX DMAC */
 	dmac_control = smsc9420_reg_read(pd, DMAC_CONTROL);
@@ -506,13 +506,13 @@ static void smsc9420_stop_tx(struct smsc9420_pdata *pd)
 	smsc9420_reg_write(pd, DMAC_CONTROL, dmac_control);
 
 	/* Wait max 10ms for transmit process to stop */
-	while (timeOut--) {
+	while (--timeout) {
 		if (smsc9420_reg_read(pd, DMAC_STATUS) & DMAC_STS_TS_)
 			break;
 		udelay(10);
 	}
 
-	if (!timeOut)
+	if (!timeout)
 		smsc_warn(IFDOWN, "TX DMAC failed to stop");
 
 	/* ACK Tx DMAC stop bit */
@@ -596,7 +596,7 @@ static void smsc9420_free_rx_ring(struct smsc9420_pdata *pd)
 
 static void smsc9420_stop_rx(struct smsc9420_pdata *pd)
 {
-	int timeOut = 1000;
+	int timeout = 1000;
 	u32 mac_cr, dmac_control, dma_intr_ena;
 
 	/* mask RX DMAC interrupts */
@@ -617,13 +617,13 @@ static void smsc9420_stop_rx(struct smsc9420_pdata *pd)
 	smsc9420_pci_flush_write(pd);
 
 	/* wait up to 10ms for receive to stop */
-	while (timeOut--) {
+	while (--timeout) {
 		if (smsc9420_reg_read(pd, DMAC_STATUS) & DMAC_STS_RS_)
 			break;
 		udelay(10);
 	}
 
-	if (!timeOut)
+	if (!timeout)
 		smsc_warn(IFDOWN, "RX DMAC did not stop! timeout.");
 
 	/* ACK the Rx DMAC stop bit */
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 86c765d83de1..b17efa9cc530 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -148,7 +148,7 @@ static u16 __phy_read(struct gem *gp, int phy_addr, int reg)
 	cmd |= (MIF_FRAME_TAMSB);
 	writel(cmd, gp->regs + MIF_FRAME);
 
-	while (limit--) {
+	while (--limit) {
 		cmd = readl(gp->regs + MIF_FRAME);
 		if (cmd & MIF_FRAME_TALSB)
 			break;
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
index 61843fd57525..78f8cee5fd74 100644
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -79,7 +79,7 @@ static int reset_one_mii_phy(struct mii_phy* phy, int phy_id)
 
 	udelay(100);
 
-	while (limit--) {
+	while (--limit) {
 		val = __phy_read(phy, phy_id, MII_BMCR);
 		if ((val & BMCR_RESET) == 0)
 			break;
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index 6e8f377355fe..fe0c3f244562 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -227,7 +227,7 @@ static int qe_init(struct sunqe *qep, int from_irq)
 	if (!(sbus_readb(mregs + MREGS_PHYCONFIG) & MREGS_PHYCONFIG_LTESTDIS)) {
 		int tries = 50;
 
-		while (tries--) {
+		while (--tries) {
 			u8 tmp;
 
 			mdelay(5);
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 75461dbd4876..a9fd2b2ccaf6 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -1237,7 +1237,7 @@ static void tsi108_init_phy(struct net_device *dev)
 	spin_lock_irqsave(&phy_lock, flags);
 
 	tsi108_write_mii(data, MII_BMCR, BMCR_RESET);
-	while (i--){
+	while (--i) {
 		if(!(tsi108_read_mii(data, MII_BMCR) & BMCR_RESET))
 			break;
 		udelay(10);
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index d5d53b633cf8..0bf2114738be 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -392,7 +392,7 @@ static void de_rx (struct de_private *de)
 	unsigned drop = 0;
 	int rc;
 
-	while (rx_work--) {
+	while (--rx_work) {
 		u32 status, len;
 		dma_addr_t mapping;
 		struct sk_buff *skb, *copy_skb;
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 0d0fa91c0251..fe98acaead97 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -455,6 +455,7 @@ static const struct usb_device_id hso_ids[] = {
 	{icon321_port_device(0x0af0, 0xd033)},	/* Icon-322 */
 	{USB_DEVICE(0x0af0, 0x7301)},		/* GE40x */
 	{USB_DEVICE(0x0af0, 0x7361)},		/* GE40x */
+	{USB_DEVICE(0x0af0, 0x7381)},		/* GE40x */
 	{USB_DEVICE(0x0af0, 0x7401)},		/* GI 0401 */
 	{USB_DEVICE(0x0af0, 0x7501)},		/* GTM 382 */
 	{USB_DEVICE(0x0af0, 0x7601)},		/* GE40x */
@@ -462,7 +463,8 @@ static const struct usb_device_id hso_ids[] = {
 	{USB_DEVICE(0x0af0, 0x7801)},
 	{USB_DEVICE(0x0af0, 0x7901)},
 	{USB_DEVICE(0x0af0, 0x7361)},
-	{icon321_port_device(0x0af0, 0xd051)},
+	{USB_DEVICE(0x0af0, 0xd057)},
+	{USB_DEVICE(0x0af0, 0xd055)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, hso_ids);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index b35c8813bef4..c01ea48da5fe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -4042,6 +4042,7 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 		priv->is_open = 1;
 	}
 
+	pci_save_state(pdev);
 	pci_set_power_state(pdev, PCI_D3hot);
 
 	return 0;
@@ -4052,6 +4053,7 @@ static int iwl_pci_resume(struct pci_dev *pdev)
 	struct iwl_priv *priv = pci_get_drvdata(pdev);
 
 	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
 
 	if (priv->is_open)
 		iwl_mac_start(priv->hw);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 412f66bac1af..70a8b21ca39b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -480,6 +480,9 @@ void iwl_clear_stations_table(struct iwl_priv *priv)
 	priv->num_stations = 0;
 	memset(priv->stations, 0, sizeof(priv->stations));
 
+	/* clean ucode key table bit map */
+	priv->ucode_key_table = 0;
+
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 }
 EXPORT_SYMBOL(iwl_clear_stations_table);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 95d01984c80e..5b44d322b99f 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -8143,6 +8143,7 @@ static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 		priv->is_open = 1;
 	}
 
+	pci_save_state(pdev);
 	pci_set_power_state(pdev, PCI_D3hot);
 
 	return 0;
@@ -8153,6 +8154,7 @@ static int iwl3945_pci_resume(struct pci_dev *pdev)
 	struct iwl3945_priv *priv = pci_get_drvdata(pdev);
 
 	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
 
 	if (priv->is_open)
 		iwl3945_mac_start(priv->hw);
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index e31fb91652ce..2aa117c8cd87 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -5,11 +5,15 @@
 obj-$(CONFIG_HOTPLUG_PCI)		+= pci_hotplug.o
 obj-$(CONFIG_HOTPLUG_PCI_COMPAQ)	+= cpqphp.o
 obj-$(CONFIG_HOTPLUG_PCI_IBM)		+= ibmphp.o
+
+# pciehp should be linked before acpiphp in order to allow the native driver
+# to attempt to bind first. We can then fall back to generic support.
+
+obj-$(CONFIG_HOTPLUG_PCI_PCIE)		+= pciehp.o
 obj-$(CONFIG_HOTPLUG_PCI_ACPI)		+= acpiphp.o
 obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM)	+= acpiphp_ibm.o
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550)	+= cpcihp_zt5550.o
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC)	+= cpcihp_generic.o
-obj-$(CONFIG_HOTPLUG_PCI_PCIE)		+= pciehp.o
 obj-$(CONFIG_HOTPLUG_PCI_SHPC)		+= shpchp.o
 obj-$(CONFIG_HOTPLUG_PCI_RPA)		+= rpaphp.o
 obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR)	+= rpadlpar_io.o
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
index b0e7de9e536d..d8649e127298 100644
--- a/drivers/pci/hotplug/fakephp.c
+++ b/drivers/pci/hotplug/fakephp.c
@@ -195,13 +195,13 @@ static void remove_slot_worker(struct work_struct *work)
  * Tries hard not to re-enable already existing devices;
  * also handles scanning of subfunctions.
  */
-static void pci_rescan_slot(struct pci_dev *temp)
+static int pci_rescan_slot(struct pci_dev *temp)
 {
 	struct pci_bus *bus = temp->bus;
 	struct pci_dev *dev;
 	int func;
-	int retval;
 	u8 hdr_type;
+	int count = 0;
 
 	if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
 		temp->hdr_type = hdr_type & 0x7f;
@@ -213,17 +213,12 @@ static void pci_rescan_slot(struct pci_dev *temp)
 				dbg("New device on %s function %x:%x\n",
 					bus->name, temp->devfn >> 3,
 					temp->devfn & 7);
-				retval = pci_bus_add_device(dev);
-				if (retval)
-					dev_err(&dev->dev, "error adding "
-						"device, continuing.\n");
-				else
-					add_slot(dev);
+				count++;
 			}
 		}
 		/* multifunction device? */
 		if (!(hdr_type & 0x80))
-			return;
+			return count;
 
 		/* continue scanning for other functions */
 		for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
@@ -239,16 +234,13 @@ static void pci_rescan_slot(struct pci_dev *temp)
 					dbg("New device on %s function %x:%x\n",
 						bus->name, temp->devfn >> 3,
 						temp->devfn & 7);
-					retval = pci_bus_add_device(dev);
-					if (retval)
-						dev_err(&dev->dev, "error adding "
-							"device, continuing.\n");
-					else
-						add_slot(dev);
+					count++;
 				}
 			}
 		}
 	}
+
+	return count;
 }
 
 
@@ -262,6 +254,8 @@ static void pci_rescan_bus(const struct pci_bus *bus)
 {
 	unsigned int devfn;
 	struct pci_dev *dev;
+	int retval;
+	int found = 0;
 	dev = alloc_pci_dev();
 	if (!dev)
 		return;
@@ -270,7 +264,23 @@ static void pci_rescan_bus(const struct pci_bus *bus)
 	dev->sysdata = bus->sysdata;
 	for (devfn = 0; devfn < 0x100; devfn += 8) {
 		dev->devfn = devfn;
-		pci_rescan_slot(dev);
+		found += pci_rescan_slot(dev);
+	}
+
+	if (found) {
+		pci_bus_assign_resources(bus);
+		list_for_each_entry(dev, &bus->devices, bus_list) {
+			/* Skip already-added devices */
+			if (dev->is_added)
+					continue;
+			retval = pci_bus_add_device(dev);
+			if (retval)
+				dev_err(&dev->dev,
+					"Error adding device, continuing\n");
+			else
+				add_slot(dev);
+		}
+		pci_bus_add_devices(bus);
 	}
 	kfree(dev);
 }
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 896a15d70f5b..44f15ff70c1d 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -103,6 +103,16 @@ static void msix_set_enable(struct pci_dev *dev, int enable)
 	}
 }
 
+/*
+ * Essentially, this is ((1 << (1 << x)) - 1), but without the
+ * undefinedness of a << 32.
+ */
+static inline __attribute_const__ u32 msi_mask(unsigned x)
+{
+	static const u32 mask[] = { 1, 2, 4, 0xf, 0xff, 0xffff, 0xffffffff };
+	return mask[x];
+}
+
 static void msix_flush_writes(struct irq_desc *desc)
 {
 	struct msi_desc *entry;
@@ -407,8 +417,7 @@ static int msi_capability_init(struct pci_dev *dev)
 
 		/* All MSIs are unmasked by default, Mask them all */
 		pci_read_config_dword(dev, base, &maskbits);
-		temp = (1 << multi_msi_capable(control));
-		temp = ((temp - 1) & ~temp);
+		temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1);
 		maskbits |= temp;
 		pci_write_config_dword(dev, base, maskbits);
 		entry->msi_attrib.maskbits_mask = temp;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 9de07b75b993..93eac1423585 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -355,6 +355,8 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
 	int i = 0;
 
 	if (drv && drv->suspend) {
+		pci_power_t prev = pci_dev->current_state;
+
 		pci_dev->state_saved = false;
 
 		i = drv->suspend(pci_dev, state);
@@ -365,8 +367,13 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
 		if (pci_dev->state_saved)
 			goto Fixup;
 
-		if (WARN_ON_ONCE(pci_dev->current_state != PCI_D0))
+		if (pci_dev->current_state != PCI_D0
+		    && pci_dev->current_state != PCI_UNKNOWN) {
+			WARN_ONCE(pci_dev->current_state != prev,
+				"PCI PM: Device state not saved by %pF\n",
+				drv->suspend);
 			goto Fixup;
+		}
 	}
 
 	pci_save_state(pci_dev);
@@ -419,38 +426,24 @@ static int pci_legacy_resume(struct device *dev)
 static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
 {
 	pci_restore_standard_config(pci_dev);
+	pci_dev->state_saved = false;
 	pci_fixup_device(pci_fixup_resume_early, pci_dev);
 }
 
-static int pci_pm_default_resume(struct pci_dev *pci_dev)
+static void pci_pm_default_resume(struct pci_dev *pci_dev)
 {
 	pci_fixup_device(pci_fixup_resume, pci_dev);
 
 	if (!pci_is_bridge(pci_dev))
 		pci_enable_wake(pci_dev, PCI_D0, false);
-
-	return pci_pm_reenable_device(pci_dev);
-}
-
-static void pci_pm_default_suspend_generic(struct pci_dev *pci_dev)
-{
-	/* If device is enabled at this point, disable it */
-	pci_disable_enabled_device(pci_dev);
-	/*
-	 * Save state with interrupts enabled, because in principle the bus the
-	 * device is on may be put into a low power state after this code runs.
-	 */
-	pci_save_state(pci_dev);
 }
 
 static void pci_pm_default_suspend(struct pci_dev *pci_dev)
 {
-	pci_pm_default_suspend_generic(pci_dev);
-
+	/* Disable non-bridge devices without PM support */
 	if (!pci_is_bridge(pci_dev))
-		pci_prepare_to_sleep(pci_dev);
-
-	pci_fixup_device(pci_fixup_suspend, pci_dev);
+		pci_disable_enabled_device(pci_dev);
+	pci_save_state(pci_dev);
 }
 
 static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
@@ -495,21 +488,49 @@ static void pci_pm_complete(struct device *dev)
 static int pci_pm_suspend(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct device_driver *drv = dev->driver;
-	int error = 0;
+	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend(dev, PMSG_SUSPEND);
 
-	if (drv && drv->pm && drv->pm->suspend) {
-		error = drv->pm->suspend(dev);
-		suspend_report_result(drv->pm->suspend, error);
+	if (!pm) {
+		pci_pm_default_suspend(pci_dev);
+		goto Fixup;
 	}
 
-	if (!error)
-		pci_pm_default_suspend(pci_dev);
+	pci_dev->state_saved = false;
 
-	return error;
+	if (pm->suspend) {
+		pci_power_t prev = pci_dev->current_state;
+		int error;
+
+		error = pm->suspend(dev);
+		suspend_report_result(pm->suspend, error);
+		if (error)
+			return error;
+
+		if (pci_dev->state_saved)
+			goto Fixup;
+
+		if (pci_dev->current_state != PCI_D0
+		    && pci_dev->current_state != PCI_UNKNOWN) {
+			WARN_ONCE(pci_dev->current_state != prev,
+				"PCI PM: State of device not saved by %pF\n",
+				pm->suspend);
+			goto Fixup;
+		}
+	}
+
+	if (!pci_dev->state_saved) {
+		pci_save_state(pci_dev);
+		if (!pci_is_bridge(pci_dev))
+			pci_prepare_to_sleep(pci_dev);
+	}
+
+ Fixup:
+	pci_fixup_device(pci_fixup_suspend, pci_dev);
+
+	return 0;
 }
 
 static int pci_pm_suspend_noirq(struct device *dev)
@@ -552,18 +573,29 @@ static int pci_pm_resume_noirq(struct device *dev)
 static int pci_pm_resume(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct device_driver *drv = dev->driver;
+	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 	int error = 0;
 
+	/*
+	 * This is necessary for the suspend error path in which resume is
+	 * called without restoring the standard config registers of the device.
+	 */
+	if (pci_dev->state_saved)
+		pci_restore_standard_config(pci_dev);
+
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_resume(dev);
 
-	error = pci_pm_default_resume(pci_dev);
+	pci_pm_default_resume(pci_dev);
 
-	if (!error && drv && drv->pm && drv->pm->resume)
-		error = drv->pm->resume(dev);
+	if (pm) {
+		if (pm->resume)
+			error = pm->resume(dev);
+	} else {
+		pci_pm_reenable_device(pci_dev);
+	}
 
-	return error;
+	return 0;
 }
 
 #else /* !CONFIG_SUSPEND */
@@ -580,21 +612,31 @@ static int pci_pm_resume(struct device *dev)
 static int pci_pm_freeze(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct device_driver *drv = dev->driver;
-	int error = 0;
+	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend(dev, PMSG_FREEZE);
 
-	if (drv && drv->pm && drv->pm->freeze) {
-		error = drv->pm->freeze(dev);
-		suspend_report_result(drv->pm->freeze, error);
+	if (!pm) {
+		pci_pm_default_suspend(pci_dev);
+		return 0;
+	}
+
+	pci_dev->state_saved = false;
+
+	if (pm->freeze) {
+		int error;
+
+		error = pm->freeze(dev);
+		suspend_report_result(pm->freeze, error);
+		if (error)
+			return error;
 	}
 
-	if (!error)
-		pci_pm_default_suspend_generic(pci_dev);
+	if (!pci_dev->state_saved)
+		pci_save_state(pci_dev);
 
-	return error;
+	return 0;
 }
 
 static int pci_pm_freeze_noirq(struct device *dev)
@@ -637,16 +679,18 @@ static int pci_pm_thaw_noirq(struct device *dev)
 static int pci_pm_thaw(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct device_driver *drv = dev->driver;
+	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 	int error = 0;
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_resume(dev);
 
-	pci_pm_reenable_device(pci_dev);
-
-	if (drv && drv->pm && drv->pm->thaw)
-		error =  drv->pm->thaw(dev);
+	if (pm) {
+		if (pm->thaw)
+			error = pm->thaw(dev);
+	} else {
+		pci_pm_reenable_device(pci_dev);
+	}
 
 	return error;
 }
@@ -654,19 +698,29 @@ static int pci_pm_thaw(struct device *dev)
 static int pci_pm_poweroff(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct device_driver *drv = dev->driver;
+	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 	int error = 0;
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend(dev, PMSG_HIBERNATE);
 
-	if (drv && drv->pm && drv->pm->poweroff) {
-		error = drv->pm->poweroff(dev);
-		suspend_report_result(drv->pm->poweroff, error);
+	if (!pm) {
+		pci_pm_default_suspend(pci_dev);
+		goto Fixup;
 	}
 
-	if (!error)
-		pci_pm_default_suspend(pci_dev);
+	pci_dev->state_saved = false;
+
+	if (pm->poweroff) {
+		error = pm->poweroff(dev);
+		suspend_report_result(pm->poweroff, error);
+	}
+
+	if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
+		pci_prepare_to_sleep(pci_dev);
+
+ Fixup:
+	pci_fixup_device(pci_fixup_suspend, pci_dev);
 
 	return error;
 }
@@ -707,16 +761,27 @@ static int pci_pm_restore_noirq(struct device *dev)
 static int pci_pm_restore(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct device_driver *drv = dev->driver;
+	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 	int error = 0;
 
+	/*
+	 * This is necessary for the hibernation error path in which restore is
+	 * called without restoring the standard config registers of the device.
+	 */
+	if (pci_dev->state_saved)
+		pci_restore_standard_config(pci_dev);
+
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_resume(dev);
 
-	error = pci_pm_default_resume(pci_dev);
+	pci_pm_default_resume(pci_dev);
 
-	if (!error && drv && drv->pm && drv->pm->restore)
-		error = drv->pm->restore(dev);
+	if (pm) {
+		if (pm->restore)
+			error = pm->restore(dev);
+	} else {
+		pci_pm_reenable_device(pci_dev);
+	}
 
 	return error;
 }
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index db7ec14fa719..dfc4e0ddf241 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -768,8 +768,8 @@ pci_read_rom(struct kobject *kobj, struct bin_attribute *bin_attr,
 		return -EINVAL;
 	
 	rom = pci_map_rom(pdev, &size);	/* size starts out as PCI window size */
-	if (!rom)
-		return 0;
+	if (!rom || !size)
+		return -EIO;
 		
 	if (off >= size)
 		count = 0;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 17bd9325a245..e3efe6b19ee7 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1393,35 +1393,35 @@ int pci_restore_standard_config(struct pci_dev *dev)
 	pci_power_t prev_state;
 	int error;
 
-	pci_restore_state(dev);
 	pci_update_current_state(dev, PCI_D0);
 
 	prev_state = dev->current_state;
 	if (prev_state == PCI_D0)
-		return 0;
+		goto Restore;
 
 	error = pci_raw_set_power_state(dev, PCI_D0, false);
 	if (error)
 		return error;
 
-	if (pci_is_bridge(dev)) {
-		if (prev_state > PCI_D1)
-			mdelay(PCI_PM_BUS_WAIT);
-	} else {
-		switch(prev_state) {
-		case PCI_D3cold:
-		case PCI_D3hot:
-			mdelay(pci_pm_d3_delay);
-			break;
-		case PCI_D2:
-			udelay(PCI_PM_D2_DELAY);
-			break;
-		}
+	/*
+	 * This assumes that we won't get a bus in B2 or B3 from the BIOS, but
+	 * we've made this assumption forever and it appears to be universally
+	 * satisfied.
+	 */
+	switch(prev_state) {
+	case PCI_D3cold:
+	case PCI_D3hot:
+		mdelay(pci_pm_d3_delay);
+		break;
+	case PCI_D2:
+		udelay(PCI_PM_D2_DELAY);
+		break;
 	}
 
-	dev->current_state = PCI_D0;
+	pci_update_current_state(dev, PCI_D0);
 
-	return 0;
+ Restore:
+	return dev->state_saved ? pci_restore_state(dev) : 0;
 }
 
 /**
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 586b6f75910d..b0367f168af4 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -718,9 +718,9 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
 
 	/*
 	 * All PCIe functions are in one slot, remove one function will remove
-	 * the the whole slot, so just wait
+	 * the whole slot, so just wait until we are the last function left.
 	 */
-	if (!list_empty(&parent->subordinate->devices))
+	if (!list_is_last(&pdev->bus_list, &parent->subordinate->devices))
 		goto out;
 
 	/* All functions are removed, so just disable ASPM for the link */
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 99a914a027f8..f9b874eaeb9f 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -55,25 +55,13 @@ static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state)
 
 }
 
-static int pcie_portdrv_suspend_late(struct pci_dev *dev, pm_message_t state)
-{
-	return pci_save_state(dev);
-}
-
-static int pcie_portdrv_resume_early(struct pci_dev *dev)
-{
-	return pci_restore_state(dev);
-}
-
 static int pcie_portdrv_resume(struct pci_dev *dev)
 {
-	pcie_portdrv_restore_config(dev);
+	pci_set_master(dev);
 	return pcie_port_device_resume(dev);
 }
 #else
 #define pcie_portdrv_suspend NULL
-#define pcie_portdrv_suspend_late NULL
-#define pcie_portdrv_resume_early NULL
 #define pcie_portdrv_resume NULL
 #endif
 
@@ -292,8 +280,6 @@ static struct pci_driver pcie_portdriver = {
 	.remove		= pcie_portdrv_remove,
 
 	.suspend	= pcie_portdrv_suspend,
-	.suspend_late	= pcie_portdrv_suspend_late,
-	.resume_early	= pcie_portdrv_resume_early,
 	.resume		= pcie_portdrv_resume,
 
 	.err_handler 	= &pcie_portdrv_err_handler,
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 132a78159b60..29cbe47f219f 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -63,7 +63,7 @@ void pci_disable_rom(struct pci_dev *pdev)
  * The PCI window size could be much larger than the
  * actual image size.
  */
-size_t pci_get_rom_size(void __iomem *rom, size_t size)
+size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
 {
 	void __iomem *image;
 	int last_image;
@@ -72,8 +72,10 @@ size_t pci_get_rom_size(void __iomem *rom, size_t size)
 	do {
 		void __iomem *pds;
 		/* Standard PCI ROMs start out with these bytes 55 AA */
-		if (readb(image) != 0x55)
+		if (readb(image) != 0x55) {
+			dev_err(&pdev->dev, "Invalid ROM contents\n");
 			break;
+		}
 		if (readb(image + 1) != 0xAA)
 			break;
 		/* get the PCI data structure and check its signature */
@@ -159,7 +161,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
 	 * size is much larger than the actual size of the ROM.
 	 * True size is important if the ROM is going to be copied.
 	 */
-	*size = pci_get_rom_size(rom, *size);
+	*size = pci_get_rom_size(pdev, rom, *size);
 	return rom;
 }
 
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 1a266d4ab5f1..94363115a42a 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -42,6 +42,7 @@ config ASUS_LAPTOP
 	depends on LEDS_CLASS
 	depends on NEW_LEDS
 	depends on BACKLIGHT_CLASS_DEVICE
+	depends on INPUT
 	---help---
 	  This is the new Linux driver for Asus laptops. It may also support some
 	  MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index 8fb8b3591048..56af6cf385b0 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -46,6 +46,7 @@
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 #include <asm/uaccess.h>
+#include <linux/input.h>
 
 #define ASUS_LAPTOP_VERSION "0.42"
 
@@ -181,6 +182,8 @@ struct asus_hotk {
 	u8 light_level;		//light sensor level
 	u8 light_switch;	//light sensor switch value
 	u16 event_count[128];	//count for each event TODO make this better
+	struct input_dev *inputdev;
+	u16 *keycode_map;
 };
 
 /*
@@ -250,6 +253,37 @@ ASUS_LED(rled, "record");
 ASUS_LED(pled, "phone");
 ASUS_LED(gled, "gaming");
 
+struct key_entry {
+	char type;
+	u8 code;
+	u16 keycode;
+};
+
+enum { KE_KEY, KE_END };
+
+static struct key_entry asus_keymap[] = {
+	{KE_KEY, 0x30, KEY_VOLUMEUP},
+	{KE_KEY, 0x31, KEY_VOLUMEDOWN},
+	{KE_KEY, 0x32, KEY_MUTE},
+	{KE_KEY, 0x33, KEY_SWITCHVIDEOMODE},
+	{KE_KEY, 0x34, KEY_SWITCHVIDEOMODE},
+	{KE_KEY, 0x40, KEY_PREVIOUSSONG},
+	{KE_KEY, 0x41, KEY_NEXTSONG},
+	{KE_KEY, 0x43, KEY_STOP},
+	{KE_KEY, 0x45, KEY_PLAYPAUSE},
+	{KE_KEY, 0x50, KEY_EMAIL},
+	{KE_KEY, 0x51, KEY_WWW},
+	{KE_KEY, 0x5C, BTN_EXTRA},  /* Performance */
+	{KE_KEY, 0x5D, KEY_WLAN},
+	{KE_KEY, 0x61, KEY_SWITCHVIDEOMODE},
+	{KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */
+	{KE_KEY, 0x82, KEY_CAMERA},
+	{KE_KEY, 0x8A, KEY_TV},
+	{KE_KEY, 0x95, KEY_MEDIA},
+	{KE_KEY, 0x99, KEY_PHONE},
+	{KE_END, 0},
+};
+
 /*
  * This function evaluates an ACPI method, given an int as parameter, the
  * method is searched within the scope of the handle, can be NULL. The output
@@ -720,8 +754,68 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr,
 	return store_status(buf, count, NULL, GPS_ON);
 }
 
+/*
+ * Hotkey functions
+ */
+static struct key_entry *asus_get_entry_by_scancode(int code)
+{
+	struct key_entry *key;
+
+	for (key = asus_keymap; key->type != KE_END; key++)
+		if (code == key->code)
+			return key;
+
+	return NULL;
+}
+
+static struct key_entry *asus_get_entry_by_keycode(int code)
+{
+	struct key_entry *key;
+
+	for (key = asus_keymap; key->type != KE_END; key++)
+		if (code == key->keycode && key->type == KE_KEY)
+			return key;
+
+	return NULL;
+}
+
+static int asus_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+{
+	struct key_entry *key = asus_get_entry_by_scancode(scancode);
+
+	if (key && key->type == KE_KEY) {
+		*keycode = key->keycode;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode)
+{
+	struct key_entry *key;
+	int old_keycode;
+
+	if (keycode < 0 || keycode > KEY_MAX)
+		return -EINVAL;
+
+	key = asus_get_entry_by_scancode(scancode);
+	if (key && key->type == KE_KEY) {
+		old_keycode = key->keycode;
+		key->keycode = keycode;
+		set_bit(keycode, dev->keybit);
+		if (!asus_get_entry_by_keycode(old_keycode))
+			clear_bit(old_keycode, dev->keybit);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
 {
+	static struct key_entry *key;
+
 	/* TODO Find a better way to handle events count. */
 	if (!hotk)
 		return;
@@ -738,10 +832,24 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
 		lcd_blank(FB_BLANK_POWERDOWN);
 	}
 
-	acpi_bus_generate_proc_event(hotk->device, event,
-				hotk->event_count[event % 128]++);
-
-	return;
+	acpi_bus_generate_netlink_event(hotk->device->pnp.device_class,
+					dev_name(&hotk->device->dev), event,
+					hotk->event_count[event % 128]++);
+
+	if (hotk->inputdev) {
+		key = asus_get_entry_by_scancode(event);
+		if (!key)
+			return ;
+
+		switch (key->type) {
+		case KE_KEY:
+			input_report_key(hotk->inputdev, key->keycode, 1);
+			input_sync(hotk->inputdev);
+			input_report_key(hotk->inputdev, key->keycode, 0);
+			input_sync(hotk->inputdev);
+			break;
+		}
+	}
 }
 
 #define ASUS_CREATE_DEVICE_ATTR(_name)					\
@@ -959,6 +1067,38 @@ static int asus_hotk_get_info(void)
 	return AE_OK;
 }
 
+static int asus_input_init(void)
+{
+	const struct key_entry *key;
+	int result;
+
+	hotk->inputdev = input_allocate_device();
+	if (!hotk->inputdev) {
+		printk(ASUS_INFO "Unable to allocate input device\n");
+		return 0;
+	}
+	hotk->inputdev->name = "Asus Laptop extra buttons";
+	hotk->inputdev->phys = ASUS_HOTK_FILE "/input0";
+	hotk->inputdev->id.bustype = BUS_HOST;
+	hotk->inputdev->getkeycode = asus_getkeycode;
+	hotk->inputdev->setkeycode = asus_setkeycode;
+
+	for (key = asus_keymap; key->type != KE_END; key++) {
+		switch (key->type) {
+		case KE_KEY:
+			set_bit(EV_KEY, hotk->inputdev->evbit);
+			set_bit(key->keycode, hotk->inputdev->keybit);
+			break;
+		}
+	}
+	result = input_register_device(hotk->inputdev);
+	if (result) {
+		printk(ASUS_INFO "Unable to register input device\n");
+		input_free_device(hotk->inputdev);
+	}
+	return result;
+}
+
 static int asus_hotk_check(void)
 {
 	int result = 0;
@@ -1044,7 +1184,7 @@ static int asus_hotk_add(struct acpi_device *device)
 	/* GPS is on by default */
 	write_status(NULL, 1, GPS_ON);
 
-      end:
+end:
 	if (result) {
 		kfree(hotk->name);
 		kfree(hotk);
@@ -1091,10 +1231,17 @@ static void asus_led_exit(void)
 	ASUS_LED_UNREGISTER(gled);
 }
 
+static void asus_input_exit(void)
+{
+	if (hotk->inputdev)
+		input_unregister_device(hotk->inputdev);
+}
+
 static void __exit asus_laptop_exit(void)
 {
 	asus_backlight_exit();
 	asus_led_exit();
+	asus_input_exit();
 
 	acpi_bus_unregister_driver(&asus_hotk_driver);
 	sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group);
@@ -1216,6 +1363,10 @@ static int __init asus_laptop_init(void)
 		printk(ASUS_INFO "Brightness ignored, must be controlled by "
 		       "ACPI video driver\n");
 
+	result = asus_input_init();
+	if (result)
+		goto fail_input;
+
 	result = asus_led_init(dev);
 	if (result)
 		goto fail_led;
@@ -1242,22 +1393,25 @@ static int __init asus_laptop_init(void)
 
 	return 0;
 
-      fail_sysfs:
+fail_sysfs:
 	platform_device_del(asuspf_device);
 
-      fail_platform_device2:
+fail_platform_device2:
 	platform_device_put(asuspf_device);
 
-      fail_platform_device1:
+fail_platform_device1:
 	platform_driver_unregister(&asuspf_driver);
 
-      fail_platform_driver:
+fail_platform_driver:
 	asus_led_exit();
 
-      fail_led:
+fail_led:
+	asus_input_exit();
+
+fail_input:
 	asus_backlight_exit();
 
-      fail_backlight:
+fail_backlight:
 
 	return result;
 }
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c
index 1e74988c7b2d..d63f26e666a4 100644
--- a/drivers/platform/x86/asus_acpi.c
+++ b/drivers/platform/x86/asus_acpi.c
@@ -143,6 +143,7 @@ struct asus_hotk {
 							 S1300N, S5200N*/
 		A4S,            /* Z81sp */
 		F3Sa,		/* (Centrino) */
+		R1F,
 		END_MODEL
 	} model;		/* Models currently supported */
 	u16 event_count[128];	/* Count for each event TODO make this better */
@@ -420,7 +421,18 @@ static struct model_data model_conf[END_MODEL] = {
 		.display_get	= "\\ADVG",
 		.display_set	= "SDSP",
 	},
-
+	{
+		.name = "R1F",
+		.mt_bt_switch = "BLED",
+		.mt_mled = "MLED",
+		.mt_wled = "WLED",
+		.mt_lcd_switch = "\\Q10",
+		.lcd_status = "\\GP06",
+		.brightness_set = "SPLV",
+		.brightness_get = "GPLV",
+		.display_set = "SDSP",
+		.display_get = "\\INFB"
+	}
 };
 
 /* procdir we use */
@@ -1165,6 +1177,8 @@ static int asus_model_match(char *model)
 		return W3V;
 	else if (strncmp(model, "W5A", 3) == 0)
 		return W5A;
+	else if (strncmp(model, "R1F", 3) == 0)
+		return R1F;
 	else if (strncmp(model, "A4S", 3) == 0)
 		return A4S;
 	else if (strncmp(model, "F3Sa", 4) == 0)
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 9d93cb971e59..786ed8661cb0 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -30,6 +30,7 @@
 #include <linux/uaccess.h>
 #include <linux/input.h>
 #include <linux/rfkill.h>
+#include <linux/pci.h>
 
 #define EEEPC_LAPTOP_VERSION	"0.1"
 
@@ -161,6 +162,10 @@ static struct key_entry eeepc_keymap[] = {
 	{KE_KEY, 0x13, KEY_MUTE },
 	{KE_KEY, 0x14, KEY_VOLUMEDOWN },
 	{KE_KEY, 0x15, KEY_VOLUMEUP },
+	{KE_KEY, 0x1a, KEY_COFFEE },
+	{KE_KEY, 0x1b, KEY_ZOOM },
+	{KE_KEY, 0x1c, KEY_PROG2 },
+	{KE_KEY, 0x1d, KEY_PROG3 },
 	{KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
 	{KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
 	{KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
@@ -510,7 +515,43 @@ static int eeepc_hotk_check(void)
 static void notify_brn(void)
 {
 	struct backlight_device *bd = eeepc_backlight_device;
-	bd->props.brightness = read_brightness(bd);
+	if (bd)
+		bd->props.brightness = read_brightness(bd);
+}
+
+static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
+{
+	struct pci_dev *dev;
+	struct pci_bus *bus = pci_find_bus(0, 1);
+
+	if (event != ACPI_NOTIFY_BUS_CHECK)
+		return;
+
+	if (!bus) {
+		printk(EEEPC_WARNING "Unable to find PCI bus 1?\n");
+		return;
+	}
+
+	if (get_acpi(CM_ASL_WLAN) == 1) {
+		dev = pci_get_slot(bus, 0);
+		if (dev) {
+			/* Device already present */
+			pci_dev_put(dev);
+			return;
+		}
+		dev = pci_scan_single_device(bus, 0);
+		if (dev) {
+			pci_bus_assign_resources(bus);
+			if (pci_bus_add_device(dev))
+				printk(EEEPC_ERR "Unable to hotplug wifi\n");
+		}
+	} else {
+		dev = pci_get_slot(bus, 0);
+		if (dev) {
+			pci_remove_bus_device(dev);
+			pci_dev_put(dev);
+		}
+	}
 }
 
 static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
@@ -520,8 +561,9 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
 		return;
 	if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
 		notify_brn();
-	acpi_bus_generate_proc_event(ehotk->device, event,
-				     ehotk->event_count[event % 128]++);
+	acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
+					dev_name(&ehotk->device->dev), event,
+					ehotk->event_count[event % 128]++);
 	if (ehotk->inputdev) {
 		key = eepc_get_entry_by_scancode(event);
 		if (key) {
@@ -539,6 +581,45 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
 	}
 }
 
+static int eeepc_register_rfkill_notifier(char *node)
+{
+	acpi_status status = AE_OK;
+	acpi_handle handle;
+
+	status = acpi_get_handle(NULL, node, &handle);
+
+	if (ACPI_SUCCESS(status)) {
+		status = acpi_install_notify_handler(handle,
+						     ACPI_SYSTEM_NOTIFY,
+						     eeepc_rfkill_notify,
+						     NULL);
+		if (ACPI_FAILURE(status))
+			printk(EEEPC_WARNING
+			       "Failed to register notify on %s\n", node);
+	} else
+		return -ENODEV;
+
+	return 0;
+}
+
+static void eeepc_unregister_rfkill_notifier(char *node)
+{
+	acpi_status status = AE_OK;
+	acpi_handle handle;
+
+	status = acpi_get_handle(NULL, node, &handle);
+
+	if (ACPI_SUCCESS(status)) {
+		status = acpi_remove_notify_handler(handle,
+						     ACPI_SYSTEM_NOTIFY,
+						     eeepc_rfkill_notify);
+		if (ACPI_FAILURE(status))
+			printk(EEEPC_ERR
+			       "Error removing rfkill notify handler %s\n",
+				node);
+	}
+}
+
 static int eeepc_hotk_add(struct acpi_device *device)
 {
 	acpi_status status = AE_OK;
@@ -558,7 +639,7 @@ static int eeepc_hotk_add(struct acpi_device *device)
 	ehotk->device = device;
 	result = eeepc_hotk_check();
 	if (result)
-		goto end;
+		goto ehotk_fail;
 	status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
 					     eeepc_hotk_notify, ehotk);
 	if (ACPI_FAILURE(status))
@@ -569,18 +650,25 @@ static int eeepc_hotk_add(struct acpi_device *device)
 							   RFKILL_TYPE_WLAN);
 
 		if (!ehotk->eeepc_wlan_rfkill)
-			goto end;
+			goto wlan_fail;
 
 		ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan";
 		ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set;
 		ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state;
-		if (get_acpi(CM_ASL_WLAN) == 1)
+		if (get_acpi(CM_ASL_WLAN) == 1) {
 			ehotk->eeepc_wlan_rfkill->state =
 				RFKILL_STATE_UNBLOCKED;
-		else
+			rfkill_set_default(RFKILL_TYPE_WLAN,
+					   RFKILL_STATE_UNBLOCKED);
+		} else {
 			ehotk->eeepc_wlan_rfkill->state =
 				RFKILL_STATE_SOFT_BLOCKED;
-		rfkill_register(ehotk->eeepc_wlan_rfkill);
+			rfkill_set_default(RFKILL_TYPE_WLAN,
+					   RFKILL_STATE_SOFT_BLOCKED);
+		}
+		result = rfkill_register(ehotk->eeepc_wlan_rfkill);
+		if (result)
+			goto wlan_fail;
 	}
 
 	if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
@@ -588,27 +676,47 @@ static int eeepc_hotk_add(struct acpi_device *device)
 			rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH);
 
 		if (!ehotk->eeepc_bluetooth_rfkill)
-			goto end;
+			goto bluetooth_fail;
 
 		ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth";
 		ehotk->eeepc_bluetooth_rfkill->toggle_radio =
 			eeepc_bluetooth_rfkill_set;
 		ehotk->eeepc_bluetooth_rfkill->get_state =
 			eeepc_bluetooth_rfkill_state;
-		if (get_acpi(CM_ASL_BLUETOOTH) == 1)
+		if (get_acpi(CM_ASL_BLUETOOTH) == 1) {
 			ehotk->eeepc_bluetooth_rfkill->state =
 				RFKILL_STATE_UNBLOCKED;
-		else
+			rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
+					   RFKILL_STATE_UNBLOCKED);
+		} else {
 			ehotk->eeepc_bluetooth_rfkill->state =
 				RFKILL_STATE_SOFT_BLOCKED;
-		rfkill_register(ehotk->eeepc_bluetooth_rfkill);
-	}
+			rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
+					   RFKILL_STATE_SOFT_BLOCKED);
+		}
 
- end:
-	if (result) {
-		kfree(ehotk);
-		ehotk = NULL;
+		result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
+		if (result)
+			goto bluetooth_fail;
 	}
+
+	eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
+	eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
+
+	return 0;
+
+ bluetooth_fail:
+	if (ehotk->eeepc_bluetooth_rfkill)
+		rfkill_free(ehotk->eeepc_bluetooth_rfkill);
+	rfkill_unregister(ehotk->eeepc_wlan_rfkill);
+	ehotk->eeepc_wlan_rfkill = NULL;
+ wlan_fail:
+	if (ehotk->eeepc_wlan_rfkill)
+		rfkill_free(ehotk->eeepc_wlan_rfkill);
+ ehotk_fail:
+	kfree(ehotk);
+	ehotk = NULL;
+
 	return result;
 }
 
@@ -622,6 +730,10 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type)
 					    eeepc_hotk_notify);
 	if (ACPI_FAILURE(status))
 		printk(EEEPC_ERR "Error removing notify handler\n");
+
+	eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
+	eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
+
 	kfree(ehotk);
 	return 0;
 }
@@ -737,13 +849,21 @@ static void eeepc_backlight_exit(void)
 {
 	if (eeepc_backlight_device)
 		backlight_device_unregister(eeepc_backlight_device);
-	if (ehotk->inputdev)
-		input_unregister_device(ehotk->inputdev);
+	eeepc_backlight_device = NULL;
+}
+
+static void eeepc_rfkill_exit(void)
+{
 	if (ehotk->eeepc_wlan_rfkill)
 		rfkill_unregister(ehotk->eeepc_wlan_rfkill);
 	if (ehotk->eeepc_bluetooth_rfkill)
 		rfkill_unregister(ehotk->eeepc_bluetooth_rfkill);
-	eeepc_backlight_device = NULL;
+}
+
+static void eeepc_input_exit(void)
+{
+	if (ehotk->inputdev)
+		input_unregister_device(ehotk->inputdev);
 }
 
 static void eeepc_hwmon_exit(void)
@@ -762,6 +882,8 @@ static void eeepc_hwmon_exit(void)
 static void __exit eeepc_laptop_exit(void)
 {
 	eeepc_backlight_exit();
+	eeepc_rfkill_exit();
+	eeepc_input_exit();
 	eeepc_hwmon_exit();
 	acpi_bus_unregister_driver(&eeepc_hotk_driver);
 	sysfs_remove_group(&platform_device->dev.kobj,
@@ -865,6 +987,8 @@ fail_platform_driver:
 fail_hwmon:
 	eeepc_backlight_exit();
 fail_backlight:
+	eeepc_input_exit();
+	eeepc_rfkill_exit();
 	return result;
 }
 
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index de91ddab0a86..f41135f2fb29 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -463,9 +463,11 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
 
 	return 0;
 register_wwan_err:
-	rfkill_unregister(bluetooth_rfkill);
+	if (bluetooth_rfkill)
+		rfkill_unregister(bluetooth_rfkill);
 register_bluetooth_error:
-	rfkill_unregister(wifi_rfkill);
+	if (wifi_rfkill)
+		rfkill_unregister(wifi_rfkill);
 add_sysfs_error:
 	cleanup_sysfs(device);
 	return err;
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index f30db367c82e..c47a44dcb702 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -507,7 +507,7 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
 
 	hkey_num = result & 0xf;
 
-	if (hkey_num < 0 || hkey_num > ARRAY_SIZE(pcc->keymap)) {
+	if (hkey_num < 0 || hkey_num >= ARRAY_SIZE(pcc->keymap)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 				  "hotkey number out of range: %d\n",
 				  hkey_num));
diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c
index 366565aba865..c175e38a4cd5 100644
--- a/drivers/regulator/bq24022.c
+++ b/drivers/regulator/bq24022.c
@@ -152,11 +152,7 @@ static void __exit bq24022_exit(void)
 	platform_driver_unregister(&bq24022_driver);
 }
 
-/*
- * make sure this is probed before gpio_vbus and pda_power,
- * but after asic3 or other GPIO expander drivers.
- */
-subsys_initcall(bq24022_init);
+module_init(bq24022_init);
 module_exit(bq24022_exit);
 
 MODULE_AUTHOR("Philipp Zabel");
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 7aa35248181b..5056e23e4414 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1435,7 +1435,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,
 	struct platform_device *pdev;
 	int ret;
 
-	if (lednum > ARRAY_SIZE(wm8350->pmic.led) || lednum < 0) {
+	if (lednum >= ARRAY_SIZE(wm8350->pmic.led) || lednum < 0) {
 		dev_err(wm8350->dev, "Invalid LED index %d\n", lednum);
 		return -ENODEV;
 	}
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index cced4d108319..81450fbd8b12 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -241,6 +241,12 @@ config RTC_DRV_M41T80_WDT
 	  If you say Y here you will get support for the
 	  watchdog timer in the ST M41T60 and M41T80 RTC chips series.
 
+config RTC_DRV_DM355EVM
+	tristate "TI DaVinci DM355 EVM RTC"
+	depends on MFD_DM355EVM_MSP
+	help
+	  Supports the RTC firmware in the MSP430 on the DM355 EVM.
+
 config RTC_DRV_TWL92330
 	boolean "TI TWL92330/Menelaus"
 	depends on MENELAUS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 6e28021abb9d..0e697aa51caa 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_RTC_DRV_AT91SAM9)	+= rtc-at91sam9.o
 obj-$(CONFIG_RTC_DRV_AU1XXX)	+= rtc-au1xxx.o
 obj-$(CONFIG_RTC_DRV_BFIN)	+= rtc-bfin.o
 obj-$(CONFIG_RTC_DRV_CMOS)	+= rtc-cmos.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
 obj-$(CONFIG_RTC_DRV_DS1302)	+= rtc-ds1302.o
diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c
new file mode 100644
index 000000000000..58d4e18530da
--- /dev/null
+++ b/drivers/rtc/rtc-dm355evm.c
@@ -0,0 +1,175 @@
+/*
+ * rtc-dm355evm.c - access battery-backed counter in MSP430 firmware
+ *
+ * Copyright (c) 2008 by David Brownell
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+
+#include <linux/i2c/dm355evm_msp.h>
+
+
+/*
+ * The MSP430 firmware on the DM355 EVM uses a watch crystal to feed
+ * a 1 Hz counter.  When a backup battery is supplied, that makes a
+ * reasonable RTC for applications where alarms and non-NTP drift
+ * compensation aren't important.
+ *
+ * The only real glitch is the inability to read or write all four
+ * counter bytes atomically:  the count may increment in the middle
+ * of an operation, causing trouble when the LSB rolls over.
+ *
+ * This driver was tested with firmware revision A4.
+ */
+union evm_time {
+	u8	bytes[4];
+	u32	value;
+};
+
+static int dm355evm_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	union evm_time	time;
+	int		status;
+	int		tries = 0;
+
+	do {
+		/*
+		 * Read LSB(0) to MSB(3) bytes.  Defend against the counter
+		 * rolling over by re-reading until the value is stable,
+		 * and assuming the four reads take at most a few seconds.
+		 */
+		status = dm355evm_msp_read(DM355EVM_MSP_RTC_0);
+		if (status < 0)
+			return status;
+		if (tries && time.bytes[0] == status)
+			break;
+		time.bytes[0] = status;
+
+		status = dm355evm_msp_read(DM355EVM_MSP_RTC_1);
+		if (status < 0)
+			return status;
+		if (tries && time.bytes[1] == status)
+			break;
+		time.bytes[1] = status;
+
+		status = dm355evm_msp_read(DM355EVM_MSP_RTC_2);
+		if (status < 0)
+			return status;
+		if (tries && time.bytes[2] == status)
+			break;
+		time.bytes[2] = status;
+
+		status = dm355evm_msp_read(DM355EVM_MSP_RTC_3);
+		if (status < 0)
+			return status;
+		if (tries && time.bytes[3] == status)
+			break;
+		time.bytes[3] = status;
+
+	} while (++tries < 5);
+
+	dev_dbg(dev, "read timestamp %08x\n", time.value);
+
+	rtc_time_to_tm(le32_to_cpu(time.value), tm);
+	return 0;
+}
+
+static int dm355evm_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	union evm_time	time;
+	unsigned long	value;
+	int		status;
+
+	rtc_tm_to_time(tm, &value);
+	time.value = cpu_to_le32(value);
+
+	dev_dbg(dev, "write timestamp %08x\n", time.value);
+
+	/*
+	 * REVISIT handle non-atomic writes ... maybe just retry until
+	 * byte[1] sticks (no rollover)?
+	 */
+	status = dm355evm_msp_write(time.bytes[0], DM355EVM_MSP_RTC_0);
+	if (status < 0)
+		return status;
+
+	status = dm355evm_msp_write(time.bytes[1], DM355EVM_MSP_RTC_1);
+	if (status < 0)
+		return status;
+
+	status = dm355evm_msp_write(time.bytes[2], DM355EVM_MSP_RTC_2);
+	if (status < 0)
+		return status;
+
+	status = dm355evm_msp_write(time.bytes[3], DM355EVM_MSP_RTC_3);
+	if (status < 0)
+		return status;
+
+	return 0;
+}
+
+static struct rtc_class_ops dm355evm_rtc_ops = {
+	.read_time	= dm355evm_rtc_read_time,
+	.set_time	= dm355evm_rtc_set_time,
+};
+
+/*----------------------------------------------------------------------*/
+
+static int __devinit dm355evm_rtc_probe(struct platform_device *pdev)
+{
+	struct rtc_device *rtc;
+
+	rtc = rtc_device_register(pdev->name,
+				  &pdev->dev, &dm355evm_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc)) {
+		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
+			PTR_ERR(rtc));
+		return PTR_ERR(rtc);
+	}
+	platform_set_drvdata(pdev, rtc);
+
+	return 0;
+}
+
+static int __devexit dm355evm_rtc_remove(struct platform_device *pdev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+
+	rtc_device_unregister(rtc);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+/*
+ * I2C is used to talk to the MSP430, but this platform device is
+ * exposed by an MFD driver that manages I2C communications.
+ */
+static struct platform_driver rtc_dm355evm_driver = {
+	.probe		= dm355evm_rtc_probe,
+	.remove		= __devexit_p(dm355evm_rtc_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "rtc-dm355evm",
+	},
+};
+
+static int __init dm355evm_rtc_init(void)
+{
+	return platform_driver_register(&rtc_dm355evm_driver);
+}
+module_init(dm355evm_rtc_init);
+
+static void __exit dm355evm_rtc_exit(void)
+{
+	platform_driver_unregister(&rtc_dm355evm_driver);
+}
+module_exit(dm355evm_rtc_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c
index e54b5c619bdf..e01b955db077 100644
--- a/drivers/rtc/rtc-ds1390.c
+++ b/drivers/rtc/rtc-ds1390.c
@@ -122,7 +122,6 @@ static const struct rtc_class_ops ds1390_rtc_ops = {
 
 static int __devinit ds1390_probe(struct spi_device *spi)
 {
-	struct rtc_device *rtc;
 	unsigned char tmp;
 	struct ds1390 *chip;
 	int res;
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index 577c0d29849d..2291c5f5af51 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -170,12 +170,17 @@ void asl_stop(struct whc *whc)
 void asl_update(struct whc *whc, uint32_t wusbcmd)
 {
 	struct wusbhc *wusbhc = &whc->wusbhc;
+	long t;
 
 	mutex_lock(&wusbhc->mutex);
 	if (wusbhc->active) {
 		whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
-		wait_event(whc->async_list_wq,
-			   (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0);
+		t = wait_event_timeout(
+			whc->async_list_wq,
+			(le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0,
+			msecs_to_jiffies(1000));
+		if (t == 0)
+			whc_hw_error(whc, "ASL update timeout");
 	}
 	mutex_unlock(&wusbhc->mutex);
 }
diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c
index d498e7203217..6afa2e379160 100644
--- a/drivers/usb/host/whci/hw.c
+++ b/drivers/usb/host/whci/hw.c
@@ -87,3 +87,18 @@ out:
 
 	return ret;
 }
+
+/**
+ * whc_hw_error - recover from a hardware error
+ * @whc:    the WHCI HC that broke.
+ * @reason: a description of the failure.
+ *
+ * Recover from broken hardware with a full reset.
+ */
+void whc_hw_error(struct whc *whc, const char *reason)
+{
+	struct wusbhc *wusbhc = &whc->wusbhc;
+
+	dev_err(&whc->umc->dev, "hardware error: %s\n", reason);
+	wusbhc_reset_all(wusbhc);
+}
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
index 2ae5abf69a6a..7dc85a0bee7c 100644
--- a/drivers/usb/host/whci/pzl.c
+++ b/drivers/usb/host/whci/pzl.c
@@ -183,12 +183,17 @@ void pzl_stop(struct whc *whc)
 void pzl_update(struct whc *whc, uint32_t wusbcmd)
 {
 	struct wusbhc *wusbhc = &whc->wusbhc;
+	long t;
 
 	mutex_lock(&wusbhc->mutex);
 	if (wusbhc->active) {
 		whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
-		wait_event(whc->periodic_list_wq,
-			   (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0);
+		t = wait_event_timeout(
+			whc->periodic_list_wq,
+			(le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0,
+			msecs_to_jiffies(1000));
+		if (t == 0)
+			whc_hw_error(whc, "PZL update timeout");
 	}
 	mutex_unlock(&wusbhc->mutex);
 }
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h
index 0f3540f04f53..d3543a181dc9 100644
--- a/drivers/usb/host/whci/whcd.h
+++ b/drivers/usb/host/whci/whcd.h
@@ -137,6 +137,7 @@ void whc_clean_up(struct whc *whc);
 /* hw.c */
 void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val);
 int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len);
+void whc_hw_error(struct whc *whc, const char *reason);
 
 /* wusb.c */
 int whc_wusbhc_start(struct wusbhc *wusbhc);
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index e2e7e4bc8463..8e18141bb2e0 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -386,6 +386,7 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
 			  | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
 	port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE;
 	if (wusb_dev) {
+		dev_dbg(wusbhc->dev, "disconnecting device from port %d\n", wusb_dev->port_idx);
 		if (!list_empty(&wusb_dev->cack_node))
 			list_del_init(&wusb_dev->cack_node);
 		/* For the one in cack_add() */
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c
index 3937bf6f8cef..9fe4246cecb9 100644
--- a/drivers/usb/wusbcore/rh.c
+++ b/drivers/usb/wusbcore/rh.c
@@ -100,6 +100,9 @@ static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx)
 	struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx);
 	struct wusb_dev *wusb_dev = port->wusb_dev;
 
+	if (wusb_dev == NULL)
+		return -ENOTCONN;
+
 	port->status |= USB_PORT_STAT_RESET;
 	port->change |= USB_PORT_STAT_C_RESET;
 
diff --git a/drivers/uwb/allocator.c b/drivers/uwb/allocator.c
index c8185e6b0cd5..c13cec7dcbc5 100644
--- a/drivers/uwb/allocator.c
+++ b/drivers/uwb/allocator.c
@@ -15,7 +15,6 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/uwb.h>
 
diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c
index 2b4f9406789d..4f5ca99a04b9 100644
--- a/drivers/uwb/drp.c
+++ b/drivers/uwb/drp.c
@@ -66,14 +66,14 @@ static void uwb_rc_set_drp_cmd_done(struct uwb_rc *rc, void *arg,
 	} else
 		dev_err(&rc->uwb_dev.dev, "SET-DRP-IE: timeout\n");
 
-	spin_lock(&rc->rsvs_lock);
+	spin_lock_bh(&rc->rsvs_lock);
 	if (rc->set_drp_ie_pending > 1) {
 		rc->set_drp_ie_pending = 0;
 		uwb_rsv_queue_update(rc);	
 	} else {
 		rc->set_drp_ie_pending = 0;	
 	}
-	spin_unlock(&rc->rsvs_lock);
+	spin_unlock_bh(&rc->rsvs_lock);
 }
 
 /**
diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c
index ec6eecb32f30..6b76f4bb4cc7 100644
--- a/drivers/uwb/rsv.c
+++ b/drivers/uwb/rsv.c
@@ -114,7 +114,8 @@ void uwb_rsv_dump(char *text, struct uwb_rsv *rsv)
 		devaddr = rsv->target.devaddr;
 	uwb_dev_addr_print(target, sizeof(target), &devaddr);
 
-	dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state));
+	dev_dbg(dev, "rsv %s %s -> %s: %s\n",
+		text, owner, target, uwb_rsv_state_str(rsv->state));
 }
 
 static void uwb_rsv_release(struct kref *kref)
@@ -511,8 +512,7 @@ void uwb_rsv_remove(struct uwb_rsv *rsv)
 
 	if (uwb_rsv_is_owner(rsv))
 		uwb_rsv_put_stream(rsv);
-	
-	del_timer_sync(&rsv->timer);
+
 	uwb_dev_put(rsv->owner);
 	if (rsv->target.type == UWB_RSV_TARGET_DEV)
 		uwb_dev_put(rsv->target.dev);
@@ -870,7 +870,7 @@ void uwb_rsv_queue_update(struct uwb_rc *rc)
  */
 void uwb_rsv_sched_update(struct uwb_rc *rc)
 {
-	spin_lock(&rc->rsvs_lock);
+	spin_lock_bh(&rc->rsvs_lock);
 	if (!delayed_work_pending(&rc->rsv_update_work)) {
 		if (rc->set_drp_ie_pending > 0) {
 			rc->set_drp_ie_pending++;
@@ -879,7 +879,7 @@ void uwb_rsv_sched_update(struct uwb_rc *rc)
 		uwb_rsv_queue_update(rc);
 	}
 unlock:
-	spin_unlock(&rc->rsvs_lock);
+	spin_unlock_bh(&rc->rsvs_lock);
 }
 
 /*
@@ -943,13 +943,22 @@ void uwb_rsv_remove_all(struct uwb_rc *rc)
 
 	mutex_lock(&rc->rsvs_mutex);
 	list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
-		uwb_rsv_remove(rsv);
+		if (rsv->state != UWB_RSV_STATE_NONE)
+			uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
+		del_timer_sync(&rsv->timer);
 	}
 	/* Cancel any postponed update. */
 	rc->set_drp_ie_pending = 0;
 	mutex_unlock(&rc->rsvs_mutex);
 
 	cancel_delayed_work_sync(&rc->rsv_update_work);
+	flush_workqueue(rc->rsv_workq);
+
+	mutex_lock(&rc->rsvs_mutex);
+	list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
+		uwb_rsv_remove(rsv);
+	}
+	mutex_unlock(&rc->rsvs_mutex);
 }
 
 void uwb_rsv_init(struct uwb_rc *rc)
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index db16112cf197..e6e299feb51b 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1475,7 +1475,7 @@ static int aty128fb_set_par(struct fb_info *info)
 	aty128_set_pll(&par->pll, par);
 	aty128_set_fifo(&par->fifo_reg, par);
 
-	config = aty_ld_le32(CONFIG_CNTL) & ~3;
+	config = aty_ld_le32(CNFG_CNTL) & ~3;
 
 #if defined(__BIG_ENDIAN)
 	if (par->crtc.bpp == 32)
@@ -1484,7 +1484,7 @@ static int aty128fb_set_par(struct fb_info *info)
 		config |= 1;	/* make aperture do 16 bit swapping */
 #endif
 
-	aty_st_le32(CONFIG_CNTL, config);
+	aty_st_le32(CNFG_CNTL, config);
 	aty_st_8(CRTC_EXT_CNTL + 1, 0);	/* turn the video back on */
 
 	info->fix.line_length = (par->crtc.vxres * par->crtc.bpp) >> 3;
@@ -1875,7 +1875,7 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
 	u32 dac;
 
 	/* Get the chip revision */
-	chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
+	chip_rev = (aty_ld_le32(CNFG_CNTL) >> 16) & 0x1F;
 
 	strcpy(video_card, "Rage128 XX ");
 	video_card[8] = ent->device >> 8;
@@ -2057,7 +2057,7 @@ static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_
 
 	/* Grab memory size from the card */
 	// How does this relate to the resource length from the PCI hardware?
-	par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
+	par->vram_size = aty_ld_le32(CNFG_MEMSIZE) & 0x03FFFFFF;
 
 	/* Virtualize the framebuffer */
 	info->screen_base = ioremap(fb_addr, par->vram_size);
@@ -2374,6 +2374,8 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
 	/* Set the chip into the appropriate suspend mode (we use D2,
 	 * D3 would require a complete re-initialisation of the chip,
 	 * including PCI config registers, clocks, AGP configuration, ...)
+	 *
+	 * For resume, the core will have already brought us back to D0
 	 */
 	if (suspend) {
 		/* Make sure CRTC2 is reset. Remove that the day we decide to
@@ -2391,17 +2393,9 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
 		aty_st_le32(BUS_CNTL1, 0x00000010);
 		aty_st_le32(MEM_POWER_MISC, 0x0c830000);
 		mdelay(100);
-		pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+
 		/* Switch PCI power management to D2 */
-		pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL,
-			(pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2);
-		pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
-	} else {
-		/* Switch back PCI power management to D0 */
-		mdelay(100);
-		pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 0);
-		pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
-		mdelay(100);
+		pci_set_power_state(pdev, PCI_D2);
 	}
 }
 
@@ -2410,6 +2404,12 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 	struct fb_info *info = pci_get_drvdata(pdev);
 	struct aty128fb_par *par = info->par;
 
+	/* Because we may change PCI D state ourselves, we need to
+	 * first save the config space content so the core can
+	 * restore it properly on resume.
+	 */
+	pci_save_state(pdev);
+
 	/* We don't do anything but D2, for now we return 0, but
 	 * we may want to change that. How do we know if the BIOS
 	 * can properly take care of D3 ? Also, with swsusp, we
@@ -2476,6 +2476,11 @@ static int aty128_do_resume(struct pci_dev *pdev)
 	if (pdev->dev.power.power_state.event == PM_EVENT_ON)
 		return 0;
 
+	/* PCI state will have been restored by the core, so
+	 * we should be in D0 now with our config space fully
+	 * restored
+	 */
+
 	/* Wakeup chip */
 	aty128_set_suspend(par, 0);
 	par->asleep = 0;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index cc6b470073da..1207c208a30b 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -135,7 +135,7 @@
 #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \
 defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT)
 static const u32 lt_lcd_regs[] = {
-	CONFIG_PANEL_LG,
+	CNFG_PANEL_LG,
 	LCD_GEN_CNTL_LG,
 	DSTN_CONTROL_LG,
 	HFB_PITCH_ADDR_LG,
@@ -446,7 +446,7 @@ static int __devinit correct_chipset(struct atyfb_par *par)
 	par->pll_limits.ecp_max = aty_chips[i].ecp_max;
 	par->features = aty_chips[i].features;
 
-	chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
+	chip_id = aty_ld_le32(CNFG_CHIP_ID, par);
 	type = chip_id & CFG_CHIP_TYPE;
 	rev = (chip_id & CFG_CHIP_REV) >> 24;
 
@@ -629,7 +629,7 @@ static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
 		    crtc->lcd_index = aty_ld_le32(LCD_INDEX, par);
 		    aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
 		}
-		crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par);
+		crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par);
 		crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par);
 
 
@@ -676,7 +676,7 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
 		aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par);
 
 		/* update non-shadow registers first */
-		aty_st_lcd(CONFIG_PANEL, crtc->lcd_config_panel, par);
+		aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par);
 		aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
 			~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
 
@@ -858,7 +858,7 @@ static int aty_var_to_crtc(const struct fb_info *info,
 		if (!M64_HAS(MOBIL_BUS))
 			crtc->lcd_index |= CRTC2_DISPLAY_DIS;
 
-		crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par) | 0x4000;
+		crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par) | 0x4000;
 		crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT;
 
 		crtc->lcd_gen_cntl &=
@@ -1978,7 +1978,7 @@ static int aty_power_mgmt(int sleep, struct atyfb_par *par)
 
 	return timeout ? 0 : -EIO;
 }
-#endif
+#endif /* CONFIG_PPC_PMAC */
 
 static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
@@ -2002,9 +2002,15 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 	par->asleep = 1;
 	par->lock_blank = 1;
 
+	/* Because we may change PCI D state ourselves, we need to
+	 * first save the config space content so the core can
+	 * restore it properly on resume.
+	 */
+	pci_save_state(pdev);
+
 #ifdef CONFIG_PPC_PMAC
 	/* Set chip to "suspend" mode */
-	if (aty_power_mgmt(1, par)) {
+	if (machine_is(powermac) && aty_power_mgmt(1, par)) {
 		par->asleep = 0;
 		par->lock_blank = 0;
 		atyfb_blank(FB_BLANK_UNBLANK, info);
@@ -2047,11 +2053,15 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
 
 	acquire_console_sem();
 
+	/* PCI state will have been restored by the core, so
+	 * we should be in D0 now with our config space fully
+	 * restored
+	 */
+
 #ifdef CONFIG_PPC_PMAC
-	if (pdev->dev.power.power_state.event == 2)
+	if (machine_is(powermac) &&
+	    pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
 		aty_power_mgmt(0, par);
-#else
-	pci_set_power_state(pdev, PCI_D0);
 #endif
 
 	aty_resume_chip(info);
@@ -2254,7 +2264,7 @@ static int __devinit aty_init(struct fb_info *info)
 	if (!M64_HAS(INTEGRATED)) {
 		u32 stat0;
 		u8 dac_type, dac_subtype, clk_type;
-		stat0 = aty_ld_le32(CONFIG_STAT0, par);
+		stat0 = aty_ld_le32(CNFG_STAT0, par);
 		par->bus_type = (stat0 >> 0) & 0x07;
 		par->ram_type = (stat0 >> 3) & 0x07;
 		ramname = aty_gx_ram[par->ram_type];
@@ -2324,7 +2334,7 @@ static int __devinit aty_init(struct fb_info *info)
 		par->dac_ops = &aty_dac_ct;
 		par->pll_ops = &aty_pll_ct;
 		par->bus_type = PCI;
-		par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
+		par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07);
 		ramname = aty_ct_ram[par->ram_type];
 		/* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
 		if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
@@ -2433,7 +2443,7 @@ static int __devinit aty_init(struct fb_info *info)
 		}
 
 	if (M64_HAS(MAGIC_VRAM_SIZE)) {
-		if (aty_ld_le32(CONFIG_STAT1, par) & 0x40000000)
+		if (aty_ld_le32(CNFG_STAT1, par) & 0x40000000)
 			info->fix.smem_len += 0x400000;
 	}
 
@@ -2946,7 +2956,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
 		 * Fix PROMs idea of MEM_CNTL settings...
 		 */
 		mem = aty_ld_le32(MEM_CNTL, par);
-		chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
+		chip_id = aty_ld_le32(CNFG_CHIP_ID, par);
 		if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) {
 			switch (mem & 0x0f) {
 			case 3:
@@ -2964,7 +2974,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
 			default:
 				break;
 			}
-			if ((aty_ld_le32(CONFIG_STAT0, par) & 7) >= SDRAM)
+			if ((aty_ld_le32(CNFG_STAT0, par) & 7) >= SDRAM)
 				mem &= ~(0x00700000);
 		}
 		mem &= ~(0xcf80e000);	/* Turn off all undocumented bits. */
@@ -3572,7 +3582,7 @@ static int __init atyfb_atari_probe(void)
 		}
 
 		/* Fake pci_id for correct_chipset() */
-		switch (aty_ld_le32(CONFIG_CHIP_ID, par) & CFG_CHIP_TYPE) {
+		switch (aty_ld_le32(CNFG_CHIP_ID, par) & CFG_CHIP_TYPE) {
 		case 0x00d7:
 			par->pci_id = PCI_CHIP_MACH64GX;
 			break;
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
index c50c7cf26fe9..2745b8539485 100644
--- a/drivers/video/aty/mach64_ct.c
+++ b/drivers/video/aty/mach64_ct.c
@@ -8,6 +8,9 @@
 #include <asm/io.h>
 #include <video/mach64.h>
 #include "atyfb.h"
+#ifdef CONFIG_PPC
+#include <asm/machdep.h>
+#endif
 
 #undef DEBUG
 
@@ -536,6 +539,14 @@ static int __devinit aty_init_pll_ct(const struct fb_info *info,
 	pll->ct.xclk_post_div_real = postdividers[xpost_div];
 	pll->ct.mclk_fb_div = q * pll->ct.xclk_post_div_real / 8;
 
+#ifdef CONFIG_PPC
+	if (machine_is(powermac)) {
+		/* Override PLL_EXT_CNTL & 0x07. */
+		pll->ct.xclk_post_div = xpost_div;
+		pll->ct.xclk_ref_div = 1;
+	}
+#endif
+
 #ifdef DEBUG
 	pllmclk = (1000000 * pll->ct.mclk_fb_mult * pll->ct.mclk_fb_div) /
 			(par->ref_clk_per * pll->ct.pll_ref_div);
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index d0f1a7fc2c9d..16bb7e3c0310 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -1936,8 +1936,8 @@ static void fixup_memory_mappings(struct radeonfb_info *rinfo)
 	OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl | CRTC_DISP_REQ_EN_B);
 	mdelay(100);
 
-	aper_base = INREG(CONFIG_APER_0_BASE);
-	aper_size = INREG(CONFIG_APER_SIZE);
+	aper_base = INREG(CNFG_APER_0_BASE);
+	aper_size = INREG(CNFG_APER_SIZE);
 
 #ifdef SET_MC_FB_FROM_APERTURE
 	/* Set framebuffer to be at the same address as set in PCI BAR */
@@ -2024,11 +2024,11 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
                      ~CRTC_H_CUTOFF_ACTIVE_EN);
           }
         } else {
-          tmp = INREG(CONFIG_MEMSIZE);
+          tmp = INREG(CNFG_MEMSIZE);
         }
 
 	/* mem size is bits [28:0], mask off the rest */
-	rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
+	rinfo->video_ram = tmp & CNFG_MEMSIZE_MASK;
 
 	/*
 	 * Hack to get around some busted production M6's
@@ -2228,7 +2228,7 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
 	 */
 	rinfo->errata = 0;
 	if (rinfo->family == CHIP_FAMILY_R300 &&
-	    (INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK)
+	    (INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK)
 	    == CFG_ATI_REV_A11)
 		rinfo->errata |= CHIP_ERRATA_R300_CG;
 
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 675abdafc2d8..ca5f0dc28546 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -333,7 +333,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
 	if (!rinfo->has_CRTC2) {
                 tmp = INPLL(pllSCLK_CNTL);
 
-		if ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13)
+		if ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13)
                     tmp &= ~(SCLK_CNTL__FORCE_CP	| SCLK_CNTL__FORCE_RB);
                 tmp &= ~(SCLK_CNTL__FORCE_HDP		| SCLK_CNTL__FORCE_DISP1 |
 			 SCLK_CNTL__FORCE_TOP		| SCLK_CNTL__FORCE_SE   |
@@ -468,9 +468,9 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
 
 	/*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/
 	if ((rinfo->family == CHIP_FAMILY_RV250 &&
-	     ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) ||
+	     ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) ||
 	    ((rinfo->family == CHIP_FAMILY_RV100) &&
-	     ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) {
+	     ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) {
 		tmp |= SCLK_CNTL__FORCE_CP;
 		tmp |= SCLK_CNTL__FORCE_VIP;
 	}
@@ -486,7 +486,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
 		/* RV200::A11 A12 RV250::A11 A12 */
 		if (((rinfo->family == CHIP_FAMILY_RV200) ||
 		     (rinfo->family == CHIP_FAMILY_RV250)) &&
-		    ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13))
+		    ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13))
 			tmp |= SCLK_MORE_CNTL__FORCEON;
 
 		OUTPLL(pllSCLK_MORE_CNTL, tmp);
@@ -497,7 +497,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
 	/* RV200::A11 A12, RV250::A11 A12 */
 	if (((rinfo->family == CHIP_FAMILY_RV200) ||
 	     (rinfo->family == CHIP_FAMILY_RV250)) &&
-	    ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) {
+	    ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) {
 		tmp = INPLL(pllPLL_PWRMGT_CNTL);
 		tmp |= PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE;
 		OUTPLL(pllPLL_PWRMGT_CNTL, tmp);
@@ -702,7 +702,7 @@ static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
 	OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
 	OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
 	OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
-	OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+	OUTREG(CNFG_MEMSIZE, rinfo->video_ram);
 
 	OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
 	OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]);
@@ -1723,7 +1723,7 @@ static void radeon_reinitialize_M10(struct radeonfb_info *rinfo)
 	OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
 	OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
 	OUTREG(OV0_BASE_ADDR, rinfo->save_regs[80]);
-	OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+	OUTREG(CNFG_MEMSIZE, rinfo->video_ram);
 	OUTREG(BUS_CNTL, rinfo->save_regs[36]);
 	OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
 	OUTREG(MPP_TB_CONFIG, rinfo->save_regs[37]);
@@ -1961,7 +1961,7 @@ static void radeon_pm_m9p_reconfigure_mc(struct radeonfb_info *rinfo)
 	OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, rinfo->save_regs[68] /*0x141555ff*/);
 	OUTMC(rinfo, ixMC_IMP_CNTL_0, rinfo->save_regs[71] /*0x00009249*/);
 	OUTREG(MC_IND_INDEX, 0);
-	OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+	OUTREG(CNFG_MEMSIZE, rinfo->video_ram);
 
 	mdelay(20);
 }
@@ -2361,7 +2361,7 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
 	OUTMC(rinfo, ixMC_IMP_CNTL_0, 0x00009249);
 	OUTREG(MC_IND_INDEX, 0);
 
-	OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+	OUTREG(CNFG_MEMSIZE, rinfo->video_ram);
 
 	radeon_pm_full_reset_sdram(rinfo);
 
@@ -2509,9 +2509,7 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
 
 static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
 {
-	u16 pwr_cmd;
 	u32 tmp;
-	int i;
 
 	if (!rinfo->pm_reg)
 		return;
@@ -2557,32 +2555,14 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
 			}
 		}
 
-		for (i = 0; i < 64; ++i)
-			pci_read_config_dword(rinfo->pdev, i * 4,
-					      &rinfo->cfg_save[i]);
-
 		/* Switch PCI power management to D2. */
 		pci_disable_device(rinfo->pdev);
-		for (;;) {
-			pci_read_config_word(
-				rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
-				&pwr_cmd);
-			if (pwr_cmd & 2)
-				break;			
-			pci_write_config_word(
-				rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
-				(pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
-			mdelay(500);
-		}
+		pci_save_state(rinfo->pdev);
+		pci_set_power_state(rinfo->pdev, PCI_D2);
 	} else {
 		printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n",
 		       pci_name(rinfo->pdev));
 
-		/* Switch back PCI powermanagment to D0 */
-		mdelay(200);
-		pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
-		mdelay(500);
-
 		if (rinfo->family <= CHIP_FAMILY_RV250) {
 			/* Reset the SDRAM controller  */
 			radeon_pm_full_reset_sdram(rinfo);
@@ -2598,37 +2578,10 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
 	}
 }
 
-static int radeon_restore_pci_cfg(struct radeonfb_info *rinfo)
-{
-	int i;
-	static u32 radeon_cfg_after_resume[64];
-
-	for (i = 0; i < 64; ++i)
-		pci_read_config_dword(rinfo->pdev, i * 4,
-				      &radeon_cfg_after_resume[i]);
-
-	if (radeon_cfg_after_resume[PCI_BASE_ADDRESS_0/4]
-	    == rinfo->cfg_save[PCI_BASE_ADDRESS_0/4])
-		return 0;	/* assume everything is ok */
-
-	for (i = PCI_BASE_ADDRESS_0/4; i < 64; ++i) {
-		if (radeon_cfg_after_resume[i] != rinfo->cfg_save[i])
-			pci_write_config_dword(rinfo->pdev, i * 4,
-					       rinfo->cfg_save[i]);
-	}
-	pci_write_config_word(rinfo->pdev, PCI_CACHE_LINE_SIZE,
-			      rinfo->cfg_save[PCI_CACHE_LINE_SIZE/4]);
-	pci_write_config_word(rinfo->pdev, PCI_COMMAND,
-			      rinfo->cfg_save[PCI_COMMAND/4]);
-	return 1;
-}
-
-
 int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
         struct fb_info *info = pci_get_drvdata(pdev);
         struct radeonfb_info *rinfo = info->par;
-	int i;
 
 	if (mesg.event == pdev->dev.power.power_state.event)
 		return 0;
@@ -2674,6 +2627,11 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
 	pmac_suspend_agp_for_card(pdev);
 #endif /* CONFIG_PPC_PMAC */
 
+	/* It's unclear whether or when the generic code will do that, so let's
+	 * do it ourselves. We save state before we do any power management
+	 */
+	pci_save_state(pdev);
+
 	/* If we support wakeup from poweroff, we save all regs we can including cfg
 	 * space
 	 */
@@ -2698,9 +2656,6 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
 			mdelay(20);
 			OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) & ~(LVDS_DIGON));
 		}
-		// FIXME: Use PCI layer
-		for (i = 0; i < 64; ++i)
-			pci_read_config_dword(pdev, i * 4, &rinfo->cfg_save[i]);
 		pci_disable_device(pdev);
 	}
 	/* If we support D2, we go to it (should be fixed later with a flag forcing
@@ -2717,6 +2672,13 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
 	return 0;
 }
 
+static int radeon_check_power_loss(struct radeonfb_info *rinfo)
+{
+	return rinfo->save_regs[4] != INPLL(CLK_PIN_CNTL) ||
+	       rinfo->save_regs[2] != INPLL(MCLK_CNTL) ||
+	       rinfo->save_regs[3] != INPLL(SCLK_CNTL);
+}
+
 int radeonfb_pci_resume(struct pci_dev *pdev)
 {
         struct fb_info *info = pci_get_drvdata(pdev);
@@ -2735,20 +2697,13 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
 	printk(KERN_DEBUG "radeonfb (%s): resuming from state: %d...\n",
 	       pci_name(pdev), pdev->dev.power.power_state.event);
 
-
-	if (pci_enable_device(pdev)) {
-		rc = -ENODEV;
-		printk(KERN_ERR "radeonfb (%s): can't enable PCI device !\n",
-		       pci_name(pdev));
-		goto bail;
-	}
-	pci_set_master(pdev);
-
+	/* PCI state will have been restored by the core, so
+	 * we should be in D0 now with our config space fully
+	 * restored
+	 */
 	if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
-		/* Wakeup chip. Check from config space if we were powered off
-		 * (todo: additionally, check CLK_PIN_CNTL too)
-		 */
-		if ((rinfo->pm_mode & radeon_pm_off) && radeon_restore_pci_cfg(rinfo)) {
+		/* Wakeup chip */
+		if ((rinfo->pm_mode & radeon_pm_off) && radeon_check_power_loss(rinfo)) {
 			if (rinfo->reinit_func != NULL)
 				rinfo->reinit_func(rinfo);
 			else {
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 3ea1b00fdd22..7351e66c7f54 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -361,8 +361,6 @@ struct radeonfb_info {
 #ifdef CONFIG_FB_RADEON_I2C
 	struct radeon_i2c_chan 	i2c[4];
 #endif
-
-	u32			cfg_save[64];
 };
 
 
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 363b3cb2f01b..63d759498165 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -18,7 +18,7 @@ obj-$(CONFIG_BACKLIGHT_OMAP1)	+= omap1_bl.o
 obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
 obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
 obj-$(CONFIG_BACKLIGHT_PWM)	+= pwm_bl.o
-obj-$(CONFIG_BACKLIGHT_DA903X)	+= da903x.o
+obj-$(CONFIG_BACKLIGHT_DA903X)	+= da903x_bl.o
 obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
 obj-$(CONFIG_BACKLIGHT_TOSA)	+= tosa_bl.o
 obj-$(CONFIG_BACKLIGHT_SAHARA)	+= kb3886_bl.o
diff --git a/drivers/video/backlight/da903x.c b/drivers/video/backlight/da903x_bl.c
index 93bb4340cc64..93bb4340cc64 100644
--- a/drivers/video/backlight/da903x.c
+++ b/drivers/video/backlight/da903x_bl.c
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 91b78e691505..f53b9f1d6aba 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -250,10 +250,6 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
 	int rc, size = cmap->len * sizeof(u16);
 	struct fb_cmap umap;
 
-	if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
-			        !info->fbops->fb_setcmap))
-		return -EINVAL;
-
 	memset(&umap, 0, sizeof(struct fb_cmap));
 	rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL);
 	if (rc)
@@ -262,11 +258,23 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
 	    copy_from_user(umap.green, cmap->green, size) ||
 	    copy_from_user(umap.blue, cmap->blue, size) ||
 	    (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) {
-		fb_dealloc_cmap(&umap);
-		return -EFAULT;
+		rc = -EFAULT;
+		goto out;
 	}
 	umap.start = cmap->start;
+	if (!lock_fb_info(info)) {
+		rc = -ENODEV;
+		goto out;
+	}
+	if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
+				!info->fbops->fb_setcmap)) {
+		rc = -EINVAL;
+		goto out1;
+	}
 	rc = fb_set_cmap(&umap, info);
+out1:
+	unlock_fb_info(info);
+out:
 	fb_dealloc_cmap(&umap);
 	return rc;
 }
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 756efeb91abc..cfd9dce1ce0b 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1013,132 +1013,139 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
 	struct fb_var_screeninfo var;
 	struct fb_fix_screeninfo fix;
 	struct fb_con2fbmap con2fb;
+	struct fb_cmap cmap_from;
 	struct fb_cmap_user cmap;
 	struct fb_event event;
 	void __user *argp = (void __user *)arg;
 	long ret = 0;
 
-	fb = info->fbops;
-	if (!fb)
-		return -ENODEV;
-
 	switch (cmd) {
 	case FBIOGET_VSCREENINFO:
-		ret = copy_to_user(argp, &info->var,
-				    sizeof(var)) ? -EFAULT : 0;
+		if (!lock_fb_info(info))
+			return -ENODEV;
+		var = info->var;
+		unlock_fb_info(info);
+
+		ret = copy_to_user(argp, &var, sizeof(var)) ? -EFAULT : 0;
 		break;
 	case FBIOPUT_VSCREENINFO:
-		if (copy_from_user(&var, argp, sizeof(var))) {
-			ret =  -EFAULT;
-			break;
-		}
+		if (copy_from_user(&var, argp, sizeof(var)))
+			return -EFAULT;
+		if (!lock_fb_info(info))
+			return -ENODEV;
 		acquire_console_sem();
 		info->flags |= FBINFO_MISC_USEREVENT;
 		ret = fb_set_var(info, &var);
 		info->flags &= ~FBINFO_MISC_USEREVENT;
 		release_console_sem();
-		if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))
+		unlock_fb_info(info);
+		if (!ret && copy_to_user(argp, &var, sizeof(var)))
 			ret = -EFAULT;
 		break;
 	case FBIOGET_FSCREENINFO:
-		ret = copy_to_user(argp, &info->fix,
-				    sizeof(fix)) ? -EFAULT : 0;
+		if (!lock_fb_info(info))
+			return -ENODEV;
+		fix = info->fix;
+		unlock_fb_info(info);
+
+		ret = copy_to_user(argp, &fix, sizeof(fix)) ? -EFAULT : 0;
 		break;
 	case FBIOPUTCMAP:
 		if (copy_from_user(&cmap, argp, sizeof(cmap)))
-			ret = -EFAULT;
-		else
-			ret = fb_set_user_cmap(&cmap, info);
+			return -EFAULT;
+		ret = fb_set_user_cmap(&cmap, info);
 		break;
 	case FBIOGETCMAP:
 		if (copy_from_user(&cmap, argp, sizeof(cmap)))
-			ret = -EFAULT;
-		else
-			ret = fb_cmap_to_user(&info->cmap, &cmap);
+			return -EFAULT;
+		if (!lock_fb_info(info))
+			return -ENODEV;
+		cmap_from = info->cmap;
+		unlock_fb_info(info);
+		ret = fb_cmap_to_user(&cmap_from, &cmap);
 		break;
 	case FBIOPAN_DISPLAY:
-		if (copy_from_user(&var, argp, sizeof(var))) {
-			ret = -EFAULT;
-			break;
-		}
+		if (copy_from_user(&var, argp, sizeof(var)))
+			return -EFAULT;
+		if (!lock_fb_info(info))
+			return -ENODEV;
 		acquire_console_sem();
 		ret = fb_pan_display(info, &var);
 		release_console_sem();
+		unlock_fb_info(info);
 		if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))
-			ret = -EFAULT;
+			return -EFAULT;
 		break;
 	case FBIO_CURSOR:
 		ret = -EINVAL;
 		break;
 	case FBIOGET_CON2FBMAP:
 		if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
-			ret = -EFAULT;
-		else if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
-			ret = -EINVAL;
-		else {
-			con2fb.framebuffer = -1;
-			event.info = info;
-			event.data = &con2fb;
-			fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP,
-								&event);
-			ret = copy_to_user(argp, &con2fb,
-				    sizeof(con2fb)) ? -EFAULT : 0;
-		}
+			return -EFAULT;
+		if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
+			return -EINVAL;
+		con2fb.framebuffer = -1;
+		event.data = &con2fb;
+
+		if (!lock_fb_info(info))
+			return -ENODEV;
+		event.info = info;
+		fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
+		unlock_fb_info(info);
+
+		ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;
 		break;
 	case FBIOPUT_CON2FBMAP:
-		if (copy_from_user(&con2fb, argp, sizeof(con2fb))) {
-			ret = -EFAULT;
-			break;
-		}
-		if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) {
-			ret = -EINVAL;
-			break;
-		}
-		if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) {
-			ret = -EINVAL;
-			break;
-		}
+		if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
+			return -EFAULT;
+		if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
+			return -EINVAL;
+		if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
+			return -EINVAL;
 		if (!registered_fb[con2fb.framebuffer])
 			request_module("fb%d", con2fb.framebuffer);
 		if (!registered_fb[con2fb.framebuffer]) {
 			ret = -EINVAL;
 			break;
 		}
-		event.info = info;
 		event.data = &con2fb;
+		if (!lock_fb_info(info))
+			return -ENODEV;
+		event.info = info;
 		ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP,
 					      &event);
+		unlock_fb_info(info);
 		break;
 	case FBIOBLANK:
+		if (!lock_fb_info(info))
+			return -ENODEV;
 		acquire_console_sem();
 		info->flags |= FBINFO_MISC_USEREVENT;
 		ret = fb_blank(info, arg);
 		info->flags &= ~FBINFO_MISC_USEREVENT;
 		release_console_sem();
-		break;;
+		unlock_fb_info(info);
+		break;
 	default:
-		if (fb->fb_ioctl == NULL)
-			ret = -ENOTTY;
-		else
+		if (!lock_fb_info(info))
+			return -ENODEV;
+		fb = info->fbops;
+		if (fb->fb_ioctl)
 			ret = fb->fb_ioctl(info, cmd, arg);
+		else
+			ret = -ENOTTY;
+		unlock_fb_info(info);
 	}
 	return ret;
 }
 
 static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-__acquires(&info->lock)
-__releases(&info->lock)
 {
 	struct inode *inode = file->f_path.dentry->d_inode;
 	int fbidx = iminor(inode);
-	struct fb_info *info;
-	long ret;
+	struct fb_info *info = registered_fb[fbidx];
 
-	info = registered_fb[fbidx];
-	mutex_lock(&info->lock);
-	ret = do_fb_ioctl(info, cmd, arg);
-	mutex_unlock(&info->lock);
-	return ret;
+	return do_fb_ioctl(info, cmd, arg);
 }
 
 #ifdef CONFIG_COMPAT
@@ -1257,8 +1264,6 @@ static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd,
 
 static long fb_compat_ioctl(struct file *file, unsigned int cmd,
 			    unsigned long arg)
-__acquires(&info->lock)
-__releases(&info->lock)
 {
 	struct inode *inode = file->f_path.dentry->d_inode;
 	int fbidx = iminor(inode);
@@ -1266,7 +1271,6 @@ __releases(&info->lock)
 	struct fb_ops *fb = info->fbops;
 	long ret = -ENOIOCTLCMD;
 
-	mutex_lock(&info->lock);
 	switch(cmd) {
 	case FBIOGET_VSCREENINFO:
 	case FBIOPUT_VSCREENINFO:
@@ -1292,7 +1296,6 @@ __releases(&info->lock)
 			ret = fb->fb_compat_ioctl(info, cmd, arg);
 		break;
 	}
-	mutex_unlock(&info->lock);
 	return ret;
 }
 #endif
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index bef6b45e8a5c..330aacbdec1f 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -192,7 +192,7 @@ static irqreturn_t vp_interrupt(int irq, void *opaque)
 		drv = container_of(vp_dev->vdev.dev.driver,
 				   struct virtio_driver, driver);
 
-		if (drv->config_changed)
+		if (drv && drv->config_changed)
 			drv->config_changed(&vp_dev->vdev);
 	}
 
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index 2ba8f95516a0..efa4b363ce72 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -498,7 +498,7 @@ static ssize_t store_target_kb(struct sys_device *dev,
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	target_bytes = memparse(buf, &endchar);
+	target_bytes = simple_strtoull(buf, &endchar, 0) * 1024;
 
 	balloon_set_new_target(target_bytes >> PAGE_SHIFT);
 
@@ -508,8 +508,39 @@ static ssize_t store_target_kb(struct sys_device *dev,
 static SYSDEV_ATTR(target_kb, S_IRUGO | S_IWUSR,
 		   show_target_kb, store_target_kb);
 
+
+static ssize_t show_target(struct sys_device *dev, struct sysdev_attribute *attr,
+			      char *buf)
+{
+	return sprintf(buf, "%llu\n",
+		       (u64)balloon_stats.target_pages << PAGE_SHIFT);
+}
+
+static ssize_t store_target(struct sys_device *dev,
+			    struct sysdev_attribute *attr,
+			    const char *buf,
+			    size_t count)
+{
+	char *endchar;
+	unsigned long long target_bytes;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	target_bytes = memparse(buf, &endchar);
+
+	balloon_set_new_target(target_bytes >> PAGE_SHIFT);
+
+	return count;
+}
+
+static SYSDEV_ATTR(target, S_IRUGO | S_IWUSR,
+		   show_target, store_target);
+
+
 static struct sysdev_attribute *balloon_attrs[] = {
 	&attr_target_kb,
+	&attr_target,
 };
 
 static struct attribute *balloon_info_attrs[] = {
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index e3ff2b9e602f..33b7235f853b 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1208,9 +1208,11 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
 	 * check for an ELF header.  If we find one, dump the first page to
 	 * aid in determining what was mapped here.
 	 */
-	if (FILTER(ELF_HEADERS) && vma->vm_file != NULL && vma->vm_pgoff == 0) {
+	if (FILTER(ELF_HEADERS) &&
+	    vma->vm_pgoff == 0 && (vma->vm_flags & VM_READ)) {
 		u32 __user *header = (u32 __user *) vma->vm_start;
 		u32 word;
+		mm_segment_t fs = get_fs();
 		/*
 		 * Doing it this way gets the constant folded by GCC.
 		 */
@@ -1223,7 +1225,15 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
 		magic.elfmag[EI_MAG1] = ELFMAG1;
 		magic.elfmag[EI_MAG2] = ELFMAG2;
 		magic.elfmag[EI_MAG3] = ELFMAG3;
-		if (get_user(word, header) == 0 && word == magic.cmp)
+		/*
+		 * Switch to the user "segment" for get_user(),
+		 * then put back what elf_core_dump() had in place.
+		 */
+		set_fs(USER_DS);
+		if (unlikely(get_user(word, header)))
+			word = 0;
+		set_fs(fs);
+		if (word == magic.cmp)
 			return PAGE_SIZE;
 	}
 
diff --git a/fs/btrfs/Kconfig b/fs/btrfs/Kconfig
index f8fcf999ea1b..7bb3c020e570 100644
--- a/fs/btrfs/Kconfig
+++ b/fs/btrfs/Kconfig
@@ -16,3 +16,16 @@ config BTRFS_FS
 	  module will be called btrfs.
 
 	  If unsure, say N.
+
+config BTRFS_FS_POSIX_ACL
+	bool "Btrfs POSIX Access Control Lists"
+	depends on BTRFS_FS
+	select FS_POSIX_ACL
+	help
+	  POSIX Access Control Lists (ACLs) support permissions for users and
+	  groups beyond the owner/group/world scheme.
+
+	  To learn more about Access Control Lists, visit the POSIX ACLs for
+	  Linux website <http://acl.bestbits.at/>.
+
+	  If you don't know what Access Control Lists are, say N
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c
index 8e2fec05dbe0..c84ca1f5259a 100644
--- a/fs/btrfs/async-thread.c
+++ b/fs/btrfs/async-thread.c
@@ -16,11 +16,11 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#include <linux/version.h>
 #include <linux/kthread.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
-# include <linux/freezer.h>
+#include <linux/freezer.h>
+#include <linux/ftrace.h>
 #include "async-thread.h"
 
 #define WORK_QUEUED_BIT 0
@@ -143,6 +143,7 @@ static int worker_loop(void *arg)
 	struct btrfs_work *work;
 	do {
 		spin_lock_irq(&worker->lock);
+again_locked:
 		while (!list_empty(&worker->pending)) {
 			cur = worker->pending.next;
 			work = list_entry(cur, struct btrfs_work, list);
@@ -165,14 +166,50 @@ static int worker_loop(void *arg)
 			check_idle_worker(worker);
 
 		}
-		worker->working = 0;
 		if (freezing(current)) {
+			worker->working = 0;
+			spin_unlock_irq(&worker->lock);
 			refrigerator();
 		} else {
-			set_current_state(TASK_INTERRUPTIBLE);
 			spin_unlock_irq(&worker->lock);
-			if (!kthread_should_stop())
+			if (!kthread_should_stop()) {
+				cpu_relax();
+				/*
+				 * we've dropped the lock, did someone else
+				 * jump_in?
+				 */
+				smp_mb();
+				if (!list_empty(&worker->pending))
+					continue;
+
+				/*
+				 * this short schedule allows more work to
+				 * come in without the queue functions
+				 * needing to go through wake_up_process()
+				 *
+				 * worker->working is still 1, so nobody
+				 * is going to try and wake us up
+				 */
+				schedule_timeout(1);
+				smp_mb();
+				if (!list_empty(&worker->pending))
+					continue;
+
+				/* still no more work?, sleep for real */
+				spin_lock_irq(&worker->lock);
+				set_current_state(TASK_INTERRUPTIBLE);
+				if (!list_empty(&worker->pending))
+					goto again_locked;
+
+				/*
+				 * this makes sure we get a wakeup when someone
+				 * adds something new to the queue
+				 */
+				worker->working = 0;
+				spin_unlock_irq(&worker->lock);
+
 				schedule();
+			}
 			__set_current_state(TASK_RUNNING);
 		}
 	} while (!kthread_should_stop());
@@ -350,13 +387,14 @@ int btrfs_requeue_work(struct btrfs_work *work)
 {
 	struct btrfs_worker_thread *worker = work->worker;
 	unsigned long flags;
+	int wake = 0;
 
 	if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags))
 		goto out;
 
 	spin_lock_irqsave(&worker->lock, flags);
-	atomic_inc(&worker->num_pending);
 	list_add_tail(&work->list, &worker->pending);
+	atomic_inc(&worker->num_pending);
 
 	/* by definition we're busy, take ourselves off the idle
 	 * list
@@ -368,10 +406,16 @@ int btrfs_requeue_work(struct btrfs_work *work)
 			       &worker->workers->worker_list);
 		spin_unlock_irqrestore(&worker->workers->lock, flags);
 	}
+	if (!worker->working) {
+		wake = 1;
+		worker->working = 1;
+	}
 
 	spin_unlock_irqrestore(&worker->lock, flags);
-
+	if (wake)
+		wake_up_process(worker->task);
 out:
+
 	return 0;
 }
 
@@ -398,9 +442,10 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work)
 	}
 
 	spin_lock_irqsave(&worker->lock, flags);
+
+	list_add_tail(&work->list, &worker->pending);
 	atomic_inc(&worker->num_pending);
 	check_busy_worker(worker);
-	list_add_tail(&work->list, &worker->pending);
 
 	/*
 	 * avoid calling into wake_up_process if this thread has already
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index ee848d8585d9..ab07627084f1 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -32,7 +32,6 @@
 #include <linux/swap.h>
 #include <linux/writeback.h>
 #include <linux/bit_spinlock.h>
-#include <linux/version.h>
 #include <linux/pagevec.h>
 #include "compat.h"
 #include "ctree.h"
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 9e46c0776816..551177c0011a 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -54,6 +54,31 @@ struct btrfs_path *btrfs_alloc_path(void)
 	return path;
 }
 
+/*
+ * set all locked nodes in the path to blocking locks.  This should
+ * be done before scheduling
+ */
+noinline void btrfs_set_path_blocking(struct btrfs_path *p)
+{
+	int i;
+	for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
+		if (p->nodes[i] && p->locks[i])
+			btrfs_set_lock_blocking(p->nodes[i]);
+	}
+}
+
+/*
+ * reset all the locked nodes in the patch to spinning locks.
+ */
+noinline void btrfs_clear_path_blocking(struct btrfs_path *p)
+{
+	int i;
+	for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
+		if (p->nodes[i] && p->locks[i])
+			btrfs_clear_lock_blocking(p->nodes[i]);
+	}
+}
+
 /* this also releases the path */
 void btrfs_free_path(struct btrfs_path *p)
 {
@@ -272,6 +297,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
 	if (IS_ERR(cow))
 		return PTR_ERR(cow);
 
+	/* cow is set to blocking by btrfs_init_new_buffer */
+
 	copy_extent_buffer(cow, buf, 0, 0, cow->len);
 	btrfs_set_header_bytenr(cow, cow->start);
 	btrfs_set_header_generation(cow, trans->transid);
@@ -388,17 +415,20 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
 		WARN_ON(1);
 	}
 
-	spin_lock(&root->fs_info->hash_lock);
 	if (btrfs_header_generation(buf) == trans->transid &&
 	    btrfs_header_owner(buf) == root->root_key.objectid &&
 	    !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) {
 		*cow_ret = buf;
-		spin_unlock(&root->fs_info->hash_lock);
 		WARN_ON(prealloc_dest);
 		return 0;
 	}
-	spin_unlock(&root->fs_info->hash_lock);
+
 	search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1);
+
+	if (parent)
+		btrfs_set_lock_blocking(parent);
+	btrfs_set_lock_blocking(buf);
+
 	ret = __btrfs_cow_block(trans, root, buf, parent,
 				 parent_slot, cow_ret, search_start, 0,
 				 prealloc_dest);
@@ -504,6 +534,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
 	if (parent_nritems == 1)
 		return 0;
 
+	btrfs_set_lock_blocking(parent);
+
 	for (i = start_slot; i < end_slot; i++) {
 		int close = 1;
 
@@ -564,6 +596,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
 			search_start = last_block;
 
 		btrfs_tree_lock(cur);
+		btrfs_set_lock_blocking(cur);
 		err = __btrfs_cow_block(trans, root, cur, parent, i,
 					&cur, search_start,
 					min(16 * blocksize,
@@ -862,6 +895,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
 		return 0;
 
 	mid = path->nodes[level];
+
 	WARN_ON(!path->locks[level]);
 	WARN_ON(btrfs_header_generation(mid) != trans->transid);
 
@@ -884,6 +918,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
 		/* promote the child to a root */
 		child = read_node_slot(root, mid, 0);
 		btrfs_tree_lock(child);
+		btrfs_set_lock_blocking(child);
 		BUG_ON(!child);
 		ret = btrfs_cow_block(trans, root, child, mid, 0, &child, 0);
 		BUG_ON(ret);
@@ -900,6 +935,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
 
 		add_root_to_dirty_list(root);
 		btrfs_tree_unlock(child);
+
 		path->locks[level] = 0;
 		path->nodes[level] = NULL;
 		clean_tree_block(trans, root, mid);
@@ -924,6 +960,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
 	left = read_node_slot(root, parent, pslot - 1);
 	if (left) {
 		btrfs_tree_lock(left);
+		btrfs_set_lock_blocking(left);
 		wret = btrfs_cow_block(trans, root, left,
 				       parent, pslot - 1, &left, 0);
 		if (wret) {
@@ -934,6 +971,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
 	right = read_node_slot(root, parent, pslot + 1);
 	if (right) {
 		btrfs_tree_lock(right);
+		btrfs_set_lock_blocking(right);
 		wret = btrfs_cow_block(trans, root, right,
 				       parent, pslot + 1, &right, 0);
 		if (wret) {
@@ -1109,6 +1147,8 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
 		u32 left_nr;
 
 		btrfs_tree_lock(left);
+		btrfs_set_lock_blocking(left);
+
 		left_nr = btrfs_header_nritems(left);
 		if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
 			wret = 1;
@@ -1155,7 +1195,10 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
 	 */
 	if (right) {
 		u32 right_nr;
+
 		btrfs_tree_lock(right);
+		btrfs_set_lock_blocking(right);
+
 		right_nr = btrfs_header_nritems(right);
 		if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) {
 			wret = 1;
@@ -1210,8 +1253,7 @@ static noinline void reada_for_search(struct btrfs_root *root,
 	struct btrfs_disk_key disk_key;
 	u32 nritems;
 	u64 search;
-	u64 lowest_read;
-	u64 highest_read;
+	u64 target;
 	u64 nread = 0;
 	int direction = path->reada;
 	struct extent_buffer *eb;
@@ -1235,8 +1277,7 @@ static noinline void reada_for_search(struct btrfs_root *root,
 		return;
 	}
 
-	highest_read = search;
-	lowest_read = search;
+	target = search;
 
 	nritems = btrfs_header_nritems(node);
 	nr = slot;
@@ -1256,27 +1297,80 @@ static noinline void reada_for_search(struct btrfs_root *root,
 				break;
 		}
 		search = btrfs_node_blockptr(node, nr);
-		if ((search >= lowest_read && search <= highest_read) ||
-		    (search < lowest_read && lowest_read - search <= 16384) ||
-		    (search > highest_read && search - highest_read <= 16384)) {
+		if ((search <= target && target - search <= 65536) ||
+		    (search > target && search - target <= 65536)) {
 			readahead_tree_block(root, search, blocksize,
 				     btrfs_node_ptr_generation(node, nr));
 			nread += blocksize;
 		}
 		nscan++;
-		if (path->reada < 2 && (nread > (64 * 1024) || nscan > 32))
+		if ((nread > 65536 || nscan > 32))
 			break;
+	}
+}
 
-		if (nread > (256 * 1024) || nscan > 128)
-			break;
+/*
+ * returns -EAGAIN if it had to drop the path, or zero if everything was in
+ * cache
+ */
+static noinline int reada_for_balance(struct btrfs_root *root,
+				      struct btrfs_path *path, int level)
+{
+	int slot;
+	int nritems;
+	struct extent_buffer *parent;
+	struct extent_buffer *eb;
+	u64 gen;
+	u64 block1 = 0;
+	u64 block2 = 0;
+	int ret = 0;
+	int blocksize;
 
-		if (search < lowest_read)
-			lowest_read = search;
-		if (search > highest_read)
-			highest_read = search;
+	parent = path->nodes[level - 1];
+	if (!parent)
+		return 0;
+
+	nritems = btrfs_header_nritems(parent);
+	slot = path->slots[level];
+	blocksize = btrfs_level_size(root, level);
+
+	if (slot > 0) {
+		block1 = btrfs_node_blockptr(parent, slot - 1);
+		gen = btrfs_node_ptr_generation(parent, slot - 1);
+		eb = btrfs_find_tree_block(root, block1, blocksize);
+		if (eb && btrfs_buffer_uptodate(eb, gen))
+			block1 = 0;
+		free_extent_buffer(eb);
+	}
+	if (slot < nritems) {
+		block2 = btrfs_node_blockptr(parent, slot + 1);
+		gen = btrfs_node_ptr_generation(parent, slot + 1);
+		eb = btrfs_find_tree_block(root, block2, blocksize);
+		if (eb && btrfs_buffer_uptodate(eb, gen))
+			block2 = 0;
+		free_extent_buffer(eb);
+	}
+	if (block1 || block2) {
+		ret = -EAGAIN;
+		btrfs_release_path(root, path);
+		if (block1)
+			readahead_tree_block(root, block1, blocksize, 0);
+		if (block2)
+			readahead_tree_block(root, block2, blocksize, 0);
+
+		if (block1) {
+			eb = read_tree_block(root, block1, blocksize, 0);
+			free_extent_buffer(eb);
+		}
+		if (block1) {
+			eb = read_tree_block(root, block2, blocksize, 0);
+			free_extent_buffer(eb);
+		}
 	}
+	return ret;
 }
 
+
 /*
  * when we walk down the tree, it is usually safe to unlock the higher layers
  * in the tree.  The exceptions are when our path goes through slot 0, because
@@ -1328,6 +1422,32 @@ static noinline void unlock_up(struct btrfs_path *path, int level,
 }
 
 /*
+ * This releases any locks held in the path starting at level and
+ * going all the way up to the root.
+ *
+ * btrfs_search_slot will keep the lock held on higher nodes in a few
+ * corner cases, such as COW of the block at slot zero in the node.  This
+ * ignores those rules, and it should only be called when there are no
+ * more updates to be done higher up in the tree.
+ */
+noinline void btrfs_unlock_up_safe(struct btrfs_path *path, int level)
+{
+	int i;
+
+	if (path->keep_locks || path->lowest_level)
+		return;
+
+	for (i = level; i < BTRFS_MAX_LEVEL; i++) {
+		if (!path->nodes[i])
+			continue;
+		if (!path->locks[i])
+			continue;
+		btrfs_tree_unlock(path->nodes[i]);
+		path->locks[i] = 0;
+	}
+}
+
+/*
  * look for key in the tree.  path is filled in with nodes along the way
  * if key is found, we return zero and you can find the item in the leaf
  * level of the path (level 0)
@@ -1387,31 +1507,30 @@ again:
 			int wret;
 
 			/* is a cow on this block not required */
-			spin_lock(&root->fs_info->hash_lock);
 			if (btrfs_header_generation(b) == trans->transid &&
 			    btrfs_header_owner(b) == root->root_key.objectid &&
 			    !btrfs_header_flag(b, BTRFS_HEADER_FLAG_WRITTEN)) {
-				spin_unlock(&root->fs_info->hash_lock);
 				goto cow_done;
 			}
-			spin_unlock(&root->fs_info->hash_lock);
 
 			/* ok, we have to cow, is our old prealloc the right
 			 * size?
 			 */
 			if (prealloc_block.objectid &&
 			    prealloc_block.offset != b->len) {
+				btrfs_release_path(root, p);
 				btrfs_free_reserved_extent(root,
 					   prealloc_block.objectid,
 					   prealloc_block.offset);
 				prealloc_block.objectid = 0;
+				goto again;
 			}
 
 			/*
 			 * for higher level blocks, try not to allocate blocks
 			 * with the block and the parent locks held.
 			 */
-			if (level > 1 && !prealloc_block.objectid &&
+			if (level > 0 && !prealloc_block.objectid &&
 			    btrfs_path_lock_waiting(p, level)) {
 				u32 size = b->len;
 				u64 hint = b->start;
@@ -1425,6 +1544,8 @@ again:
 				goto again;
 			}
 
+			btrfs_set_path_blocking(p);
+
 			wret = btrfs_cow_block(trans, root, b,
 					       p->nodes[level + 1],
 					       p->slots[level + 1],
@@ -1446,6 +1567,22 @@ cow_done:
 		if (!p->skip_locking)
 			p->locks[level] = 1;
 
+		btrfs_clear_path_blocking(p);
+
+		/*
+		 * we have a lock on b and as long as we aren't changing
+		 * the tree, there is no way to for the items in b to change.
+		 * It is safe to drop the lock on our parent before we
+		 * go through the expensive btree search on b.
+		 *
+		 * If cow is true, then we might be changing slot zero,
+		 * which may require changing the parent.  So, we can't
+		 * drop the lock until after we know which slot we're
+		 * operating on.
+		 */
+		if (!cow)
+			btrfs_unlock_up_safe(p, level + 1);
+
 		ret = check_block(root, p, level);
 		if (ret) {
 			ret = -1;
@@ -1453,6 +1590,7 @@ cow_done:
 		}
 
 		ret = bin_search(b, key, level, &slot);
+
 		if (level != 0) {
 			if (ret && slot > 0)
 				slot -= 1;
@@ -1460,7 +1598,16 @@ cow_done:
 			if ((p->search_for_split || ins_len > 0) &&
 			    btrfs_header_nritems(b) >=
 			    BTRFS_NODEPTRS_PER_BLOCK(root) - 3) {
-				int sret = split_node(trans, root, p, level);
+				int sret;
+
+				sret = reada_for_balance(root, p, level);
+				if (sret)
+					goto again;
+
+				btrfs_set_path_blocking(p);
+				sret = split_node(trans, root, p, level);
+				btrfs_clear_path_blocking(p);
+
 				BUG_ON(sret > 0);
 				if (sret) {
 					ret = sret;
@@ -1468,9 +1615,19 @@ cow_done:
 				}
 				b = p->nodes[level];
 				slot = p->slots[level];
-			} else if (ins_len < 0) {
-				int sret = balance_level(trans, root, p,
-							 level);
+			} else if (ins_len < 0 &&
+				   btrfs_header_nritems(b) <
+				   BTRFS_NODEPTRS_PER_BLOCK(root) / 4) {
+				int sret;
+
+				sret = reada_for_balance(root, p, level);
+				if (sret)
+					goto again;
+
+				btrfs_set_path_blocking(p);
+				sret = balance_level(trans, root, p, level);
+				btrfs_clear_path_blocking(p);
+
 				if (sret) {
 					ret = sret;
 					goto done;
@@ -1504,7 +1661,7 @@ cow_done:
 				 * of the btree by dropping locks before
 				 * we read.
 				 */
-				if (level > 1) {
+				if (level > 0) {
 					btrfs_release_path(NULL, p);
 					if (tmp)
 						free_extent_buffer(tmp);
@@ -1519,6 +1676,7 @@ cow_done:
 						free_extent_buffer(tmp);
 					goto again;
 				} else {
+					btrfs_set_path_blocking(p);
 					if (tmp)
 						free_extent_buffer(tmp);
 					if (should_reada)
@@ -1528,14 +1686,29 @@ cow_done:
 					b = read_node_slot(root, b, slot);
 				}
 			}
-			if (!p->skip_locking)
-				btrfs_tree_lock(b);
+			if (!p->skip_locking) {
+				int lret;
+
+				btrfs_clear_path_blocking(p);
+				lret = btrfs_try_spin_lock(b);
+
+				if (!lret) {
+					btrfs_set_path_blocking(p);
+					btrfs_tree_lock(b);
+					btrfs_clear_path_blocking(p);
+				}
+			}
 		} else {
 			p->slots[level] = slot;
 			if (ins_len > 0 &&
 			    btrfs_leaf_free_space(root, b) < ins_len) {
-				int sret = split_leaf(trans, root, key,
+				int sret;
+
+				btrfs_set_path_blocking(p);
+				sret = split_leaf(trans, root, key,
 						      p, ins_len, ret == 0);
+				btrfs_clear_path_blocking(p);
+
 				BUG_ON(sret > 0);
 				if (sret) {
 					ret = sret;
@@ -1549,12 +1722,16 @@ cow_done:
 	}
 	ret = 1;
 done:
+	/*
+	 * we don't really know what they plan on doing with the path
+	 * from here on, so for now just mark it as blocking
+	 */
+	btrfs_set_path_blocking(p);
 	if (prealloc_block.objectid) {
 		btrfs_free_reserved_extent(root,
 			   prealloc_block.objectid,
 			   prealloc_block.offset);
 	}
-
 	return ret;
 }
 
@@ -1578,6 +1755,8 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans,
 	ret = btrfs_cow_block(trans, root, eb, NULL, 0, &eb, 0);
 	BUG_ON(ret);
 
+	btrfs_set_lock_blocking(eb);
+
 	parent = eb;
 	while (1) {
 		level = btrfs_header_level(parent);
@@ -1602,6 +1781,7 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans,
 			eb = read_tree_block(root, bytenr, blocksize,
 					     generation);
 			btrfs_tree_lock(eb);
+			btrfs_set_lock_blocking(eb);
 		}
 
 		/*
@@ -1626,6 +1806,7 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans,
 				eb = read_tree_block(root, bytenr, blocksize,
 						generation);
 				btrfs_tree_lock(eb);
+				btrfs_set_lock_blocking(eb);
 			}
 
 			ret = btrfs_cow_block(trans, root, eb, parent, slot,
@@ -2172,6 +2353,8 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
 
 	right = read_node_slot(root, upper, slot + 1);
 	btrfs_tree_lock(right);
+	btrfs_set_lock_blocking(right);
+
 	free_space = btrfs_leaf_free_space(root, right);
 	if (free_space < data_size)
 		goto out_unlock;
@@ -2367,6 +2550,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
 
 	left = read_node_slot(root, path->nodes[1], slot - 1);
 	btrfs_tree_lock(left);
+	btrfs_set_lock_blocking(left);
+
 	free_space = btrfs_leaf_free_space(root, left);
 	if (free_space < data_size) {
 		ret = 1;
@@ -2825,6 +3010,12 @@ int btrfs_split_item(struct btrfs_trans_handle *trans,
 	path->keep_locks = 0;
 	BUG_ON(ret);
 
+	/*
+	 * make sure any changes to the path from split_leaf leave it
+	 * in a blocking state
+	 */
+	btrfs_set_path_blocking(path);
+
 	leaf = path->nodes[0];
 	BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item));
 
@@ -3354,6 +3545,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
 		BUG();
 	}
 out:
+	btrfs_unlock_up_safe(path, 1);
 	return ret;
 }
 
@@ -3441,15 +3633,22 @@ noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans,
 {
 	int ret;
 	u64 root_gen = btrfs_header_generation(path->nodes[1]);
+	u64 parent_start = path->nodes[1]->start;
+	u64 parent_owner = btrfs_header_owner(path->nodes[1]);
 
 	ret = del_ptr(trans, root, path, 1, path->slots[1]);
 	if (ret)
 		return ret;
 
+	/*
+	 * btrfs_free_extent is expensive, we want to make sure we
+	 * aren't holding any locks when we call it
+	 */
+	btrfs_unlock_up_safe(path, 0);
+
 	ret = btrfs_free_extent(trans, root, bytenr,
 				btrfs_level_size(root, 0),
-				path->nodes[1]->start,
-				btrfs_header_owner(path->nodes[1]),
+				parent_start, parent_owner,
 				root_gen, 0, 1);
 	return ret;
 }
@@ -3721,12 +3920,14 @@ find_next_key:
 		 */
 		if (slot >= nritems) {
 			path->slots[level] = slot;
+			btrfs_set_path_blocking(path);
 			sret = btrfs_find_next_key(root, path, min_key, level,
 						  cache_only, min_trans);
 			if (sret == 0) {
 				btrfs_release_path(root, path);
 				goto again;
 			} else {
+				btrfs_clear_path_blocking(path);
 				goto out;
 			}
 		}
@@ -3738,16 +3939,20 @@ find_next_key:
 			unlock_up(path, level, 1);
 			goto out;
 		}
+		btrfs_set_path_blocking(path);
 		cur = read_node_slot(root, cur, slot);
 
 		btrfs_tree_lock(cur);
+
 		path->locks[level - 1] = 1;
 		path->nodes[level - 1] = cur;
 		unlock_up(path, level, 1);
+		btrfs_clear_path_blocking(path);
 	}
 out:
 	if (ret == 0)
 		memcpy(min_key, &found_key, sizeof(found_key));
+	btrfs_set_path_blocking(path);
 	return ret;
 }
 
@@ -3843,6 +4048,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
 	if (ret < 0)
 		return ret;
 
+	btrfs_set_path_blocking(path);
 	nritems = btrfs_header_nritems(path->nodes[0]);
 	/*
 	 * by releasing the path above we dropped all our locks.  A balance
@@ -3873,6 +4079,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
 			free_extent_buffer(next);
 		}
 
+		/* the path was set to blocking above */
 		if (level == 1 && (path->locks[1] || path->skip_locking) &&
 		    path->reada)
 			reada_for_search(root, path, level, slot, 0);
@@ -3881,6 +4088,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
 		if (!path->skip_locking) {
 			WARN_ON(!btrfs_tree_locked(c));
 			btrfs_tree_lock(next);
+			btrfs_set_lock_blocking(next);
 		}
 		break;
 	}
@@ -3897,12 +4105,15 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
 			path->locks[level] = 1;
 		if (!level)
 			break;
+
+		btrfs_set_path_blocking(path);
 		if (level == 1 && path->locks[1] && path->reada)
 			reada_for_search(root, path, level, slot, 0);
 		next = read_node_slot(root, next, 0);
 		if (!path->skip_locking) {
 			WARN_ON(!btrfs_tree_locked(path->nodes[level]));
 			btrfs_tree_lock(next);
+			btrfs_set_lock_blocking(next);
 		}
 	}
 done:
@@ -3927,6 +4138,7 @@ int btrfs_previous_item(struct btrfs_root *root,
 
 	while (1) {
 		if (path->slots[0] == 0) {
+			btrfs_set_path_blocking(path);
 			ret = btrfs_prev_leaf(root, path);
 			if (ret != 0)
 				return ret;
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index eee060f88113..531db112c8bd 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -454,17 +454,11 @@ struct btrfs_timespec {
 	__le32 nsec;
 } __attribute__ ((__packed__));
 
-typedef enum {
+enum btrfs_compression_type {
 	BTRFS_COMPRESS_NONE = 0,
 	BTRFS_COMPRESS_ZLIB = 1,
 	BTRFS_COMPRESS_LAST = 2,
-} btrfs_compression_type;
-
-/* we don't understand any encryption methods right now */
-typedef enum {
-	BTRFS_ENCRYPTION_NONE = 0,
-	BTRFS_ENCRYPTION_LAST = 1,
-} btrfs_encryption_type;
+};
 
 struct btrfs_inode_item {
 	/* nfs style generation number */
@@ -701,9 +695,7 @@ struct btrfs_fs_info {
 	struct btrfs_transaction *running_transaction;
 	wait_queue_head_t transaction_throttle;
 	wait_queue_head_t transaction_wait;
-
 	wait_queue_head_t async_submit_wait;
-	wait_queue_head_t tree_log_wait;
 
 	struct btrfs_super_block super_copy;
 	struct btrfs_super_block super_for_commit;
@@ -711,7 +703,6 @@ struct btrfs_fs_info {
 	struct super_block *sb;
 	struct inode *btree_inode;
 	struct backing_dev_info bdi;
-	spinlock_t hash_lock;
 	struct mutex trans_mutex;
 	struct mutex tree_log_mutex;
 	struct mutex transaction_kthread_mutex;
@@ -730,10 +721,6 @@ struct btrfs_fs_info {
 	atomic_t async_submit_draining;
 	atomic_t nr_async_bios;
 	atomic_t async_delalloc_pages;
-	atomic_t tree_log_writers;
-	atomic_t tree_log_commit;
-	unsigned long tree_log_batch;
-	u64 tree_log_transid;
 
 	/*
 	 * this is used by the balancing code to wait for all the pending
@@ -833,7 +820,14 @@ struct btrfs_root {
 	struct kobject root_kobj;
 	struct completion kobj_unregister;
 	struct mutex objectid_mutex;
+
 	struct mutex log_mutex;
+	wait_queue_head_t log_writer_wait;
+	wait_queue_head_t log_commit_wait[2];
+	atomic_t log_writers;
+	atomic_t log_commit[2];
+	unsigned long log_transid;
+	unsigned long log_batch;
 
 	u64 objectid;
 	u64 last_trans;
@@ -1841,6 +1835,10 @@ void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p);
 struct btrfs_path *btrfs_alloc_path(void);
 void btrfs_free_path(struct btrfs_path *p);
 void btrfs_init_path(struct btrfs_path *p);
+void btrfs_set_path_blocking(struct btrfs_path *p);
+void btrfs_clear_path_blocking(struct btrfs_path *p);
+void btrfs_unlock_up_safe(struct btrfs_path *p, int level);
+
 int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 		   struct btrfs_path *path, int slot, int nr);
 int btrfs_del_leaf(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 81a313874ae5..5aebddd71193 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -16,7 +16,6 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#include <linux/version.h>
 #include <linux/fs.h>
 #include <linux/blkdev.h>
 #include <linux/scatterlist.h>
@@ -800,7 +799,7 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
 	ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid);
 
 	if (ret == 0)
-		buf->flags |= EXTENT_UPTODATE;
+		set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags);
 	else
 		WARN_ON(1);
 	return buf;
@@ -814,6 +813,10 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 	if (btrfs_header_generation(buf) ==
 	    root->fs_info->running_transaction->transid) {
 		WARN_ON(!btrfs_tree_locked(buf));
+
+		/* ugh, clear_extent_buffer_dirty can be expensive */
+		btrfs_set_lock_blocking(buf);
+
 		clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree,
 					  buf);
 	}
@@ -850,6 +853,14 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
 	spin_lock_init(&root->list_lock);
 	mutex_init(&root->objectid_mutex);
 	mutex_init(&root->log_mutex);
+	init_waitqueue_head(&root->log_writer_wait);
+	init_waitqueue_head(&root->log_commit_wait[0]);
+	init_waitqueue_head(&root->log_commit_wait[1]);
+	atomic_set(&root->log_commit[0], 0);
+	atomic_set(&root->log_commit[1], 0);
+	atomic_set(&root->log_writers, 0);
+	root->log_batch = 0;
+	root->log_transid = 0;
 	extent_io_tree_init(&root->dirty_log_pages,
 			     fs_info->btree_inode->i_mapping, GFP_NOFS);
 
@@ -934,15 +945,16 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans,
 	return 0;
 }
 
-int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
-			     struct btrfs_fs_info *fs_info)
+static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
+					 struct btrfs_fs_info *fs_info)
 {
 	struct btrfs_root *root;
 	struct btrfs_root *tree_root = fs_info->tree_root;
+	struct extent_buffer *leaf;
 
 	root = kzalloc(sizeof(*root), GFP_NOFS);
 	if (!root)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
 	__setup_root(tree_root->nodesize, tree_root->leafsize,
 		     tree_root->sectorsize, tree_root->stripesize,
@@ -951,12 +963,23 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
 	root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID;
 	root->root_key.type = BTRFS_ROOT_ITEM_KEY;
 	root->root_key.offset = BTRFS_TREE_LOG_OBJECTID;
+	/*
+	 * log trees do not get reference counted because they go away
+	 * before a real commit is actually done.  They do store pointers
+	 * to file data extents, and those reference counts still get
+	 * updated (along with back refs to the log tree).
+	 */
 	root->ref_cows = 0;
 
-	root->node = btrfs_alloc_free_block(trans, root, root->leafsize,
-					    0, BTRFS_TREE_LOG_OBJECTID,
-					    trans->transid, 0, 0, 0);
+	leaf = btrfs_alloc_free_block(trans, root, root->leafsize,
+				      0, BTRFS_TREE_LOG_OBJECTID,
+				      trans->transid, 0, 0, 0);
+	if (IS_ERR(leaf)) {
+		kfree(root);
+		return ERR_CAST(leaf);
+	}
 
+	root->node = leaf;
 	btrfs_set_header_nritems(root->node, 0);
 	btrfs_set_header_level(root->node, 0);
 	btrfs_set_header_bytenr(root->node, root->node->start);
@@ -968,7 +991,48 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
 			    BTRFS_FSID_SIZE);
 	btrfs_mark_buffer_dirty(root->node);
 	btrfs_tree_unlock(root->node);
-	fs_info->log_root_tree = root;
+	return root;
+}
+
+int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
+			     struct btrfs_fs_info *fs_info)
+{
+	struct btrfs_root *log_root;
+
+	log_root = alloc_log_tree(trans, fs_info);
+	if (IS_ERR(log_root))
+		return PTR_ERR(log_root);
+	WARN_ON(fs_info->log_root_tree);
+	fs_info->log_root_tree = log_root;
+	return 0;
+}
+
+int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
+		       struct btrfs_root *root)
+{
+	struct btrfs_root *log_root;
+	struct btrfs_inode_item *inode_item;
+
+	log_root = alloc_log_tree(trans, root->fs_info);
+	if (IS_ERR(log_root))
+		return PTR_ERR(log_root);
+
+	log_root->last_trans = trans->transid;
+	log_root->root_key.offset = root->root_key.objectid;
+
+	inode_item = &log_root->root_item.inode;
+	inode_item->generation = cpu_to_le64(1);
+	inode_item->size = cpu_to_le64(3);
+	inode_item->nlink = cpu_to_le32(1);
+	inode_item->nbytes = cpu_to_le64(root->leafsize);
+	inode_item->mode = cpu_to_le32(S_IFDIR | 0755);
+
+	btrfs_set_root_bytenr(&log_root->root_item, log_root->node->start);
+	btrfs_set_root_generation(&log_root->root_item, trans->transid);
+
+	WARN_ON(root->log_root);
+	root->log_root = log_root;
+	root->log_transid = 0;
 	return 0;
 }
 
@@ -1136,7 +1200,6 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits)
 {
 	struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data;
 	int ret = 0;
-	struct list_head *cur;
 	struct btrfs_device *device;
 	struct backing_dev_info *bdi;
 #if 0
@@ -1144,8 +1207,7 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits)
 	    btrfs_congested_async(info, 0))
 		return 1;
 #endif
-	list_for_each(cur, &info->fs_devices->devices) {
-		device = list_entry(cur, struct btrfs_device, dev_list);
+	list_for_each_entry(device, &info->fs_devices->devices, dev_list) {
 		if (!device->bdev)
 			continue;
 		bdi = blk_get_backing_dev_info(device->bdev);
@@ -1163,13 +1225,11 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits)
  */
 static void __unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
 {
-	struct list_head *cur;
 	struct btrfs_device *device;
 	struct btrfs_fs_info *info;
 
 	info = (struct btrfs_fs_info *)bdi->unplug_io_data;
-	list_for_each(cur, &info->fs_devices->devices) {
-		device = list_entry(cur, struct btrfs_device, dev_list);
+	list_for_each_entry(device, &info->fs_devices->devices, dev_list) {
 		if (!device->bdev)
 			continue;
 
@@ -1447,7 +1507,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 	INIT_LIST_HEAD(&fs_info->dead_roots);
 	INIT_LIST_HEAD(&fs_info->hashers);
 	INIT_LIST_HEAD(&fs_info->delalloc_inodes);
-	spin_lock_init(&fs_info->hash_lock);
 	spin_lock_init(&fs_info->delalloc_lock);
 	spin_lock_init(&fs_info->new_trans_lock);
 	spin_lock_init(&fs_info->ref_cache_lock);
@@ -1535,10 +1594,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 	init_waitqueue_head(&fs_info->transaction_throttle);
 	init_waitqueue_head(&fs_info->transaction_wait);
 	init_waitqueue_head(&fs_info->async_submit_wait);
-	init_waitqueue_head(&fs_info->tree_log_wait);
-	atomic_set(&fs_info->tree_log_commit, 0);
-	atomic_set(&fs_info->tree_log_writers, 0);
-	fs_info->tree_log_transid = 0;
 
 	__setup_root(4096, 4096, 4096, 4096, tree_root,
 		     fs_info, BTRFS_ROOT_TREE_OBJECTID);
@@ -1627,6 +1682,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 	 * low idle thresh
 	 */
 	fs_info->endio_workers.idle_thresh = 4;
+	fs_info->endio_meta_workers.idle_thresh = 4;
+
 	fs_info->endio_write_workers.idle_thresh = 64;
 	fs_info->endio_meta_write_workers.idle_thresh = 64;
 
@@ -1740,13 +1797,13 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 	fs_info->system_alloc_profile = fs_info->metadata_alloc_profile;
 	fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root,
 					       "btrfs-cleaner");
-	if (!fs_info->cleaner_kthread)
+	if (IS_ERR(fs_info->cleaner_kthread))
 		goto fail_csum_root;
 
 	fs_info->transaction_kthread = kthread_run(transaction_kthread,
 						   tree_root,
 						   "btrfs-transaction");
-	if (!fs_info->transaction_kthread)
+	if (IS_ERR(fs_info->transaction_kthread))
 		goto fail_cleaner;
 
 	if (btrfs_super_log_root(disk_super) != 0) {
@@ -1828,13 +1885,14 @@ fail_sb_buffer:
 fail_iput:
 	invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
 	iput(fs_info->btree_inode);
-fail:
+
 	btrfs_close_devices(fs_info->fs_devices);
 	btrfs_mapping_tree_free(&fs_info->mapping_tree);
+	bdi_destroy(&fs_info->bdi);
 
+fail:
 	kfree(extent_root);
 	kfree(tree_root);
-	bdi_destroy(&fs_info->bdi);
 	kfree(fs_info);
 	kfree(chunk_root);
 	kfree(dev_root);
@@ -1995,7 +2053,6 @@ static int write_dev_supers(struct btrfs_device *device,
 
 int write_all_supers(struct btrfs_root *root, int max_mirrors)
 {
-	struct list_head *cur;
 	struct list_head *head = &root->fs_info->fs_devices->devices;
 	struct btrfs_device *dev;
 	struct btrfs_super_block *sb;
@@ -2011,8 +2068,7 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors)
 
 	sb = &root->fs_info->super_for_commit;
 	dev_item = &sb->dev_item;
-	list_for_each(cur, head) {
-		dev = list_entry(cur, struct btrfs_device, dev_list);
+	list_for_each_entry(dev, head, dev_list) {
 		if (!dev->bdev) {
 			total_errors++;
 			continue;
@@ -2045,8 +2101,7 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors)
 	}
 
 	total_errors = 0;
-	list_for_each(cur, head) {
-		dev = list_entry(cur, struct btrfs_device, dev_list);
+	list_for_each_entry(dev, head, dev_list) {
 		if (!dev->bdev)
 			continue;
 		if (!dev->in_fs_metadata || !dev->writeable)
@@ -2260,6 +2315,8 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
 	u64 transid = btrfs_header_generation(buf);
 	struct inode *btree_inode = root->fs_info->btree_inode;
 
+	btrfs_set_lock_blocking(buf);
+
 	WARN_ON(!btrfs_tree_locked(buf));
 	if (transid != root->fs_info->generation) {
 		printk(KERN_CRIT "btrfs transid mismatch buffer %llu, "
@@ -2302,14 +2359,13 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid)
 	int ret;
 	ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid);
 	if (ret == 0)
-		buf->flags |= EXTENT_UPTODATE;
+		set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags);
 	return ret;
 }
 
 int btree_lock_page_hook(struct page *page)
 {
 	struct inode *inode = page->mapping->host;
-	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
 	struct extent_buffer *eb;
 	unsigned long len;
@@ -2324,9 +2380,7 @@ int btree_lock_page_hook(struct page *page)
 		goto out;
 
 	btrfs_tree_lock(eb);
-	spin_lock(&root->fs_info->hash_lock);
 	btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);
-	spin_unlock(&root->fs_info->hash_lock);
 	btrfs_tree_unlock(eb);
 	free_extent_buffer(eb);
 out:
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index c0ff404c31b7..494a56eb2986 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -98,5 +98,7 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans,
 			     struct btrfs_fs_info *fs_info);
 int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
 			     struct btrfs_fs_info *fs_info);
+int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
+		       struct btrfs_root *root);
 int btree_lock_page_hook(struct page *page);
 #endif
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 293da650873f..7527523c2d2d 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -19,7 +19,7 @@
 #include <linux/pagemap.h>
 #include <linux/writeback.h>
 #include <linux/blkdev.h>
-#include <linux/version.h>
+#include <linux/sort.h>
 #include "compat.h"
 #include "hash.h"
 #include "crc32c.h"
@@ -30,7 +30,6 @@
 #include "volumes.h"
 #include "locking.h"
 #include "ref-cache.h"
-#include "compat.h"
 
 #define PENDING_EXTENT_INSERT 0
 #define PENDING_EXTENT_DELETE 1
@@ -326,10 +325,8 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info,
 						  u64 flags)
 {
 	struct list_head *head = &info->space_info;
-	struct list_head *cur;
 	struct btrfs_space_info *found;
-	list_for_each(cur, head) {
-		found = list_entry(cur, struct btrfs_space_info, list);
+	list_for_each_entry(found, head, list) {
 		if (found->flags == flags)
 			return found;
 	}
@@ -1525,15 +1522,55 @@ out:
 	return ret;
 }
 
-int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
-		  struct extent_buffer *orig_buf, struct extent_buffer *buf,
-		  u32 *nr_extents)
+/* when a block goes through cow, we update the reference counts of
+ * everything that block points to.  The internal pointers of the block
+ * can be in just about any order, and it is likely to have clusters of
+ * things that are close together and clusters of things that are not.
+ *
+ * To help reduce the seeks that come with updating all of these reference
+ * counts, sort them by byte number before actual updates are done.
+ *
+ * struct refsort is used to match byte number to slot in the btree block.
+ * we sort based on the byte number and then use the slot to actually
+ * find the item.
+ *
+ * struct refsort is smaller than strcut btrfs_item and smaller than
+ * struct btrfs_key_ptr.  Since we're currently limited to the page size
+ * for a btree block, there's no way for a kmalloc of refsorts for a
+ * single node to be bigger than a page.
+ */
+struct refsort {
+	u64 bytenr;
+	u32 slot;
+};
+
+/*
+ * for passing into sort()
+ */
+static int refsort_cmp(const void *a_void, const void *b_void)
+{
+	const struct refsort *a = a_void;
+	const struct refsort *b = b_void;
+
+	if (a->bytenr < b->bytenr)
+		return -1;
+	if (a->bytenr > b->bytenr)
+		return 1;
+	return 0;
+}
+
+
+noinline int btrfs_inc_ref(struct btrfs_trans_handle *trans,
+			   struct btrfs_root *root,
+			   struct extent_buffer *orig_buf,
+			   struct extent_buffer *buf, u32 *nr_extents)
 {
 	u64 bytenr;
 	u64 ref_root;
 	u64 orig_root;
 	u64 ref_generation;
 	u64 orig_generation;
+	struct refsort *sorted;
 	u32 nritems;
 	u32 nr_file_extents = 0;
 	struct btrfs_key key;
@@ -1542,6 +1579,8 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 	int level;
 	int ret = 0;
 	int faili = 0;
+	int refi = 0;
+	int slot;
 	int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *,
 			    u64, u64, u64, u64, u64, u64, u64, u64);
 
@@ -1553,6 +1592,9 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 	nritems = btrfs_header_nritems(buf);
 	level = btrfs_header_level(buf);
 
+	sorted = kmalloc(sizeof(struct refsort) * nritems, GFP_NOFS);
+	BUG_ON(!sorted);
+
 	if (root->ref_cows) {
 		process_func = __btrfs_inc_extent_ref;
 	} else {
@@ -1565,6 +1607,11 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 		process_func = __btrfs_update_extent_ref;
 	}
 
+	/*
+	 * we make two passes through the items.  In the first pass we
+	 * only record the byte number and slot.  Then we sort based on
+	 * byte number and do the actual work based on the sorted results
+	 */
 	for (i = 0; i < nritems; i++) {
 		cond_resched();
 		if (level == 0) {
@@ -1581,6 +1628,32 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 				continue;
 
 			nr_file_extents++;
+			sorted[refi].bytenr = bytenr;
+			sorted[refi].slot = i;
+			refi++;
+		} else {
+			bytenr = btrfs_node_blockptr(buf, i);
+			sorted[refi].bytenr = bytenr;
+			sorted[refi].slot = i;
+			refi++;
+		}
+	}
+	/*
+	 * if refi == 0, we didn't actually put anything into the sorted
+	 * array and we're done
+	 */
+	if (refi == 0)
+		goto out;
+
+	sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL);
+
+	for (i = 0; i < refi; i++) {
+		cond_resched();
+		slot = sorted[i].slot;
+		bytenr = sorted[i].bytenr;
+
+		if (level == 0) {
+			btrfs_item_key_to_cpu(buf, &key, slot);
 
 			ret = process_func(trans, root, bytenr,
 					   orig_buf->start, buf->start,
@@ -1589,25 +1662,25 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 					   key.objectid);
 
 			if (ret) {
-				faili = i;
+				faili = slot;
 				WARN_ON(1);
 				goto fail;
 			}
 		} else {
-			bytenr = btrfs_node_blockptr(buf, i);
 			ret = process_func(trans, root, bytenr,
 					   orig_buf->start, buf->start,
 					   orig_root, ref_root,
 					   orig_generation, ref_generation,
 					   level - 1);
 			if (ret) {
-				faili = i;
+				faili = slot;
 				WARN_ON(1);
 				goto fail;
 			}
 		}
 	}
 out:
+	kfree(sorted);
 	if (nr_extents) {
 		if (level == 0)
 			*nr_extents = nr_file_extents;
@@ -1616,6 +1689,7 @@ out:
 	}
 	return 0;
 fail:
+	kfree(sorted);
 	WARN_ON(1);
 	return ret;
 }
@@ -2159,7 +2233,8 @@ again:
 		ret = find_first_extent_bit(&info->extent_ins, search, &start,
 					    &end, EXTENT_WRITEBACK);
 		if (ret) {
-			if (skipped && all && !num_inserts) {
+			if (skipped && all && !num_inserts &&
+			    list_empty(&update_list)) {
 				skipped = 0;
 				search = 0;
 				continue;
@@ -2547,6 +2622,7 @@ again:
 		if (ret) {
 			if (all && skipped && !nr) {
 				search = 0;
+				skipped = 0;
 				continue;
 			}
 			mutex_unlock(&info->extent_ins_mutex);
@@ -2700,13 +2776,9 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
 	/* if metadata always pin */
 	if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID) {
 		if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) {
-			struct btrfs_block_group_cache *cache;
-
-			/* btrfs_free_reserved_extent */
-			cache = btrfs_lookup_block_group(root->fs_info, bytenr);
-			BUG_ON(!cache);
-			btrfs_add_free_space(cache, bytenr, num_bytes);
-			put_block_group(cache);
+			mutex_lock(&root->fs_info->pinned_mutex);
+			btrfs_update_pinned_extents(root, bytenr, num_bytes, 1);
+			mutex_unlock(&root->fs_info->pinned_mutex);
 			update_reserved_extents(root, bytenr, num_bytes, 0);
 			return 0;
 		}
@@ -3014,7 +3086,6 @@ loop_check:
 static void dump_space_info(struct btrfs_space_info *info, u64 bytes)
 {
 	struct btrfs_block_group_cache *cache;
-	struct list_head *l;
 
 	printk(KERN_INFO "space_info has %llu free, is %sfull\n",
 	       (unsigned long long)(info->total_bytes - info->bytes_used -
@@ -3022,8 +3093,7 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes)
 	       (info->full) ? "" : "not ");
 
 	down_read(&info->groups_sem);
-	list_for_each(l, &info->block_groups) {
-		cache = list_entry(l, struct btrfs_block_group_cache, list);
+	list_for_each_entry(cache, &info->block_groups, list) {
 		spin_lock(&cache->lock);
 		printk(KERN_INFO "block group %llu has %llu bytes, %llu used "
 		       "%llu pinned %llu reserved\n",
@@ -3342,7 +3412,10 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans,
 	btrfs_set_header_generation(buf, trans->transid);
 	btrfs_tree_lock(buf);
 	clean_tree_block(trans, root, buf);
+
+	btrfs_set_lock_blocking(buf);
 	btrfs_set_buffer_uptodate(buf);
+
 	if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) {
 		set_extent_dirty(&root->dirty_log_pages, buf->start,
 			 buf->start + buf->len - 1, GFP_NOFS);
@@ -3351,6 +3424,7 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans,
 			 buf->start + buf->len - 1, GFP_NOFS);
 	}
 	trans->blocks_used++;
+	/* this returns a buffer locked for blocking */
 	return buf;
 }
 
@@ -3388,36 +3462,73 @@ int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans,
 {
 	u64 leaf_owner;
 	u64 leaf_generation;
+	struct refsort *sorted;
 	struct btrfs_key key;
 	struct btrfs_file_extent_item *fi;
 	int i;
 	int nritems;
 	int ret;
+	int refi = 0;
+	int slot;
 
 	BUG_ON(!btrfs_is_leaf(leaf));
 	nritems = btrfs_header_nritems(leaf);
 	leaf_owner = btrfs_header_owner(leaf);
 	leaf_generation = btrfs_header_generation(leaf);
 
+	sorted = kmalloc(sizeof(*sorted) * nritems, GFP_NOFS);
+	/* we do this loop twice.  The first time we build a list
+	 * of the extents we have a reference on, then we sort the list
+	 * by bytenr.  The second time around we actually do the
+	 * extent freeing.
+	 */
 	for (i = 0; i < nritems; i++) {
 		u64 disk_bytenr;
 		cond_resched();
 
 		btrfs_item_key_to_cpu(leaf, &key, i);
+
+		/* only extents have references, skip everything else */
 		if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY)
 			continue;
+
 		fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item);
+
+		/* inline extents live in the btree, they don't have refs */
 		if (btrfs_file_extent_type(leaf, fi) ==
 		    BTRFS_FILE_EXTENT_INLINE)
 			continue;
-		/*
-		 * FIXME make sure to insert a trans record that
-		 * repeats the snapshot del on crash
-		 */
+
 		disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
+
+		/* holes don't have refs */
 		if (disk_bytenr == 0)
 			continue;
 
+		sorted[refi].bytenr = disk_bytenr;
+		sorted[refi].slot = i;
+		refi++;
+	}
+
+	if (refi == 0)
+		goto out;
+
+	sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL);
+
+	for (i = 0; i < refi; i++) {
+		u64 disk_bytenr;
+
+		disk_bytenr = sorted[i].bytenr;
+		slot = sorted[i].slot;
+
+		cond_resched();
+
+		btrfs_item_key_to_cpu(leaf, &key, slot);
+		if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY)
+			continue;
+
+		fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
+
 		ret = __btrfs_free_extent(trans, root, disk_bytenr,
 				btrfs_file_extent_disk_num_bytes(leaf, fi),
 				leaf->start, leaf_owner, leaf_generation,
@@ -3428,6 +3539,8 @@ int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans,
 		wake_up(&root->fs_info->transaction_throttle);
 		cond_resched();
 	}
+out:
+	kfree(sorted);
 	return 0;
 }
 
@@ -3437,9 +3550,25 @@ static noinline int cache_drop_leaf_ref(struct btrfs_trans_handle *trans,
 {
 	int i;
 	int ret;
-	struct btrfs_extent_info *info = ref->extents;
+	struct btrfs_extent_info *info;
+	struct refsort *sorted;
+
+	if (ref->nritems == 0)
+		return 0;
 
+	sorted = kmalloc(sizeof(*sorted) * ref->nritems, GFP_NOFS);
 	for (i = 0; i < ref->nritems; i++) {
+		sorted[i].bytenr = ref->extents[i].bytenr;
+		sorted[i].slot = i;
+	}
+	sort(sorted, ref->nritems, sizeof(struct refsort), refsort_cmp, NULL);
+
+	/*
+	 * the items in the ref were sorted when the ref was inserted
+	 * into the ref cache, so this is already in order
+	 */
+	for (i = 0; i < ref->nritems; i++) {
+		info = ref->extents + sorted[i].slot;
 		ret = __btrfs_free_extent(trans, root, info->bytenr,
 					  info->num_bytes, ref->bytenr,
 					  ref->owner, ref->generation,
@@ -3453,6 +3582,7 @@ static noinline int cache_drop_leaf_ref(struct btrfs_trans_handle *trans,
 		info++;
 	}
 
+	kfree(sorted);
 	return 0;
 }
 
@@ -3497,6 +3627,152 @@ static int drop_snap_lookup_refcount(struct btrfs_root *root, u64 start,
 }
 
 /*
+ * this is used while deleting old snapshots, and it drops the refs
+ * on a whole subtree starting from a level 1 node.
+ *
+ * The idea is to sort all the leaf pointers, and then drop the
+ * ref on all the leaves in order.  Most of the time the leaves
+ * will have ref cache entries, so no leaf IOs will be required to
+ * find the extents they have references on.
+ *
+ * For each leaf, any references it has are also dropped in order
+ *
+ * This ends up dropping the references in something close to optimal
+ * order for reading and modifying the extent allocation tree.
+ */
+static noinline int drop_level_one_refs(struct btrfs_trans_handle *trans,
+					struct btrfs_root *root,
+					struct btrfs_path *path)
+{
+	u64 bytenr;
+	u64 root_owner;
+	u64 root_gen;
+	struct extent_buffer *eb = path->nodes[1];
+	struct extent_buffer *leaf;
+	struct btrfs_leaf_ref *ref;
+	struct refsort *sorted = NULL;
+	int nritems = btrfs_header_nritems(eb);
+	int ret;
+	int i;
+	int refi = 0;
+	int slot = path->slots[1];
+	u32 blocksize = btrfs_level_size(root, 0);
+	u32 refs;
+
+	if (nritems == 0)
+		goto out;
+
+	root_owner = btrfs_header_owner(eb);
+	root_gen = btrfs_header_generation(eb);
+	sorted = kmalloc(sizeof(*sorted) * nritems, GFP_NOFS);
+
+	/*
+	 * step one, sort all the leaf pointers so we don't scribble
+	 * randomly into the extent allocation tree
+	 */
+	for (i = slot; i < nritems; i++) {
+		sorted[refi].bytenr = btrfs_node_blockptr(eb, i);
+		sorted[refi].slot = i;
+		refi++;
+	}
+
+	/*
+	 * nritems won't be zero, but if we're picking up drop_snapshot
+	 * after a crash, slot might be > 0, so double check things
+	 * just in case.
+	 */
+	if (refi == 0)
+		goto out;
+
+	sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL);
+
+	/*
+	 * the first loop frees everything the leaves point to
+	 */
+	for (i = 0; i < refi; i++) {
+		u64 ptr_gen;
+
+		bytenr = sorted[i].bytenr;
+
+		/*
+		 * check the reference count on this leaf.  If it is > 1
+		 * we just decrement it below and don't update any
+		 * of the refs the leaf points to.
+		 */
+		ret = drop_snap_lookup_refcount(root, bytenr, blocksize, &refs);
+		BUG_ON(ret);
+		if (refs != 1)
+			continue;
+
+		ptr_gen = btrfs_node_ptr_generation(eb, sorted[i].slot);
+
+		/*
+		 * the leaf only had one reference, which means the
+		 * only thing pointing to this leaf is the snapshot
+		 * we're deleting.  It isn't possible for the reference
+		 * count to increase again later
+		 *
+		 * The reference cache is checked for the leaf,
+		 * and if found we'll be able to drop any refs held by
+		 * the leaf without needing to read it in.
+		 */
+		ref = btrfs_lookup_leaf_ref(root, bytenr);
+		if (ref && ref->generation != ptr_gen) {
+			btrfs_free_leaf_ref(root, ref);
+			ref = NULL;
+		}
+		if (ref) {
+			ret = cache_drop_leaf_ref(trans, root, ref);
+			BUG_ON(ret);
+			btrfs_remove_leaf_ref(root, ref);
+			btrfs_free_leaf_ref(root, ref);
+		} else {
+			/*
+			 * the leaf wasn't in the reference cache, so
+			 * we have to read it.
+			 */
+			leaf = read_tree_block(root, bytenr, blocksize,
+					       ptr_gen);
+			ret = btrfs_drop_leaf_ref(trans, root, leaf);
+			BUG_ON(ret);
+			free_extent_buffer(leaf);
+		}
+		atomic_inc(&root->fs_info->throttle_gen);
+		wake_up(&root->fs_info->transaction_throttle);
+		cond_resched();
+	}
+
+	/*
+	 * run through the loop again to free the refs on the leaves.
+	 * This is faster than doing it in the loop above because
+	 * the leaves are likely to be clustered together.  We end up
+	 * working in nice chunks on the extent allocation tree.
+	 */
+	for (i = 0; i < refi; i++) {
+		bytenr = sorted[i].bytenr;
+		ret = __btrfs_free_extent(trans, root, bytenr,
+					blocksize, eb->start,
+					root_owner, root_gen, 0, 1);
+		BUG_ON(ret);
+
+		atomic_inc(&root->fs_info->throttle_gen);
+		wake_up(&root->fs_info->transaction_throttle);
+		cond_resched();
+	}
+out:
+	kfree(sorted);
+
+	/*
+	 * update the path to show we've processed the entire level 1
+	 * node.  This will get saved into the root's drop_snapshot_progress
+	 * field so these drops are not repeated again if this transaction
+	 * commits.
+	 */
+	path->slots[1] = nritems;
+	return 0;
+}
+
+/*
  * helper function for drop_snapshot, this walks down the tree dropping ref
  * counts as it goes.
  */
@@ -3511,7 +3787,6 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans,
 	struct extent_buffer *next;
 	struct extent_buffer *cur;
 	struct extent_buffer *parent;
-	struct btrfs_leaf_ref *ref;
 	u32 blocksize;
 	int ret;
 	u32 refs;
@@ -3538,17 +3813,46 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans,
 		if (path->slots[*level] >=
 		    btrfs_header_nritems(cur))
 			break;
+
+		/* the new code goes down to level 1 and does all the
+		 * leaves pointed to that node in bulk.  So, this check
+		 * for level 0 will always be false.
+		 *
+		 * But, the disk format allows the drop_snapshot_progress
+		 * field in the root to leave things in a state where
+		 * a leaf will need cleaning up here.  If someone crashes
+		 * with the old code and then boots with the new code,
+		 * we might find a leaf here.
+		 */
 		if (*level == 0) {
 			ret = btrfs_drop_leaf_ref(trans, root, cur);
 			BUG_ON(ret);
 			break;
 		}
+
+		/*
+		 * once we get to level one, process the whole node
+		 * at once, including everything below it.
+		 */
+		if (*level == 1) {
+			ret = drop_level_one_refs(trans, root, path);
+			BUG_ON(ret);
+			break;
+		}
+
 		bytenr = btrfs_node_blockptr(cur, path->slots[*level]);
 		ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]);
 		blocksize = btrfs_level_size(root, *level - 1);
 
 		ret = drop_snap_lookup_refcount(root, bytenr, blocksize, &refs);
 		BUG_ON(ret);
+
+		/*
+		 * if there is more than one reference, we don't need
+		 * to read that node to drop any references it has.  We
+		 * just drop the ref we hold on that node and move on to the
+		 * next slot in this level.
+		 */
 		if (refs != 1) {
 			parent = path->nodes[*level];
 			root_owner = btrfs_header_owner(parent);
@@ -3567,46 +3871,12 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans,
 
 			continue;
 		}
+
 		/*
-		 * at this point, we have a single ref, and since the
-		 * only place referencing this extent is a dead root
-		 * the reference count should never go higher.
-		 * So, we don't need to check it again
+		 * we need to keep freeing things in the next level down.
+		 * read the block and loop around to process it
 		 */
-		if (*level == 1) {
-			ref = btrfs_lookup_leaf_ref(root, bytenr);
-			if (ref && ref->generation != ptr_gen) {
-				btrfs_free_leaf_ref(root, ref);
-				ref = NULL;
-			}
-			if (ref) {
-				ret = cache_drop_leaf_ref(trans, root, ref);
-				BUG_ON(ret);
-				btrfs_remove_leaf_ref(root, ref);
-				btrfs_free_leaf_ref(root, ref);
-				*level = 0;
-				break;
-			}
-		}
-		next = btrfs_find_tree_block(root, bytenr, blocksize);
-		if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) {
-			free_extent_buffer(next);
-
-			next = read_tree_block(root, bytenr, blocksize,
-					       ptr_gen);
-			cond_resched();
-#if 0
-			/*
-			 * this is a debugging check and can go away
-			 * the ref should never go all the way down to 1
-			 * at this point
-			 */
-			ret = lookup_extent_ref(NULL, root, bytenr, blocksize,
-						&refs);
-			BUG_ON(ret);
-			WARN_ON(refs != 1);
-#endif
-		}
+		next = read_tree_block(root, bytenr, blocksize, ptr_gen);
 		WARN_ON(*level <= 0);
 		if (path->nodes[*level-1])
 			free_extent_buffer(path->nodes[*level-1]);
@@ -3631,11 +3901,16 @@ out:
 	root_owner = btrfs_header_owner(parent);
 	root_gen = btrfs_header_generation(parent);
 
+	/*
+	 * cleanup and free the reference on the last node
+	 * we processed
+	 */
 	ret = __btrfs_free_extent(trans, root, bytenr, blocksize,
 				  parent->start, root_owner, root_gen,
 				  *level, 1);
 	free_extent_buffer(path->nodes[*level]);
 	path->nodes[*level] = NULL;
+
 	*level += 1;
 	BUG_ON(ret);
 
@@ -3687,6 +3962,7 @@ static noinline int walk_down_subtree(struct btrfs_trans_handle *trans,
 
 		next = read_tree_block(root, bytenr, blocksize, ptr_gen);
 		btrfs_tree_lock(next);
+		btrfs_set_lock_blocking(next);
 
 		ret = btrfs_lookup_extent_ref(trans, root, bytenr, blocksize,
 					      &refs);
@@ -3754,6 +4030,13 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans,
 		if (slot < btrfs_header_nritems(path->nodes[i]) - 1) {
 			struct extent_buffer *node;
 			struct btrfs_disk_key disk_key;
+
+			/*
+			 * there is more work to do in this level.
+			 * Update the drop_progress marker to reflect
+			 * the work we've done so far, and then bump
+			 * the slot number
+			 */
 			node = path->nodes[i];
 			path->slots[i]++;
 			*level = i;
@@ -3765,6 +4048,11 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans,
 			return 0;
 		} else {
 			struct extent_buffer *parent;
+
+			/*
+			 * this whole node is done, free our reference
+			 * on it and go up one level
+			 */
 			if (path->nodes[*level] == root->node)
 				parent = path->nodes[*level];
 			else
@@ -4444,7 +4732,7 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans,
 	u64 lock_end = 0;
 	u64 num_bytes;
 	u64 ext_offset;
-	u64 first_pos;
+	u64 search_end = (u64)-1;
 	u32 nritems;
 	int nr_scaned = 0;
 	int extent_locked = 0;
@@ -4452,7 +4740,6 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans,
 	int ret;
 
 	memcpy(&key, leaf_key, sizeof(key));
-	first_pos = INT_LIMIT(loff_t) - extent_key->offset;
 	if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) {
 		if (key.objectid < ref_path->owner_objectid ||
 		    (key.objectid == ref_path->owner_objectid &&
@@ -4501,7 +4788,7 @@ next:
 			if ((key.objectid > ref_path->owner_objectid) ||
 			    (key.objectid == ref_path->owner_objectid &&
 			     key.type > BTRFS_EXTENT_DATA_KEY) ||
-			    (key.offset >= first_pos + extent_key->offset))
+			    key.offset >= search_end)
 				break;
 		}
 
@@ -4534,8 +4821,10 @@ next:
 		num_bytes = btrfs_file_extent_num_bytes(leaf, fi);
 		ext_offset = btrfs_file_extent_offset(leaf, fi);
 
-		if (first_pos > key.offset - ext_offset)
-			first_pos = key.offset - ext_offset;
+		if (search_end == (u64)-1) {
+			search_end = key.offset - ext_offset +
+				btrfs_file_extent_ram_bytes(leaf, fi);
+		}
 
 		if (!extent_locked) {
 			lock_start = key.offset;
@@ -4724,7 +5013,7 @@ next:
 		}
 skip:
 		if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS &&
-		    key.offset >= first_pos + extent_key->offset)
+		    key.offset >= search_end)
 			break;
 
 		cond_resched();
@@ -4778,6 +5067,7 @@ int btrfs_reloc_tree_cache_ref(struct btrfs_trans_handle *trans,
 		ref->bytenr = buf->start;
 		ref->owner = btrfs_header_owner(buf);
 		ref->generation = btrfs_header_generation(buf);
+
 		ret = btrfs_add_leaf_ref(root, ref, 0);
 		WARN_ON(ret);
 		btrfs_free_leaf_ref(root, ref);
@@ -5957,9 +6247,11 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
 	path = btrfs_alloc_path();
 	BUG_ON(!path);
 
-	btrfs_remove_free_space_cache(block_group);
+	spin_lock(&root->fs_info->block_group_cache_lock);
 	rb_erase(&block_group->cache_node,
 		 &root->fs_info->block_group_cache_tree);
+	spin_unlock(&root->fs_info->block_group_cache_lock);
+	btrfs_remove_free_space_cache(block_group);
 	down_write(&block_group->space_info->groups_sem);
 	list_del(&block_group->list);
 	up_write(&block_group->space_info->groups_sem);
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index e086d407f1fa..37d43b516b79 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -9,7 +9,6 @@
 #include <linux/spinlock.h>
 #include <linux/blkdev.h>
 #include <linux/swap.h>
-#include <linux/version.h>
 #include <linux/writeback.h>
 #include <linux/pagevec.h>
 #include "extent_io.h"
@@ -31,7 +30,7 @@ static LIST_HEAD(buffers);
 static LIST_HEAD(states);
 
 #define LEAK_DEBUG 0
-#ifdef LEAK_DEBUG
+#if LEAK_DEBUG
 static DEFINE_SPINLOCK(leak_lock);
 #endif
 
@@ -120,7 +119,7 @@ void extent_io_tree_init(struct extent_io_tree *tree,
 static struct extent_state *alloc_extent_state(gfp_t mask)
 {
 	struct extent_state *state;
-#ifdef LEAK_DEBUG
+#if LEAK_DEBUG
 	unsigned long flags;
 #endif
 
@@ -130,7 +129,7 @@ static struct extent_state *alloc_extent_state(gfp_t mask)
 	state->state = 0;
 	state->private = 0;
 	state->tree = NULL;
-#ifdef LEAK_DEBUG
+#if LEAK_DEBUG
 	spin_lock_irqsave(&leak_lock, flags);
 	list_add(&state->leak_list, &states);
 	spin_unlock_irqrestore(&leak_lock, flags);
@@ -145,11 +144,11 @@ static void free_extent_state(struct extent_state *state)
 	if (!state)
 		return;
 	if (atomic_dec_and_test(&state->refs)) {
-#ifdef LEAK_DEBUG
+#if LEAK_DEBUG
 		unsigned long flags;
 #endif
 		WARN_ON(state->tree);
-#ifdef LEAK_DEBUG
+#if LEAK_DEBUG
 		spin_lock_irqsave(&leak_lock, flags);
 		list_del(&state->leak_list);
 		spin_unlock_irqrestore(&leak_lock, flags);
@@ -2378,11 +2377,6 @@ static int extent_write_cache_pages(struct extent_io_tree *tree,
 	int scanned = 0;
 	int range_whole = 0;
 
-	if (wbc->nonblocking && bdi_write_congested(bdi)) {
-		wbc->encountered_congestion = 1;
-		return 0;
-	}
-
 	pagevec_init(&pvec, 0);
 	if (wbc->range_cyclic) {
 		index = mapping->writeback_index; /* Start from prev offset */
@@ -2855,6 +2849,98 @@ out:
 	return sector;
 }
 
+int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+		__u64 start, __u64 len, get_extent_t *get_extent)
+{
+	int ret;
+	u64 off = start;
+	u64 max = start + len;
+	u32 flags = 0;
+	u64 disko = 0;
+	struct extent_map *em = NULL;
+	int end = 0;
+	u64 em_start = 0, em_len = 0;
+	unsigned long emflags;
+	ret = 0;
+
+	if (len == 0)
+		return -EINVAL;
+
+	lock_extent(&BTRFS_I(inode)->io_tree, start, start + len,
+		GFP_NOFS);
+	em = get_extent(inode, NULL, 0, off, max - off, 0);
+	if (!em)
+		goto out;
+	if (IS_ERR(em)) {
+		ret = PTR_ERR(em);
+		goto out;
+	}
+	while (!end) {
+		off = em->start + em->len;
+		if (off >= max)
+			end = 1;
+
+		em_start = em->start;
+		em_len = em->len;
+
+		disko = 0;
+		flags = 0;
+
+		switch (em->block_start) {
+		case EXTENT_MAP_LAST_BYTE:
+			end = 1;
+			flags |= FIEMAP_EXTENT_LAST;
+			break;
+		case EXTENT_MAP_HOLE:
+			flags |= FIEMAP_EXTENT_UNWRITTEN;
+			break;
+		case EXTENT_MAP_INLINE:
+			flags |= (FIEMAP_EXTENT_DATA_INLINE |
+				  FIEMAP_EXTENT_NOT_ALIGNED);
+			break;
+		case EXTENT_MAP_DELALLOC:
+			flags |= (FIEMAP_EXTENT_DELALLOC |
+				  FIEMAP_EXTENT_UNKNOWN);
+			break;
+		default:
+			disko = em->block_start;
+			break;
+		}
+		if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags))
+			flags |= FIEMAP_EXTENT_ENCODED;
+
+		emflags = em->flags;
+		free_extent_map(em);
+		em = NULL;
+
+		if (!end) {
+			em = get_extent(inode, NULL, 0, off, max - off, 0);
+			if (!em)
+				goto out;
+			if (IS_ERR(em)) {
+				ret = PTR_ERR(em);
+				goto out;
+			}
+			emflags = em->flags;
+		}
+		if (test_bit(EXTENT_FLAG_VACANCY, &emflags)) {
+			flags |= FIEMAP_EXTENT_LAST;
+			end = 1;
+		}
+
+		ret = fiemap_fill_next_extent(fieinfo, em_start, disko,
+					em_len, flags);
+		if (ret)
+			goto out_free;
+	}
+out_free:
+	free_extent_map(em);
+out:
+	unlock_extent(&BTRFS_I(inode)->io_tree, start, start + len,
+			GFP_NOFS);
+	return ret;
+}
+
 static inline struct page *extent_buffer_page(struct extent_buffer *eb,
 					      unsigned long i)
 {
@@ -2892,15 +2978,17 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree,
 						   gfp_t mask)
 {
 	struct extent_buffer *eb = NULL;
-#ifdef LEAK_DEBUG
+#if LEAK_DEBUG
 	unsigned long flags;
 #endif
 
 	eb = kmem_cache_zalloc(extent_buffer_cache, mask);
 	eb->start = start;
 	eb->len = len;
-	mutex_init(&eb->mutex);
-#ifdef LEAK_DEBUG
+	spin_lock_init(&eb->lock);
+	init_waitqueue_head(&eb->lock_wq);
+
+#if LEAK_DEBUG
 	spin_lock_irqsave(&leak_lock, flags);
 	list_add(&eb->leak_list, &buffers);
 	spin_unlock_irqrestore(&leak_lock, flags);
@@ -2912,7 +3000,7 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree,
 
 static void __free_extent_buffer(struct extent_buffer *eb)
 {
-#ifdef LEAK_DEBUG
+#if LEAK_DEBUG
 	unsigned long flags;
 	spin_lock_irqsave(&leak_lock, flags);
 	list_del(&eb->leak_list);
@@ -2980,8 +3068,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
 		unlock_page(p);
 	}
 	if (uptodate)
-		eb->flags |= EXTENT_UPTODATE;
-	eb->flags |= EXTENT_BUFFER_FILLED;
+		set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
 
 	spin_lock(&tree->buffer_lock);
 	exists = buffer_tree_insert(tree, start, &eb->rb_node);
@@ -3135,7 +3222,7 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
 	unsigned long num_pages;
 
 	num_pages = num_extent_pages(eb->start, eb->len);
-	eb->flags &= ~EXTENT_UPTODATE;
+	clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
 
 	clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
 			      GFP_NOFS);
@@ -3206,7 +3293,7 @@ int extent_buffer_uptodate(struct extent_io_tree *tree,
 	struct page *page;
 	int pg_uptodate = 1;
 
-	if (eb->flags & EXTENT_UPTODATE)
+	if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))
 		return 1;
 
 	ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1,
@@ -3242,7 +3329,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
 	struct bio *bio = NULL;
 	unsigned long bio_flags = 0;
 
-	if (eb->flags & EXTENT_UPTODATE)
+	if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))
 		return 0;
 
 	if (test_range_bit(tree, eb->start, eb->start + eb->len - 1,
@@ -3273,7 +3360,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
 	}
 	if (all_uptodate) {
 		if (start_i == 0)
-			eb->flags |= EXTENT_UPTODATE;
+			set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
 		goto unlock_exit;
 	}
 
@@ -3309,7 +3396,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
 	}
 
 	if (!ret)
-		eb->flags |= EXTENT_UPTODATE;
+		set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
 	return ret;
 
 unlock_exit:
@@ -3406,7 +3493,6 @@ int map_extent_buffer(struct extent_buffer *eb, unsigned long start,
 		unmap_extent_buffer(eb, eb->map_token, km);
 		eb->map_token = NULL;
 		save = 1;
-		WARN_ON(!mutex_is_locked(&eb->mutex));
 	}
 	err = map_private_extent_buffer(eb, start, min_len, token, map,
 				       map_start, map_len, km);
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index c5b483a79137..1f9df88afbf6 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -22,6 +22,10 @@
 /* flags for bio submission */
 #define EXTENT_BIO_COMPRESSED 1
 
+/* these are bit numbers for test/set bit */
+#define EXTENT_BUFFER_UPTODATE 0
+#define EXTENT_BUFFER_BLOCKING 1
+
 /*
  * page->private values.  Every page that is controlled by the extent
  * map has page->private set to one.
@@ -95,11 +99,19 @@ struct extent_buffer {
 	unsigned long map_start;
 	unsigned long map_len;
 	struct page *first_page;
+	unsigned long bflags;
 	atomic_t refs;
-	int flags;
 	struct list_head leak_list;
 	struct rb_node rb_node;
-	struct mutex mutex;
+
+	/* the spinlock is used to protect most operations */
+	spinlock_t lock;
+
+	/*
+	 * when we keep the lock held while blocking, waiters go onto
+	 * the wq
+	 */
+	wait_queue_head_t lock_wq;
 };
 
 struct extent_map_tree;
@@ -193,6 +205,8 @@ int extent_commit_write(struct extent_io_tree *tree,
 			unsigned from, unsigned to);
 sector_t extent_bmap(struct address_space *mapping, sector_t iblock,
 		get_extent_t *get_extent);
+int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+		__u64 start, __u64 len, get_extent_t *get_extent);
 int set_range_dirty(struct extent_io_tree *tree, u64 start, u64 end);
 int set_state_private(struct extent_io_tree *tree, u64 start, u64 private);
 int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private);
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 4a83e33ada32..50da69da20ce 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -3,7 +3,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <linux/version.h>
 #include <linux/hardirq.h>
 #include "extent_map.h"
 
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 90268334145e..3e8023efaff7 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -29,7 +29,6 @@
 #include <linux/writeback.h>
 #include <linux/statfs.h>
 #include <linux/compat.h>
-#include <linux/version.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -1215,10 +1214,10 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
 	}
 	mutex_unlock(&root->fs_info->trans_mutex);
 
-	root->fs_info->tree_log_batch++;
+	root->log_batch++;
 	filemap_fdatawrite(inode->i_mapping);
 	btrfs_wait_ordered_range(inode, 0, (u64)-1);
-	root->fs_info->tree_log_batch++;
+	root->log_batch++;
 
 	/*
 	 * ok we haven't committed the transaction yet, lets do a commit
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 8adfe059ab41..8f0706210a47 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -34,7 +34,6 @@
 #include <linux/statfs.h>
 #include <linux/compat.h>
 #include <linux/bit_spinlock.h>
-#include <linux/version.h>
 #include <linux/xattr.h>
 #include <linux/posix_acl.h>
 #include <linux/falloc.h>
@@ -51,6 +50,7 @@
 #include "tree-log.h"
 #include "ref-cache.h"
 #include "compression.h"
+#include "locking.h"
 
 struct btrfs_iget_args {
 	u64 ino;
@@ -91,6 +91,16 @@ static noinline int cow_file_range(struct inode *inode,
 				   u64 start, u64 end, int *page_started,
 				   unsigned long *nr_written, int unlock);
 
+static int btrfs_init_inode_security(struct inode *inode,  struct inode *dir)
+{
+	int err;
+
+	err = btrfs_init_acl(inode, dir);
+	if (!err)
+		err = btrfs_xattr_security_init(inode, dir);
+	return err;
+}
+
 /*
  * a very lame attempt at stopping writes when the FS is 85% full.  There
  * are countless ways this is incorrect, but it is better than nothing.
@@ -350,6 +360,19 @@ again:
 	nr_pages = (end >> PAGE_CACHE_SHIFT) - (start >> PAGE_CACHE_SHIFT) + 1;
 	nr_pages = min(nr_pages, (128 * 1024UL) / PAGE_CACHE_SIZE);
 
+	/*
+	 * we don't want to send crud past the end of i_size through
+	 * compression, that's just a waste of CPU time.  So, if the
+	 * end of the file is before the start of our current
+	 * requested range of bytes, we bail out to the uncompressed
+	 * cleanup code that can deal with all of this.
+	 *
+	 * It isn't really the fastest way to fix things, but this is a
+	 * very uncommon corner.
+	 */
+	if (actual_end <= start)
+		goto cleanup_and_bail_uncompressed;
+
 	total_compressed = actual_end - start;
 
 	/* we want to make sure that amount of ram required to uncompress
@@ -494,6 +517,7 @@ again:
 			goto again;
 		}
 	} else {
+cleanup_and_bail_uncompressed:
 		/*
 		 * No compression, but we still need to write the pages in
 		 * the file we've been given so far.  redirty the locked
@@ -1324,12 +1348,11 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans,
 			     struct inode *inode, u64 file_offset,
 			     struct list_head *list)
 {
-	struct list_head *cur;
 	struct btrfs_ordered_sum *sum;
 
 	btrfs_set_trans_block_group(trans, inode);
-	list_for_each(cur, list) {
-		sum = list_entry(cur, struct btrfs_ordered_sum, list);
+
+	list_for_each_entry(sum, list, list) {
 		btrfs_csum_file_blocks(trans,
 		       BTRFS_I(inode)->root->fs_info->csum_root, sum);
 	}
@@ -2013,6 +2036,7 @@ void btrfs_read_locked_inode(struct inode *inode)
 	BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
 
 	alloc_group_block = btrfs_inode_block_group(leaf, inode_item);
+
 	BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0,
 						alloc_group_block, 0);
 	btrfs_free_path(path);
@@ -2039,6 +2063,7 @@ void btrfs_read_locked_inode(struct inode *inode)
 		inode->i_mapping->backing_dev_info = &root->fs_info->bdi;
 		break;
 	default:
+		inode->i_op = &btrfs_special_inode_operations;
 		init_special_inode(inode, inode->i_mode, rdev);
 		break;
 	}
@@ -2108,6 +2133,7 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans,
 		goto failed;
 	}
 
+	btrfs_unlock_up_safe(path, 1);
 	leaf = path->nodes[0];
 	inode_item = btrfs_item_ptr(leaf, path->slots[0],
 				  struct btrfs_inode_item);
@@ -2429,6 +2455,8 @@ next_node:
 			ref->generation = leaf_gen;
 			ref->nritems = 0;
 
+			btrfs_sort_leaf_ref(ref);
+
 			ret = btrfs_add_leaf_ref(root, ref, 0);
 			WARN_ON(ret);
 			btrfs_free_leaf_ref(root, ref);
@@ -2476,7 +2504,7 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
 	struct btrfs_path *path;
 	struct btrfs_key key;
 	struct btrfs_key found_key;
-	u32 found_type;
+	u32 found_type = (u8)-1;
 	struct extent_buffer *leaf;
 	struct btrfs_file_extent_item *fi;
 	u64 extent_start = 0;
@@ -2663,6 +2691,8 @@ next:
 			if (pending_del_nr)
 				goto del_pending;
 			btrfs_release_path(root, path);
+			if (found_type == BTRFS_INODE_ITEM_KEY)
+				break;
 			goto search_again;
 		}
 
@@ -2679,6 +2709,8 @@ del_pending:
 			BUG_ON(ret);
 			pending_del_nr = 0;
 			btrfs_release_path(root, path);
+			if (found_type == BTRFS_INODE_ITEM_KEY)
+				break;
 			goto search_again;
 		}
 	}
@@ -3265,7 +3297,7 @@ skip:
 
 	/* Reached end of directory/root. Bump pos past the last item. */
 	if (key_type == BTRFS_DIR_INDEX_KEY)
-		filp->f_pos = INT_LIMIT(typeof(filp->f_pos));
+		filp->f_pos = INT_LIMIT(off_t);
 	else
 		filp->f_pos++;
 nopos:
@@ -3458,7 +3490,14 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
 		root->highest_inode = objectid;
 
 	inode->i_uid = current_fsuid();
-	inode->i_gid = current_fsgid();
+
+	if (dir && (dir->i_mode & S_ISGID)) {
+		inode->i_gid = dir->i_gid;
+		if (S_ISDIR(mode))
+			mode |= S_ISGID;
+	} else
+		inode->i_gid = current_fsgid();
+
 	inode->i_mode = mode;
 	inode->i_ino = objectid;
 	inode_set_bytes(inode, 0);
@@ -3586,7 +3625,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
 	if (IS_ERR(inode))
 		goto out_unlock;
 
-	err = btrfs_init_acl(inode, dir);
+	err = btrfs_init_inode_security(inode, dir);
 	if (err) {
 		drop_inode = 1;
 		goto out_unlock;
@@ -3649,7 +3688,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
 	if (IS_ERR(inode))
 		goto out_unlock;
 
-	err = btrfs_init_acl(inode, dir);
+	err = btrfs_init_inode_security(inode, dir);
 	if (err) {
 		drop_inode = 1;
 		goto out_unlock;
@@ -3772,7 +3811,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
 	drop_on_err = 1;
 
-	err = btrfs_init_acl(inode, dir);
+	err = btrfs_init_inode_security(inode, dir);
 	if (err)
 		goto out_fail;
 
@@ -4158,9 +4197,10 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
 	return -EINVAL;
 }
 
-static sector_t btrfs_bmap(struct address_space *mapping, sector_t iblock)
+static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+		__u64 start, __u64 len)
 {
-	return extent_bmap(mapping, iblock, btrfs_get_extent);
+	return extent_fiemap(inode, fieinfo, start, len, btrfs_get_extent);
 }
 
 int btrfs_readpage(struct file *file, struct page *page)
@@ -4733,7 +4773,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
 	if (IS_ERR(inode))
 		goto out_unlock;
 
-	err = btrfs_init_acl(inode, dir);
+	err = btrfs_init_inode_security(inode, dir);
 	if (err) {
 		drop_inode = 1;
 		goto out_unlock;
@@ -4987,13 +5027,24 @@ static struct extent_io_ops btrfs_extent_io_ops = {
 	.clear_bit_hook = btrfs_clear_bit_hook,
 };
 
+/*
+ * btrfs doesn't support the bmap operation because swapfiles
+ * use bmap to make a mapping of extents in the file.  They assume
+ * these extents won't change over the life of the file and they
+ * use the bmap result to do IO directly to the drive.
+ *
+ * the btrfs bmap call would return logical addresses that aren't
+ * suitable for IO and they also will change frequently as COW
+ * operations happen.  So, swapfile + btrfs == corruption.
+ *
+ * For now we're avoiding this by dropping bmap.
+ */
 static struct address_space_operations btrfs_aops = {
 	.readpage	= btrfs_readpage,
 	.writepage	= btrfs_writepage,
 	.writepages	= btrfs_writepages,
 	.readpages	= btrfs_readpages,
 	.sync_page	= block_sync_page,
-	.bmap		= btrfs_bmap,
 	.direct_IO	= btrfs_direct_IO,
 	.invalidatepage = btrfs_invalidatepage,
 	.releasepage	= btrfs_releasepage,
@@ -5017,6 +5068,7 @@ static struct inode_operations btrfs_file_inode_operations = {
 	.removexattr	= btrfs_removexattr,
 	.permission	= btrfs_permission,
 	.fallocate	= btrfs_fallocate,
+	.fiemap		= btrfs_fiemap,
 };
 static struct inode_operations btrfs_special_inode_operations = {
 	.getattr	= btrfs_getattr,
@@ -5032,4 +5084,8 @@ static struct inode_operations btrfs_symlink_inode_operations = {
 	.follow_link	= page_follow_link_light,
 	.put_link	= page_put_link,
 	.permission	= btrfs_permission,
+	.setxattr	= btrfs_setxattr,
+	.getxattr	= btrfs_getxattr,
+	.listxattr	= btrfs_listxattr,
+	.removexattr	= btrfs_removexattr,
 };
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index c2aa33e3feb5..988fdc8b49eb 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -38,7 +38,6 @@
 #include <linux/compat.h>
 #include <linux/bit_spinlock.h>
 #include <linux/security.h>
-#include <linux/version.h>
 #include <linux/xattr.h>
 #include <linux/vmalloc.h>
 #include "compat.h"
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c
index 39bae7761db6..68fd9ccf1805 100644
--- a/fs/btrfs/locking.c
+++ b/fs/btrfs/locking.c
@@ -26,45 +26,215 @@
 #include "locking.h"
 
 /*
- * locks the per buffer mutex in an extent buffer.  This uses adaptive locks
- * and the spin is not tuned very extensively.  The spinning does make a big
- * difference in almost every workload, but spinning for the right amount of
- * time needs some help.
- *
- * In general, we want to spin as long as the lock holder is doing btree
- * searches, and we should give up if they are in more expensive code.
+ * btrfs_header_level() isn't free, so don't call it when lockdep isn't
+ * on
  */
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+static inline void spin_nested(struct extent_buffer *eb)
+{
+	spin_lock_nested(&eb->lock, BTRFS_MAX_LEVEL - btrfs_header_level(eb));
+}
+#else
+static inline void spin_nested(struct extent_buffer *eb)
+{
+	spin_lock(&eb->lock);
+}
+#endif
 
-int btrfs_tree_lock(struct extent_buffer *eb)
+/*
+ * Setting a lock to blocking will drop the spinlock and set the
+ * flag that forces other procs who want the lock to wait.  After
+ * this you can safely schedule with the lock held.
+ */
+void btrfs_set_lock_blocking(struct extent_buffer *eb)
 {
-	int i;
+	if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) {
+		set_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags);
+		spin_unlock(&eb->lock);
+	}
+	/* exit with the spin lock released and the bit set */
+}
 
-	if (mutex_trylock(&eb->mutex))
-		return 0;
+/*
+ * clearing the blocking flag will take the spinlock again.
+ * After this you can't safely schedule
+ */
+void btrfs_clear_lock_blocking(struct extent_buffer *eb)
+{
+	if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) {
+		spin_nested(eb);
+		clear_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags);
+		smp_mb__after_clear_bit();
+	}
+	/* exit with the spin lock held */
+}
+
+/*
+ * unfortunately, many of the places that currently set a lock to blocking
+ * don't end up blocking for every long, and often they don't block
+ * at all.  For a dbench 50 run, if we don't spin one the blocking bit
+ * at all, the context switch rate can jump up to 400,000/sec or more.
+ *
+ * So, we're still stuck with this crummy spin on the blocking bit,
+ * at least until the most common causes of the short blocks
+ * can be dealt with.
+ */
+static int btrfs_spin_on_block(struct extent_buffer *eb)
+{
+	int i;
 	for (i = 0; i < 512; i++) {
 		cpu_relax();
-		if (mutex_trylock(&eb->mutex))
+		if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
+			return 1;
+		if (need_resched())
+			break;
+	}
+	return 0;
+}
+
+/*
+ * This is somewhat different from trylock.  It will take the
+ * spinlock but if it finds the lock is set to blocking, it will
+ * return without the lock held.
+ *
+ * returns 1 if it was able to take the lock and zero otherwise
+ *
+ * After this call, scheduling is not safe without first calling
+ * btrfs_set_lock_blocking()
+ */
+int btrfs_try_spin_lock(struct extent_buffer *eb)
+{
+	int i;
+
+	spin_nested(eb);
+	if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
+		return 1;
+	spin_unlock(&eb->lock);
+
+	/* spin for a bit on the BLOCKING flag */
+	for (i = 0; i < 2; i++) {
+		if (!btrfs_spin_on_block(eb))
+			break;
+
+		spin_nested(eb);
+		if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
+			return 1;
+		spin_unlock(&eb->lock);
+	}
+	return 0;
+}
+
+/*
+ * the autoremove wake function will return 0 if it tried to wake up
+ * a process that was already awake, which means that process won't
+ * count as an exclusive wakeup.  The waitq code will continue waking
+ * procs until it finds one that was actually sleeping.
+ *
+ * For btrfs, this isn't quite what we want.  We want a single proc
+ * to be notified that the lock is ready for taking.  If that proc
+ * already happen to be awake, great, it will loop around and try for
+ * the lock.
+ *
+ * So, btrfs_wake_function always returns 1, even when the proc that we
+ * tried to wake up was already awake.
+ */
+static int btrfs_wake_function(wait_queue_t *wait, unsigned mode,
+			       int sync, void *key)
+{
+	autoremove_wake_function(wait, mode, sync, key);
+	return 1;
+}
+
+/*
+ * returns with the extent buffer spinlocked.
+ *
+ * This will spin and/or wait as required to take the lock, and then
+ * return with the spinlock held.
+ *
+ * After this call, scheduling is not safe without first calling
+ * btrfs_set_lock_blocking()
+ */
+int btrfs_tree_lock(struct extent_buffer *eb)
+{
+	DEFINE_WAIT(wait);
+	wait.func = btrfs_wake_function;
+
+	while(1) {
+		spin_nested(eb);
+
+		/* nobody is blocking, exit with the spinlock held */
+		if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
 			return 0;
+
+		/*
+		 * we have the spinlock, but the real owner is blocking.
+		 * wait for them
+		 */
+		spin_unlock(&eb->lock);
+
+		/*
+		 * spin for a bit, and if the blocking flag goes away,
+		 * loop around
+		 */
+		if (btrfs_spin_on_block(eb))
+			continue;
+
+		prepare_to_wait_exclusive(&eb->lock_wq, &wait,
+					  TASK_UNINTERRUPTIBLE);
+
+		if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
+			schedule();
+
+		finish_wait(&eb->lock_wq, &wait);
 	}
-	cpu_relax();
-	mutex_lock_nested(&eb->mutex, BTRFS_MAX_LEVEL - btrfs_header_level(eb));
 	return 0;
 }
 
+/*
+ * Very quick trylock, this does not spin or schedule.  It returns
+ * 1 with the spinlock held if it was able to take the lock, or it
+ * returns zero if it was unable to take the lock.
+ *
+ * After this call, scheduling is not safe without first calling
+ * btrfs_set_lock_blocking()
+ */
 int btrfs_try_tree_lock(struct extent_buffer *eb)
 {
-	return mutex_trylock(&eb->mutex);
+	if (spin_trylock(&eb->lock)) {
+		if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) {
+			/*
+			 * we've got the spinlock, but the real owner is
+			 * blocking.  Drop the spinlock and return failure
+			 */
+			spin_unlock(&eb->lock);
+			return 0;
+		}
+		return 1;
+	}
+	/* someone else has the spinlock giveup */
+	return 0;
 }
 
 int btrfs_tree_unlock(struct extent_buffer *eb)
 {
-	mutex_unlock(&eb->mutex);
+	/*
+	 * if we were a blocking owner, we don't have the spinlock held
+	 * just clear the bit and look for waiters
+	 */
+	if (test_and_clear_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
+		smp_mb__after_clear_bit();
+	else
+		spin_unlock(&eb->lock);
+
+	if (waitqueue_active(&eb->lock_wq))
+		wake_up(&eb->lock_wq);
 	return 0;
 }
 
 int btrfs_tree_locked(struct extent_buffer *eb)
 {
-	return mutex_is_locked(&eb->mutex);
+	return test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags) ||
+			spin_is_locked(&eb->lock);
 }
 
 /*
@@ -75,12 +245,14 @@ int btrfs_path_lock_waiting(struct btrfs_path *path, int level)
 {
 	int i;
 	struct extent_buffer *eb;
+
 	for (i = level; i <= level + 1 && i < BTRFS_MAX_LEVEL; i++) {
 		eb = path->nodes[i];
 		if (!eb)
 			break;
 		smp_mb();
-		if (!list_empty(&eb->mutex.wait_list))
+		if (spin_is_contended(&eb->lock) ||
+		    waitqueue_active(&eb->lock_wq))
 			return 1;
 	}
 	return 0;
diff --git a/fs/btrfs/locking.h b/fs/btrfs/locking.h
index bc1faef12519..d92e707f5870 100644
--- a/fs/btrfs/locking.h
+++ b/fs/btrfs/locking.h
@@ -22,6 +22,12 @@
 int btrfs_tree_lock(struct extent_buffer *eb);
 int btrfs_tree_unlock(struct extent_buffer *eb);
 int btrfs_tree_locked(struct extent_buffer *eb);
+
 int btrfs_try_tree_lock(struct extent_buffer *eb);
+int btrfs_try_spin_lock(struct extent_buffer *eb);
+
 int btrfs_path_lock_waiting(struct btrfs_path *path, int level);
+
+void btrfs_set_lock_blocking(struct extent_buffer *eb);
+void btrfs_clear_lock_blocking(struct extent_buffer *eb);
 #endif
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index a20940170274..77c2411a5f0f 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -613,7 +613,6 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
 	struct btrfs_sector_sum *sector_sums;
 	struct btrfs_ordered_extent *ordered;
 	struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree;
-	struct list_head *cur;
 	unsigned long num_sectors;
 	unsigned long i;
 	u32 sectorsize = BTRFS_I(inode)->root->sectorsize;
@@ -624,8 +623,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
 		return 1;
 
 	mutex_lock(&tree->mutex);
-	list_for_each_prev(cur, &ordered->list) {
-		ordered_sum = list_entry(cur, struct btrfs_ordered_sum, list);
+	list_for_each_entry_reverse(ordered_sum, &ordered->list, list) {
 		if (disk_bytenr >= ordered_sum->bytenr) {
 			num_sectors = ordered_sum->len / sectorsize;
 			sector_sums = ordered_sum->sums;
diff --git a/fs/btrfs/ref-cache.c b/fs/btrfs/ref-cache.c
index 6f0acc4c9eab..d0cc62bccb94 100644
--- a/fs/btrfs/ref-cache.c
+++ b/fs/btrfs/ref-cache.c
@@ -17,6 +17,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/sort.h>
 #include "ctree.h"
 #include "ref-cache.h"
 #include "transaction.h"
diff --git a/fs/btrfs/ref-cache.h b/fs/btrfs/ref-cache.h
index 16f3183d7c59..bc283ad2db73 100644
--- a/fs/btrfs/ref-cache.h
+++ b/fs/btrfs/ref-cache.h
@@ -73,5 +73,4 @@ int btrfs_add_leaf_ref(struct btrfs_root *root, struct btrfs_leaf_ref *ref,
 int btrfs_remove_leaf_refs(struct btrfs_root *root, u64 max_root_gen,
 			   int shared);
 int btrfs_remove_leaf_ref(struct btrfs_root *root, struct btrfs_leaf_ref *ref);
-
 #endif
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index db9fb3bc1e33..f3fd7e2cbc38 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -37,7 +37,6 @@
 #include <linux/ctype.h>
 #include <linux/namei.h>
 #include <linux/miscdevice.h>
-#include <linux/version.h>
 #include <linux/magic.h>
 #include "compat.h"
 #include "ctree.h"
@@ -583,17 +582,18 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
 	struct btrfs_ioctl_vol_args *vol;
 	struct btrfs_fs_devices *fs_devices;
 	int ret = -ENOTTY;
-	int len;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	vol = kmalloc(sizeof(*vol), GFP_KERNEL);
+	if (!vol)
+		return -ENOMEM;
+
 	if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) {
 		ret = -EFAULT;
 		goto out;
 	}
-	len = strnlen(vol->name, BTRFS_PATH_NAME_MAX);
 
 	switch (cmd) {
 	case BTRFS_IOC_SCAN_DEV:
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 8a08f9443340..919172de5c9a 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -852,11 +852,9 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
 {
 	struct btrfs_pending_snapshot *pending;
 	struct list_head *head = &trans->transaction->pending_snapshots;
-	struct list_head *cur;
 	int ret;
 
-	list_for_each(cur, head) {
-		pending = list_entry(cur, struct btrfs_pending_snapshot, list);
+	list_for_each_entry(pending, head, list) {
 		ret = create_pending_snapshot(trans, fs_info, pending);
 		BUG_ON(ret);
 	}
diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c
index 3e8358c36165..98d25fa4570e 100644
--- a/fs/btrfs/tree-defrag.c
+++ b/fs/btrfs/tree-defrag.c
@@ -74,6 +74,7 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
 		u32 nritems;
 
 		root_node = btrfs_lock_root_node(root);
+		btrfs_set_lock_blocking(root_node);
 		nritems = btrfs_header_nritems(root_node);
 		root->defrag_max.objectid = 0;
 		/* from above we know this is not a leaf */
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index d81cda2e077c..20794290256b 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -78,104 +78,6 @@ static int link_to_fixup_dir(struct btrfs_trans_handle *trans,
  */
 
 /*
- * btrfs_add_log_tree adds a new per-subvolume log tree into the
- * tree of log tree roots.  This must be called with a tree log transaction
- * running (see start_log_trans).
- */
-static int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
-		      struct btrfs_root *root)
-{
-	struct btrfs_key key;
-	struct btrfs_root_item root_item;
-	struct btrfs_inode_item *inode_item;
-	struct extent_buffer *leaf;
-	struct btrfs_root *new_root = root;
-	int ret;
-	u64 objectid = root->root_key.objectid;
-
-	leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0,
-				      BTRFS_TREE_LOG_OBJECTID,
-				      trans->transid, 0, 0, 0);
-	if (IS_ERR(leaf)) {
-		ret = PTR_ERR(leaf);
-		return ret;
-	}
-
-	btrfs_set_header_nritems(leaf, 0);
-	btrfs_set_header_level(leaf, 0);
-	btrfs_set_header_bytenr(leaf, leaf->start);
-	btrfs_set_header_generation(leaf, trans->transid);
-	btrfs_set_header_owner(leaf, BTRFS_TREE_LOG_OBJECTID);
-
-	write_extent_buffer(leaf, root->fs_info->fsid,
-			    (unsigned long)btrfs_header_fsid(leaf),
-			    BTRFS_FSID_SIZE);
-	btrfs_mark_buffer_dirty(leaf);
-
-	inode_item = &root_item.inode;
-	memset(inode_item, 0, sizeof(*inode_item));
-	inode_item->generation = cpu_to_le64(1);
-	inode_item->size = cpu_to_le64(3);
-	inode_item->nlink = cpu_to_le32(1);
-	inode_item->nbytes = cpu_to_le64(root->leafsize);
-	inode_item->mode = cpu_to_le32(S_IFDIR | 0755);
-
-	btrfs_set_root_bytenr(&root_item, leaf->start);
-	btrfs_set_root_generation(&root_item, trans->transid);
-	btrfs_set_root_level(&root_item, 0);
-	btrfs_set_root_refs(&root_item, 0);
-	btrfs_set_root_used(&root_item, 0);
-
-	memset(&root_item.drop_progress, 0, sizeof(root_item.drop_progress));
-	root_item.drop_level = 0;
-
-	btrfs_tree_unlock(leaf);
-	free_extent_buffer(leaf);
-	leaf = NULL;
-
-	btrfs_set_root_dirid(&root_item, 0);
-
-	key.objectid = BTRFS_TREE_LOG_OBJECTID;
-	key.offset = objectid;
-	btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
-	ret = btrfs_insert_root(trans, root->fs_info->log_root_tree, &key,
-				&root_item);
-	if (ret)
-		goto fail;
-
-	new_root = btrfs_read_fs_root_no_radix(root->fs_info->log_root_tree,
-					       &key);
-	BUG_ON(!new_root);
-
-	WARN_ON(root->log_root);
-	root->log_root = new_root;
-
-	/*
-	 * log trees do not get reference counted because they go away
-	 * before a real commit is actually done.  They do store pointers
-	 * to file data extents, and those reference counts still get
-	 * updated (along with back refs to the log tree).
-	 */
-	new_root->ref_cows = 0;
-	new_root->last_trans = trans->transid;
-
-	/*
-	 * we need to make sure the root block for this new tree
-	 * is marked as dirty in the dirty_log_pages tree.  This
-	 * is how it gets flushed down to disk at tree log commit time.
-	 *
-	 * the tree logging mutex keeps others from coming in and changing
-	 * the new_root->node, so we can safely access it here
-	 */
-	set_extent_dirty(&new_root->dirty_log_pages, new_root->node->start,
-			 new_root->node->start + new_root->node->len - 1,
-			 GFP_NOFS);
-
-fail:
-	return ret;
-}
-
-/*
  * start a sub transaction and setup the log tree
  * this increments the log tree writer count to make the people
  * syncing the tree wait for us to finish
@@ -184,6 +86,14 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
 			   struct btrfs_root *root)
 {
 	int ret;
+
+	mutex_lock(&root->log_mutex);
+	if (root->log_root) {
+		root->log_batch++;
+		atomic_inc(&root->log_writers);
+		mutex_unlock(&root->log_mutex);
+		return 0;
+	}
 	mutex_lock(&root->fs_info->tree_log_mutex);
 	if (!root->fs_info->log_root_tree) {
 		ret = btrfs_init_log_root_tree(trans, root->fs_info);
@@ -193,9 +103,10 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
 		ret = btrfs_add_log_tree(trans, root);
 		BUG_ON(ret);
 	}
-	atomic_inc(&root->fs_info->tree_log_writers);
-	root->fs_info->tree_log_batch++;
 	mutex_unlock(&root->fs_info->tree_log_mutex);
+	root->log_batch++;
+	atomic_inc(&root->log_writers);
+	mutex_unlock(&root->log_mutex);
 	return 0;
 }
 
@@ -212,13 +123,12 @@ static int join_running_log_trans(struct btrfs_root *root)
 	if (!root->log_root)
 		return -ENOENT;
 
-	mutex_lock(&root->fs_info->tree_log_mutex);
+	mutex_lock(&root->log_mutex);
 	if (root->log_root) {
 		ret = 0;
-		atomic_inc(&root->fs_info->tree_log_writers);
-		root->fs_info->tree_log_batch++;
+		atomic_inc(&root->log_writers);
 	}
-	mutex_unlock(&root->fs_info->tree_log_mutex);
+	mutex_unlock(&root->log_mutex);
 	return ret;
 }
 
@@ -228,10 +138,11 @@ static int join_running_log_trans(struct btrfs_root *root)
  */
 static int end_log_trans(struct btrfs_root *root)
 {
-	atomic_dec(&root->fs_info->tree_log_writers);
-	smp_mb();
-	if (waitqueue_active(&root->fs_info->tree_log_wait))
-		wake_up(&root->fs_info->tree_log_wait);
+	if (atomic_dec_and_test(&root->log_writers)) {
+		smp_mb();
+		if (waitqueue_active(&root->log_writer_wait))
+			wake_up(&root->log_writer_wait);
+	}
 	return 0;
 }
 
@@ -1704,6 +1615,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
 
 				btrfs_tree_lock(next);
 				clean_tree_block(trans, root, next);
+				btrfs_set_lock_blocking(next);
 				btrfs_wait_tree_block_writeback(next);
 				btrfs_tree_unlock(next);
 
@@ -1750,6 +1662,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
 		next = path->nodes[*level];
 		btrfs_tree_lock(next);
 		clean_tree_block(trans, root, next);
+		btrfs_set_lock_blocking(next);
 		btrfs_wait_tree_block_writeback(next);
 		btrfs_tree_unlock(next);
 
@@ -1807,6 +1720,7 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
 
 				btrfs_tree_lock(next);
 				clean_tree_block(trans, root, next);
+				btrfs_set_lock_blocking(next);
 				btrfs_wait_tree_block_writeback(next);
 				btrfs_tree_unlock(next);
 
@@ -1879,6 +1793,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
 
 			btrfs_tree_lock(next);
 			clean_tree_block(trans, log, next);
+			btrfs_set_lock_blocking(next);
 			btrfs_wait_tree_block_writeback(next);
 			btrfs_tree_unlock(next);
 
@@ -1902,26 +1817,65 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
 		}
 	}
 	btrfs_free_path(path);
-	if (wc->free)
-		free_extent_buffer(log->node);
 	return ret;
 }
 
-static int wait_log_commit(struct btrfs_root *log)
+/*
+ * helper function to update the item for a given subvolumes log root
+ * in the tree of log roots
+ */
+static int update_log_root(struct btrfs_trans_handle *trans,
+			   struct btrfs_root *log)
+{
+	int ret;
+
+	if (log->log_transid == 1) {
+		/* insert root item on the first sync */
+		ret = btrfs_insert_root(trans, log->fs_info->log_root_tree,
+				&log->root_key, &log->root_item);
+	} else {
+		ret = btrfs_update_root(trans, log->fs_info->log_root_tree,
+				&log->root_key, &log->root_item);
+	}
+	return ret;
+}
+
+static int wait_log_commit(struct btrfs_root *root, unsigned long transid)
 {
 	DEFINE_WAIT(wait);
-	u64 transid = log->fs_info->tree_log_transid;
+	int index = transid % 2;
 
+	/*
+	 * we only allow two pending log transactions at a time,
+	 * so we know that if ours is more than 2 older than the
+	 * current transaction, we're done
+	 */
 	do {
-		prepare_to_wait(&log->fs_info->tree_log_wait, &wait,
-				TASK_UNINTERRUPTIBLE);
-		mutex_unlock(&log->fs_info->tree_log_mutex);
-		if (atomic_read(&log->fs_info->tree_log_commit))
+		prepare_to_wait(&root->log_commit_wait[index],
+				&wait, TASK_UNINTERRUPTIBLE);
+		mutex_unlock(&root->log_mutex);
+		if (root->log_transid < transid + 2 &&
+		    atomic_read(&root->log_commit[index]))
 			schedule();
-		finish_wait(&log->fs_info->tree_log_wait, &wait);
-		mutex_lock(&log->fs_info->tree_log_mutex);
-	} while (transid == log->fs_info->tree_log_transid &&
-		atomic_read(&log->fs_info->tree_log_commit));
+		finish_wait(&root->log_commit_wait[index], &wait);
+		mutex_lock(&root->log_mutex);
+	} while (root->log_transid < transid + 2 &&
+		 atomic_read(&root->log_commit[index]));
+	return 0;
+}
+
+static int wait_for_writer(struct btrfs_root *root)
+{
+	DEFINE_WAIT(wait);
+	while (atomic_read(&root->log_writers)) {
+		prepare_to_wait(&root->log_writer_wait,
+				&wait, TASK_UNINTERRUPTIBLE);
+		mutex_unlock(&root->log_mutex);
+		if (atomic_read(&root->log_writers))
+			schedule();
+		mutex_lock(&root->log_mutex);
+		finish_wait(&root->log_writer_wait, &wait);
+	}
 	return 0;
 }
 
@@ -1933,57 +1887,114 @@ static int wait_log_commit(struct btrfs_root *log)
 int btrfs_sync_log(struct btrfs_trans_handle *trans,
 		   struct btrfs_root *root)
 {
+	int index1;
+	int index2;
 	int ret;
-	unsigned long batch;
 	struct btrfs_root *log = root->log_root;
+	struct btrfs_root *log_root_tree = root->fs_info->log_root_tree;
 
-	mutex_lock(&log->fs_info->tree_log_mutex);
-	if (atomic_read(&log->fs_info->tree_log_commit)) {
-		wait_log_commit(log);
-		goto out;
+	mutex_lock(&root->log_mutex);
+	index1 = root->log_transid % 2;
+	if (atomic_read(&root->log_commit[index1])) {
+		wait_log_commit(root, root->log_transid);
+		mutex_unlock(&root->log_mutex);
+		return 0;
 	}
-	atomic_set(&log->fs_info->tree_log_commit, 1);
+	atomic_set(&root->log_commit[index1], 1);
+
+	/* wait for previous tree log sync to complete */
+	if (atomic_read(&root->log_commit[(index1 + 1) % 2]))
+		wait_log_commit(root, root->log_transid - 1);
 
 	while (1) {
-		batch = log->fs_info->tree_log_batch;
-		mutex_unlock(&log->fs_info->tree_log_mutex);
+		unsigned long batch = root->log_batch;
+		mutex_unlock(&root->log_mutex);
 		schedule_timeout_uninterruptible(1);
-		mutex_lock(&log->fs_info->tree_log_mutex);
-
-		while (atomic_read(&log->fs_info->tree_log_writers)) {
-			DEFINE_WAIT(wait);
-			prepare_to_wait(&log->fs_info->tree_log_wait, &wait,
-					TASK_UNINTERRUPTIBLE);
-			mutex_unlock(&log->fs_info->tree_log_mutex);
-			if (atomic_read(&log->fs_info->tree_log_writers))
-				schedule();
-			mutex_lock(&log->fs_info->tree_log_mutex);
-			finish_wait(&log->fs_info->tree_log_wait, &wait);
-		}
-		if (batch == log->fs_info->tree_log_batch)
+		mutex_lock(&root->log_mutex);
+		wait_for_writer(root);
+		if (batch == root->log_batch)
 			break;
 	}
 
 	ret = btrfs_write_and_wait_marked_extents(log, &log->dirty_log_pages);
 	BUG_ON(ret);
-	ret = btrfs_write_and_wait_marked_extents(root->fs_info->log_root_tree,
-			       &root->fs_info->log_root_tree->dirty_log_pages);
+
+	btrfs_set_root_bytenr(&log->root_item, log->node->start);
+	btrfs_set_root_generation(&log->root_item, trans->transid);
+	btrfs_set_root_level(&log->root_item, btrfs_header_level(log->node));
+
+	root->log_batch = 0;
+	root->log_transid++;
+	log->log_transid = root->log_transid;
+	smp_mb();
+	/*
+	 * log tree has been flushed to disk, new modifications of
+	 * the log will be written to new positions. so it's safe to
+	 * allow log writers to go in.
+	 */
+	mutex_unlock(&root->log_mutex);
+
+	mutex_lock(&log_root_tree->log_mutex);
+	log_root_tree->log_batch++;
+	atomic_inc(&log_root_tree->log_writers);
+	mutex_unlock(&log_root_tree->log_mutex);
+
+	ret = update_log_root(trans, log);
+	BUG_ON(ret);
+
+	mutex_lock(&log_root_tree->log_mutex);
+	if (atomic_dec_and_test(&log_root_tree->log_writers)) {
+		smp_mb();
+		if (waitqueue_active(&log_root_tree->log_writer_wait))
+			wake_up(&log_root_tree->log_writer_wait);
+	}
+
+	index2 = log_root_tree->log_transid % 2;
+	if (atomic_read(&log_root_tree->log_commit[index2])) {
+		wait_log_commit(log_root_tree, log_root_tree->log_transid);
+		mutex_unlock(&log_root_tree->log_mutex);
+		goto out;
+	}
+	atomic_set(&log_root_tree->log_commit[index2], 1);
+
+	if (atomic_read(&log_root_tree->log_commit[(index2 + 1) % 2]))
+		wait_log_commit(log_root_tree, log_root_tree->log_transid - 1);
+
+	wait_for_writer(log_root_tree);
+
+	ret = btrfs_write_and_wait_marked_extents(log_root_tree,
+				&log_root_tree->dirty_log_pages);
 	BUG_ON(ret);
 
 	btrfs_set_super_log_root(&root->fs_info->super_for_commit,
-				 log->fs_info->log_root_tree->node->start);
+				log_root_tree->node->start);
 	btrfs_set_super_log_root_level(&root->fs_info->super_for_commit,
-		       btrfs_header_level(log->fs_info->log_root_tree->node));
+				btrfs_header_level(log_root_tree->node));
+
+	log_root_tree->log_batch = 0;
+	log_root_tree->log_transid++;
+	smp_mb();
+
+	mutex_unlock(&log_root_tree->log_mutex);
+
+	/*
+	 * nobody else is going to jump in and write the the ctree
+	 * super here because the log_commit atomic below is protecting
+	 * us.  We must be called with a transaction handle pinning
+	 * the running transaction open, so a full commit can't hop
+	 * in and cause problems either.
+	 */
+	write_ctree_super(trans, root->fs_info->tree_root, 2);
 
-	write_ctree_super(trans, log->fs_info->tree_root, 2);
-	log->fs_info->tree_log_transid++;
-	log->fs_info->tree_log_batch = 0;
-	atomic_set(&log->fs_info->tree_log_commit, 0);
+	atomic_set(&log_root_tree->log_commit[index2], 0);
 	smp_mb();
-	if (waitqueue_active(&log->fs_info->tree_log_wait))
-		wake_up(&log->fs_info->tree_log_wait);
+	if (waitqueue_active(&log_root_tree->log_commit_wait[index2]))
+		wake_up(&log_root_tree->log_commit_wait[index2]);
 out:
-	mutex_unlock(&log->fs_info->tree_log_mutex);
+	atomic_set(&root->log_commit[index1], 0);
+	smp_mb();
+	if (waitqueue_active(&root->log_commit_wait[index1]))
+		wake_up(&root->log_commit_wait[index1]);
 	return 0;
 }
 
@@ -2019,38 +2030,18 @@ int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root)
 				   start, end, GFP_NOFS);
 	}
 
-	log = root->log_root;
-	ret = btrfs_del_root(trans, root->fs_info->log_root_tree,
-			     &log->root_key);
-	BUG_ON(ret);
+	if (log->log_transid > 0) {
+		ret = btrfs_del_root(trans, root->fs_info->log_root_tree,
+				     &log->root_key);
+		BUG_ON(ret);
+	}
 	root->log_root = NULL;
-	kfree(root->log_root);
+	free_extent_buffer(log->node);
+	kfree(log);
 	return 0;
 }
 
 /*
- * helper function to update the item for a given subvolumes log root
- * in the tree of log roots
- */
-static int update_log_root(struct btrfs_trans_handle *trans,
-			   struct btrfs_root *log)
-{
-	u64 bytenr = btrfs_root_bytenr(&log->root_item);
-	int ret;
-
-	if (log->node->start == bytenr)
-		return 0;
-
-	btrfs_set_root_bytenr(&log->root_item, log->node->start);
-	btrfs_set_root_generation(&log->root_item, trans->transid);
-	btrfs_set_root_level(&log->root_item, btrfs_header_level(log->node));
-	ret = btrfs_update_root(trans, log->fs_info->log_root_tree,
-				&log->root_key, &log->root_item);
-	BUG_ON(ret);
-	return ret;
-}
-
-/*
  * If both a file and directory are logged, and unlinks or renames are
  * mixed in, we have a few interesting corners:
  *
@@ -2711,11 +2702,6 @@ next_slot:
 
 	btrfs_free_path(path);
 	btrfs_free_path(dst_path);
-
-	mutex_lock(&root->fs_info->tree_log_mutex);
-	ret = update_log_root(trans, log);
-	BUG_ON(ret);
-	mutex_unlock(&root->fs_info->tree_log_mutex);
 out:
 	return 0;
 }
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 3451e1cca2b5..bcd14ebccae1 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -20,7 +20,6 @@
 #include <linux/buffer_head.h>
 #include <linux/blkdev.h>
 #include <linux/random.h>
-#include <linux/version.h>
 #include <asm/div64.h>
 #include "compat.h"
 #include "ctree.h"
@@ -104,10 +103,8 @@ static noinline struct btrfs_device *__find_device(struct list_head *head,
 						   u64 devid, u8 *uuid)
 {
 	struct btrfs_device *dev;
-	struct list_head *cur;
 
-	list_for_each(cur, head) {
-		dev = list_entry(cur, struct btrfs_device, dev_list);
+	list_for_each_entry(dev, head, dev_list) {
 		if (dev->devid == devid &&
 		    (!uuid || !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE))) {
 			return dev;
@@ -118,11 +115,9 @@ static noinline struct btrfs_device *__find_device(struct list_head *head,
 
 static noinline struct btrfs_fs_devices *find_fsid(u8 *fsid)
 {
-	struct list_head *cur;
 	struct btrfs_fs_devices *fs_devices;
 
-	list_for_each(cur, &fs_uuids) {
-		fs_devices = list_entry(cur, struct btrfs_fs_devices, list);
+	list_for_each_entry(fs_devices, &fs_uuids, list) {
 		if (memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE) == 0)
 			return fs_devices;
 	}
@@ -159,6 +154,7 @@ static noinline int run_scheduled_bios(struct btrfs_device *device)
 loop:
 	spin_lock(&device->io_lock);
 
+loop_lock:
 	/* take all the bios off the list at once and process them
 	 * later on (without the lock held).  But, remember the
 	 * tail and other pointers so the bios can be properly reinserted
@@ -208,7 +204,7 @@ loop:
 		 * is now congested.  Back off and let other work structs
 		 * run instead
 		 */
-		if (pending && bdi_write_congested(bdi) &&
+		if (pending && bdi_write_congested(bdi) && num_run > 16 &&
 		    fs_info->fs_devices->open_devices > 1) {
 			struct bio *old_head;
 
@@ -220,7 +216,8 @@ loop:
 				tail->bi_next = old_head;
 			else
 				device->pending_bio_tail = tail;
-			device->running_pending = 0;
+
+			device->running_pending = 1;
 
 			spin_unlock(&device->io_lock);
 			btrfs_requeue_work(&device->work);
@@ -229,6 +226,11 @@ loop:
 	}
 	if (again)
 		goto loop;
+
+	spin_lock(&device->io_lock);
+	if (device->pending_bios)
+		goto loop_lock;
+	spin_unlock(&device->io_lock);
 done:
 	return 0;
 }
@@ -345,14 +347,11 @@ error:
 
 int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices)
 {
-	struct list_head *tmp;
-	struct list_head *cur;
-	struct btrfs_device *device;
+	struct btrfs_device *device, *next;
 
 	mutex_lock(&uuid_mutex);
 again:
-	list_for_each_safe(cur, tmp, &fs_devices->devices) {
-		device = list_entry(cur, struct btrfs_device, dev_list);
+	list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) {
 		if (device->in_fs_metadata)
 			continue;
 
@@ -383,14 +382,12 @@ again:
 
 static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
 {
-	struct list_head *cur;
 	struct btrfs_device *device;
 
 	if (--fs_devices->opened > 0)
 		return 0;
 
-	list_for_each(cur, &fs_devices->devices) {
-		device = list_entry(cur, struct btrfs_device, dev_list);
+	list_for_each_entry(device, &fs_devices->devices, dev_list) {
 		if (device->bdev) {
 			close_bdev_exclusive(device->bdev, device->mode);
 			fs_devices->open_devices--;
@@ -439,7 +436,6 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
 {
 	struct block_device *bdev;
 	struct list_head *head = &fs_devices->devices;
-	struct list_head *cur;
 	struct btrfs_device *device;
 	struct block_device *latest_bdev = NULL;
 	struct buffer_head *bh;
@@ -450,8 +446,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
 	int seeding = 1;
 	int ret = 0;
 
-	list_for_each(cur, head) {
-		device = list_entry(cur, struct btrfs_device, dev_list);
+	list_for_each_entry(device, head, dev_list) {
 		if (device->bdev)
 			continue;
 		if (!device->name)
@@ -578,7 +573,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
 		       *(unsigned long long *)disk_super->fsid,
 		       *(unsigned long long *)(disk_super->fsid + 8));
 	}
-	printk(KERN_INFO "devid %llu transid %llu %s\n",
+	printk(KERN_CONT "devid %llu transid %llu %s\n",
 	       (unsigned long long)devid, (unsigned long long)transid, path);
 	ret = device_list_add(path, disk_super, devid, fs_devices_ret);
 
@@ -1017,14 +1012,12 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 	}
 
 	if (strcmp(device_path, "missing") == 0) {
-		struct list_head *cur;
 		struct list_head *devices;
 		struct btrfs_device *tmp;
 
 		device = NULL;
 		devices = &root->fs_info->fs_devices->devices;
-		list_for_each(cur, devices) {
-			tmp = list_entry(cur, struct btrfs_device, dev_list);
+		list_for_each_entry(tmp, devices, dev_list) {
 			if (tmp->in_fs_metadata && !tmp->bdev) {
 				device = tmp;
 				break;
@@ -1280,7 +1273,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
 	struct btrfs_trans_handle *trans;
 	struct btrfs_device *device;
 	struct block_device *bdev;
-	struct list_head *cur;
 	struct list_head *devices;
 	struct super_block *sb = root->fs_info->sb;
 	u64 total_bytes;
@@ -1304,8 +1296,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
 	mutex_lock(&root->fs_info->volume_mutex);
 
 	devices = &root->fs_info->fs_devices->devices;
-	list_for_each(cur, devices) {
-		device = list_entry(cur, struct btrfs_device, dev_list);
+	list_for_each_entry(device, devices, dev_list) {
 		if (device->bdev == bdev) {
 			ret = -EEXIST;
 			goto error;
@@ -1704,7 +1695,6 @@ static u64 div_factor(u64 num, int factor)
 int btrfs_balance(struct btrfs_root *dev_root)
 {
 	int ret;
-	struct list_head *cur;
 	struct list_head *devices = &dev_root->fs_info->fs_devices->devices;
 	struct btrfs_device *device;
 	u64 old_size;
@@ -1723,8 +1713,7 @@ int btrfs_balance(struct btrfs_root *dev_root)
 	dev_root = dev_root->fs_info->dev_root;
 
 	/* step one make some room on all the devices */
-	list_for_each(cur, devices) {
-		device = list_entry(cur, struct btrfs_device, dev_list);
+	list_for_each_entry(device, devices, dev_list) {
 		old_size = device->total_bytes;
 		size_to_free = div_factor(old_size, 1);
 		size_to_free = min(size_to_free, (u64)1 * 1024 * 1024);
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index 7f332e270894..a9d3bf4d2689 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/rwsem.h>
 #include <linux/xattr.h>
+#include <linux/security.h>
 #include "ctree.h"
 #include "btrfs_inode.h"
 #include "transaction.h"
@@ -45,9 +46,12 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name,
 	/* lookup the xattr by name */
 	di = btrfs_lookup_xattr(NULL, root, path, inode->i_ino, name,
 				strlen(name), 0);
-	if (!di || IS_ERR(di)) {
+	if (!di) {
 		ret = -ENODATA;
 		goto out;
+	} else if (IS_ERR(di)) {
+		ret = PTR_ERR(di);
+		goto out;
 	}
 
 	leaf = path->nodes[0];
@@ -62,6 +66,14 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name,
 		ret = -ERANGE;
 		goto out;
 	}
+
+	/*
+	 * The way things are packed into the leaf is like this
+	 * |struct btrfs_dir_item|name|data|
+	 * where name is the xattr name, so security.foo, and data is the
+	 * content of the xattr.  data_ptr points to the location in memory
+	 * where the data starts in the in memory leaf
+	 */
 	data_ptr = (unsigned long)((char *)(di + 1) +
 				   btrfs_dir_name_len(leaf, di));
 	read_extent_buffer(leaf, buffer, data_ptr,
@@ -86,7 +98,7 @@ int __btrfs_setxattr(struct inode *inode, const char *name,
 	if (!path)
 		return -ENOMEM;
 
-	trans = btrfs_start_transaction(root, 1);
+	trans = btrfs_join_transaction(root, 1);
 	btrfs_set_trans_block_group(trans, inode);
 
 	/* first lets see if we already have this xattr */
@@ -176,7 +188,6 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
 	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
 	if (ret < 0)
 		goto err;
-	ret = 0;
 	advance = 0;
 	while (1) {
 		leaf = path->nodes[0];
@@ -320,3 +331,34 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
 		return -EOPNOTSUPP;
 	return __btrfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE);
 }
+
+int btrfs_xattr_security_init(struct inode *inode, struct inode *dir)
+{
+	int err;
+	size_t len;
+	void *value;
+	char *suffix;
+	char *name;
+
+	err = security_inode_init_security(inode, dir, &suffix, &value, &len);
+	if (err) {
+		if (err == -EOPNOTSUPP)
+			return 0;
+		return err;
+	}
+
+	name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1,
+		       GFP_NOFS);
+	if (!name) {
+		err = -ENOMEM;
+	} else {
+		strcpy(name, XATTR_SECURITY_PREFIX);
+		strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix);
+		err = __btrfs_setxattr(inode, name, value, len, 0);
+		kfree(name);
+	}
+
+	kfree(suffix);
+	kfree(value);
+	return err;
+}
diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h
index 5b1d08f8e68d..c71e9c3cf3f7 100644
--- a/fs/btrfs/xattr.h
+++ b/fs/btrfs/xattr.h
@@ -36,4 +36,6 @@ extern int btrfs_setxattr(struct dentry *dentry, const char *name,
 		const void *value, size_t size, int flags);
 extern int btrfs_removexattr(struct dentry *dentry, const char *name);
 
+extern int btrfs_xattr_security_init(struct inode *inode, struct inode *dir);
+
 #endif /* __XATTR__ */
diff --git a/fs/buffer.c b/fs/buffer.c
index b58208f1640a..665d446b25bc 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2688,7 +2688,7 @@ int nobh_write_end(struct file *file, struct address_space *mapping,
 	struct buffer_head *bh;
 	BUG_ON(fsdata != NULL && page_has_buffers(page));
 
-	if (unlikely(copied < len) && !page_has_buffers(page))
+	if (unlikely(copied < len) && head)
 		attach_nobh_buffers(page, head);
 	if (page_has_buffers(page))
 		return generic_write_end(file, mapping, pos, len,
diff --git a/fs/compat.c b/fs/compat.c
index 65a070e705ab..d0145ca27572 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1407,7 +1407,7 @@ int compat_do_execve(char * filename,
 	bprm->cred = prepare_exec_creds();
 	if (!bprm->cred)
 		goto out_unlock;
-	check_unsafe_exec(bprm);
+	check_unsafe_exec(bprm, current->files);
 
 	file = open_exec(filename);
 	retval = PTR_ERR(file);
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index c8f8d5904f5e..9c6d815dd191 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -785,7 +785,7 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
 
 	if (copy_in_user(&sgio->status, &sgio32->status,
 			 (4 * sizeof(unsigned char)) +
-			 (2 * sizeof(unsigned (short))) +
+			 (2 * sizeof(unsigned short)) +
 			 (3 * sizeof(int))))
 		return -EFAULT;
 
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index c01e043670e2..f6caeb1d1106 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -1716,7 +1716,7 @@ static int ecryptfs_copy_filename(char **copied_name, size_t *copied_name_size,
 {
 	int rc = 0;
 
-	(*copied_name) = kmalloc((name_size + 2), GFP_KERNEL);
+	(*copied_name) = kmalloc((name_size + 1), GFP_KERNEL);
 	if (!(*copied_name)) {
 		rc = -ENOMEM;
 		goto out;
@@ -1726,7 +1726,7 @@ static int ecryptfs_copy_filename(char **copied_name, size_t *copied_name_size,
 						 * in printing out the
 						 * string in debug
 						 * messages */
-	(*copied_name_size) = (name_size + 1);
+	(*copied_name_size) = name_size;
 out:
 	return rc;
 }
diff --git a/fs/exec.c b/fs/exec.c
index 0dd60a01f1b4..929b58004b7e 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1049,16 +1049,32 @@ EXPORT_SYMBOL(install_exec_creds);
  * - the caller must hold current->cred_exec_mutex to protect against
  *   PTRACE_ATTACH
  */
-void check_unsafe_exec(struct linux_binprm *bprm)
+void check_unsafe_exec(struct linux_binprm *bprm, struct files_struct *files)
 {
-	struct task_struct *p = current;
+	struct task_struct *p = current, *t;
+	unsigned long flags;
+	unsigned n_fs, n_files, n_sighand;
 
 	bprm->unsafe = tracehook_unsafe_exec(p);
 
-	if (atomic_read(&p->fs->count) > 1 ||
-	    atomic_read(&p->files->count) > 1 ||
-	    atomic_read(&p->sighand->count) > 1)
+	n_fs = 1;
+	n_files = 1;
+	n_sighand = 1;
+	lock_task_sighand(p, &flags);
+	for (t = next_thread(p); t != p; t = next_thread(t)) {
+		if (t->fs == p->fs)
+			n_fs++;
+		if (t->files == files)
+			n_files++;
+		n_sighand++;
+	}
+
+	if (atomic_read(&p->fs->count) > n_fs ||
+	    atomic_read(&p->files->count) > n_files ||
+	    atomic_read(&p->sighand->count) > n_sighand)
 		bprm->unsafe |= LSM_UNSAFE_SHARE;
+
+	unlock_task_sighand(p, &flags);
 }
 
 /* 
@@ -1273,7 +1289,7 @@ int do_execve(char * filename,
 	bprm->cred = prepare_exec_creds();
 	if (!bprm->cred)
 		goto out_unlock;
-	check_unsafe_exec(bprm);
+	check_unsafe_exec(bprm, displaced);
 
 	file = open_exec(filename);
 	retval = PTR_ERR(file);
diff --git a/fs/internal.h b/fs/internal.h
index 53af885f1732..0d8ac497b3d5 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -43,7 +43,7 @@ extern void __init chrdev_init(void);
 /*
  * exec.c
  */
-extern void check_unsafe_exec(struct linux_binprm *);
+extern void check_unsafe_exec(struct linux_binprm *, struct files_struct *);
 
 /*
  * namespace.c
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index d861096c9d81..60fe74035db5 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -5390,6 +5390,9 @@ int ocfs2_remove_btree_range(struct inode *inode,
 		goto out;
 	}
 
+	vfs_dq_free_space_nodirty(inode,
+				  ocfs2_clusters_to_bytes(inode->i_sb, len));
+
 	ret = ocfs2_remove_extent(inode, et, cpos, len, handle, meta_ac,
 				  dealloc);
 	if (ret) {
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
index b1cc7c381e88..e9d7c2038c0f 100644
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -38,6 +38,7 @@
 #include "dlmglue.h"
 #include "file.h"
 #include "inode.h"
+#include "super.h"
 
 
 static int ocfs2_dentry_revalidate(struct dentry *dentry,
@@ -294,6 +295,34 @@ out_attach:
 	return ret;
 }
 
+static DEFINE_SPINLOCK(dentry_list_lock);
+
+/* We limit the number of dentry locks to drop in one go. We have
+ * this limit so that we don't starve other users of ocfs2_wq. */
+#define DL_INODE_DROP_COUNT 64
+
+/* Drop inode references from dentry locks */
+void ocfs2_drop_dl_inodes(struct work_struct *work)
+{
+	struct ocfs2_super *osb = container_of(work, struct ocfs2_super,
+					       dentry_lock_work);
+	struct ocfs2_dentry_lock *dl;
+	int drop_count = DL_INODE_DROP_COUNT;
+
+	spin_lock(&dentry_list_lock);
+	while (osb->dentry_lock_list && drop_count--) {
+		dl = osb->dentry_lock_list;
+		osb->dentry_lock_list = dl->dl_next;
+		spin_unlock(&dentry_list_lock);
+		iput(dl->dl_inode);
+		kfree(dl);
+		spin_lock(&dentry_list_lock);
+	}
+	if (osb->dentry_lock_list)
+		queue_work(ocfs2_wq, &osb->dentry_lock_work);
+	spin_unlock(&dentry_list_lock);
+}
+
 /*
  * ocfs2_dentry_iput() and friends.
  *
@@ -318,16 +347,23 @@ out_attach:
 static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
 				   struct ocfs2_dentry_lock *dl)
 {
-	iput(dl->dl_inode);
 	ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
 	ocfs2_lock_res_free(&dl->dl_lockres);
-	kfree(dl);
+
+	/* We leave dropping of inode reference to ocfs2_wq as that can
+	 * possibly lead to inode deletion which gets tricky */
+	spin_lock(&dentry_list_lock);
+	if (!osb->dentry_lock_list)
+		queue_work(ocfs2_wq, &osb->dentry_lock_work);
+	dl->dl_next = osb->dentry_lock_list;
+	osb->dentry_lock_list = dl;
+	spin_unlock(&dentry_list_lock);
 }
 
 void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
 			   struct ocfs2_dentry_lock *dl)
 {
-	int unlock = 0;
+	int unlock;
 
 	BUG_ON(dl->dl_count == 0);
 
diff --git a/fs/ocfs2/dcache.h b/fs/ocfs2/dcache.h
index c091c34d9883..d06e16c06640 100644
--- a/fs/ocfs2/dcache.h
+++ b/fs/ocfs2/dcache.h
@@ -29,8 +29,13 @@
 extern struct dentry_operations ocfs2_dentry_ops;
 
 struct ocfs2_dentry_lock {
+	/* Use count of dentry lock */
 	unsigned int		dl_count;
-	u64			dl_parent_blkno;
+	union {
+		/* Linked list of dentry locks to release */
+		struct ocfs2_dentry_lock *dl_next;
+		u64			dl_parent_blkno;
+	};
 
 	/*
 	 * The ocfs2_dentry_lock keeps an inode reference until
@@ -47,6 +52,8 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry, struct inode *inode,
 void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
 			   struct ocfs2_dentry_lock *dl);
 
+void ocfs2_drop_dl_inodes(struct work_struct *work);
+
 struct dentry *ocfs2_find_local_alias(struct inode *inode, u64 parent_blkno,
 				      int skip_unhashed);
 
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index b0c4cadd4c45..206a2370876a 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -2860,6 +2860,10 @@ static void ocfs2_unlock_ast(void *opaque, int error)
 	case OCFS2_UNLOCK_CANCEL_CONVERT:
 		mlog(0, "Cancel convert success for %s\n", lockres->l_name);
 		lockres->l_action = OCFS2_AST_INVALID;
+		/* Downconvert thread may have requeued this lock, we
+		 * need to wake it. */
+		if (lockres->l_flags & OCFS2_LOCK_BLOCKED)
+			ocfs2_wake_downconvert_thread(ocfs2_get_lockres_osb(lockres));
 		break;
 	case OCFS2_UNLOCK_DROP_LOCK:
 		lockres->l_level = DLM_LOCK_IV;
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index ad5c24a29edd..077384135f4e 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -210,6 +210,7 @@ struct ocfs2_journal;
 struct ocfs2_slot_info;
 struct ocfs2_recovery_map;
 struct ocfs2_quota_recovery;
+struct ocfs2_dentry_lock;
 struct ocfs2_super
 {
 	struct task_struct *commit_task;
@@ -325,6 +326,11 @@ struct ocfs2_super
 	struct list_head blocked_lock_list;
 	unsigned long blocked_lock_count;
 
+	/* List of dentry locks to release. Anyone can add locks to
+	 * the list, ocfs2_wq processes the list  */
+	struct ocfs2_dentry_lock *dentry_lock_list;
+	struct work_struct dentry_lock_work;
+
 	wait_queue_head_t		osb_mount_event;
 
 	/* Truncate log info */
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index f4efa89baee5..1ed0f7c86869 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -754,7 +754,9 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot)
 	if (dquot->dq_flags & mask)
 		sync = 1;
 	spin_unlock(&dq_data_lock);
-	if (!sync) {
+	/* This is a slight hack but we can't afford getting global quota
+	 * lock if we already have a transaction started. */
+	if (!sync || journal_current_handle()) {
 		status = ocfs2_write_dquot(dquot);
 		goto out;
 	}
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 43ed11345b59..b1cb38fbe807 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1887,6 +1887,9 @@ static int ocfs2_initialize_super(struct super_block *sb,
 	INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery);
 	journal->j_state = OCFS2_JOURNAL_FREE;
 
+	INIT_WORK(&osb->dentry_lock_work, ocfs2_drop_dl_inodes);
+	osb->dentry_lock_list = NULL;
+
 	/* get some pseudo constants for clustersize bits */
 	osb->s_clustersize_bits =
 		le32_to_cpu(di->id2.i_super.s_clustersize_bits);
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index e1d638af6ac3..915039fffe6e 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -4729,13 +4729,6 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
 	vb.vb_xv = (struct ocfs2_xattr_value_root *)
 		(vb.vb_bh->b_data + offset % blocksize);
 
-	ret = ocfs2_xattr_bucket_journal_access(ctxt->handle, bucket,
-						OCFS2_JOURNAL_ACCESS_WRITE);
-	if (ret) {
-		mlog_errno(ret);
-		goto out;
-	}
-
 	/*
 	 * From here on out we have to dirty the bucket.  The generic
 	 * value calls only modify one of the bucket's bhs, but we need
@@ -4748,12 +4741,18 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
 	ret = ocfs2_xattr_value_truncate(inode, &vb, len, ctxt);
 	if (ret) {
 		mlog_errno(ret);
-		goto out_dirty;
+		goto out;
+	}
+
+	ret = ocfs2_xattr_bucket_journal_access(ctxt->handle, bucket,
+						OCFS2_JOURNAL_ACCESS_WRITE);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
 	}
 
 	xe->xe_value_size = cpu_to_le64(len);
 
-out_dirty:
 	ocfs2_xattr_bucket_journal_dirty(ctxt->handle, bucket);
 
 out:
diff --git a/fs/seq_file.c b/fs/seq_file.c
index b569ff1c4dc8..5267098532bf 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -54,6 +54,64 @@ int seq_open(struct file *file, const struct seq_operations *op)
 }
 EXPORT_SYMBOL(seq_open);
 
+static int traverse(struct seq_file *m, loff_t offset)
+{
+	loff_t pos = 0, index;
+	int error = 0;
+	void *p;
+
+	m->version = 0;
+	index = 0;
+	m->count = m->from = 0;
+	if (!offset) {
+		m->index = index;
+		return 0;
+	}
+	if (!m->buf) {
+		m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
+		if (!m->buf)
+			return -ENOMEM;
+	}
+	p = m->op->start(m, &index);
+	while (p) {
+		error = PTR_ERR(p);
+		if (IS_ERR(p))
+			break;
+		error = m->op->show(m, p);
+		if (error < 0)
+			break;
+		if (unlikely(error)) {
+			error = 0;
+			m->count = 0;
+		}
+		if (m->count == m->size)
+			goto Eoverflow;
+		if (pos + m->count > offset) {
+			m->from = offset - pos;
+			m->count -= m->from;
+			m->index = index;
+			break;
+		}
+		pos += m->count;
+		m->count = 0;
+		if (pos == offset) {
+			index++;
+			m->index = index;
+			break;
+		}
+		p = m->op->next(m, p, &index);
+	}
+	m->op->stop(m, p);
+	m->index = index;
+	return error;
+
+Eoverflow:
+	m->op->stop(m, p);
+	kfree(m->buf);
+	m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
+	return !m->buf ? -ENOMEM : -EAGAIN;
+}
+
 /**
  *	seq_read -	->read() method for sequential files.
  *	@file: the file to read from
@@ -186,63 +244,6 @@ Efault:
 }
 EXPORT_SYMBOL(seq_read);
 
-static int traverse(struct seq_file *m, loff_t offset)
-{
-	loff_t pos = 0, index;
-	int error = 0;
-	void *p;
-
-	m->version = 0;
-	index = 0;
-	m->count = m->from = 0;
-	if (!offset) {
-		m->index = index;
-		return 0;
-	}
-	if (!m->buf) {
-		m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
-		if (!m->buf)
-			return -ENOMEM;
-	}
-	p = m->op->start(m, &index);
-	while (p) {
-		error = PTR_ERR(p);
-		if (IS_ERR(p))
-			break;
-		error = m->op->show(m, p);
-		if (error < 0)
-			break;
-		if (unlikely(error)) {
-			error = 0;
-			m->count = 0;
-		}
-		if (m->count == m->size)
-			goto Eoverflow;
-		if (pos + m->count > offset) {
-			m->from = offset - pos;
-			m->count -= m->from;
-			m->index = index;
-			break;
-		}
-		pos += m->count;
-		m->count = 0;
-		if (pos == offset) {
-			index++;
-			m->index = index;
-			break;
-		}
-		p = m->op->next(m, p, &index);
-	}
-	m->op->stop(m, p);
-	return error;
-
-Eoverflow:
-	m->op->stop(m, p);
-	kfree(m->buf);
-	m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
-	return !m->buf ? -ENOMEM : -EAGAIN;
-}
-
 /**
  *	seq_lseek -	->llseek() method for sequential files.
  *	@file: the file in question
diff --git a/fs/super.c b/fs/super.c
index 645e5403f2a0..61dce001dd57 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -301,7 +301,7 @@ void generic_shutdown_super(struct super_block *sb)
 		/*
 		 * wait for asynchronous fs operations to finish before going further
 		 */
-		async_synchronize_full_special(&sb->s_async_list);
+		async_synchronize_full_domain(&sb->s_async_list);
 
 		/* bad name - it should be evict_inodes() */
 		invalidate_inodes(sb);
@@ -470,7 +470,7 @@ restart:
 		sb->s_count++;
 		spin_unlock(&sb_lock);
 		down_read(&sb->s_umount);
-		async_synchronize_full_special(&sb->s_async_list);
+		async_synchronize_full_domain(&sb->s_async_list);
 		if (sb->s_root && (wait || sb->s_dirt))
 			sb->s_op->sync_fs(sb, wait);
 		up_read(&sb->s_umount);
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index 175f9c590b77..f393620890ee 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -689,7 +689,7 @@ long long ubifs_reported_space(const struct ubifs_info *c, long long free)
 }
 
 /**
- * ubifs_get_free_space - return amount of free space.
+ * ubifs_get_free_space_nolock - return amount of free space.
  * @c: UBIFS file-system description object
  *
  * This function calculates amount of free space to report to user-space.
@@ -704,16 +704,14 @@ long long ubifs_reported_space(const struct ubifs_info *c, long long free)
  * traditional file-systems, because they have way less overhead than UBIFS.
  * So, to keep users happy, UBIFS tries to take the overhead into account.
  */
-long long ubifs_get_free_space(struct ubifs_info *c)
+long long ubifs_get_free_space_nolock(struct ubifs_info *c)
 {
-	int min_idx_lebs, rsvd_idx_lebs, lebs;
+	int rsvd_idx_lebs, lebs;
 	long long available, outstanding, free;
 
-	spin_lock(&c->space_lock);
-	min_idx_lebs = c->min_idx_lebs;
-	ubifs_assert(min_idx_lebs == ubifs_calc_min_idx_lebs(c));
+	ubifs_assert(c->min_idx_lebs == ubifs_calc_min_idx_lebs(c));
 	outstanding = c->budg_data_growth + c->budg_dd_growth;
-	available = ubifs_calc_available(c, min_idx_lebs);
+	available = ubifs_calc_available(c, c->min_idx_lebs);
 
 	/*
 	 * When reporting free space to user-space, UBIFS guarantees that it is
@@ -726,15 +724,14 @@ long long ubifs_get_free_space(struct ubifs_info *c)
 	 * Note, the calculations below are similar to what we have in
 	 * 'do_budget_space()', so refer there for comments.
 	 */
-	if (min_idx_lebs > c->lst.idx_lebs)
-		rsvd_idx_lebs = min_idx_lebs - c->lst.idx_lebs;
+	if (c->min_idx_lebs > c->lst.idx_lebs)
+		rsvd_idx_lebs = c->min_idx_lebs - c->lst.idx_lebs;
 	else
 		rsvd_idx_lebs = 0;
 	lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt -
 	       c->lst.taken_empty_lebs;
 	lebs -= rsvd_idx_lebs;
 	available += lebs * (c->dark_wm - c->leb_overhead);
-	spin_unlock(&c->space_lock);
 
 	if (available > outstanding)
 		free = ubifs_reported_space(c, available - outstanding);
@@ -742,3 +739,21 @@ long long ubifs_get_free_space(struct ubifs_info *c)
 		free = 0;
 	return free;
 }
+
+/**
+ * ubifs_get_free_space - return amount of free space.
+ * @c: UBIFS file-system description object
+ *
+ * This function calculates and retuns amount of free space to report to
+ * user-space.
+ */
+long long ubifs_get_free_space(struct ubifs_info *c)
+{
+	long long free;
+
+	spin_lock(&c->space_lock);
+	free = ubifs_get_free_space_nolock(c);
+	spin_unlock(&c->space_lock);
+
+	return free;
+}
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 792c5a16c182..e975bd82f38b 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -620,9 +620,11 @@ void dbg_dump_budg(struct ubifs_info *c)
 	       c->dark_wm, c->dead_wm, c->max_idx_node_sz);
 	printk(KERN_DEBUG "\tgc_lnum %d, ihead_lnum %d\n",
 	       c->gc_lnum, c->ihead_lnum);
-	for (i = 0; i < c->jhead_cnt; i++)
-		printk(KERN_DEBUG "\tjhead %d\t LEB %d\n",
-		       c->jheads[i].wbuf.jhead, c->jheads[i].wbuf.lnum);
+	/* If we are in R/O mode, journal heads do not exist */
+	if (c->jheads)
+		for (i = 0; i < c->jhead_cnt; i++)
+			printk(KERN_DEBUG "\tjhead %d\t LEB %d\n",
+			       c->jheads[i].wbuf.jhead, c->jheads[i].wbuf.lnum);
 	for (rb = rb_first(&c->buds); rb; rb = rb_next(rb)) {
 		bud = rb_entry(rb, struct ubifs_bud, rb);
 		printk(KERN_DEBUG "\tbud LEB %d\n", bud->lnum);
@@ -637,10 +639,7 @@ void dbg_dump_budg(struct ubifs_info *c)
 	/* Print budgeting predictions */
 	available = ubifs_calc_available(c, c->min_idx_lebs);
 	outstanding = c->budg_data_growth + c->budg_dd_growth;
-	if (available > outstanding)
-		free = ubifs_reported_space(c, available - outstanding);
-	else
-		free = 0;
+	free = ubifs_get_free_space_nolock(c);
 	printk(KERN_DEBUG "Budgeting predictions:\n");
 	printk(KERN_DEBUG "\tavailable: %lld, outstanding %lld, free %lld\n",
 	       available, outstanding, free);
@@ -861,6 +860,65 @@ void dbg_dump_index(struct ubifs_info *c)
 }
 
 /**
+ * dbg_save_space_info - save information about flash space.
+ * @c: UBIFS file-system description object
+ *
+ * This function saves information about UBIFS free space, dirty space, etc, in
+ * order to check it later.
+ */
+void dbg_save_space_info(struct ubifs_info *c)
+{
+	struct ubifs_debug_info *d = c->dbg;
+
+	ubifs_get_lp_stats(c, &d->saved_lst);
+
+	spin_lock(&c->space_lock);
+	d->saved_free = ubifs_get_free_space_nolock(c);
+	spin_unlock(&c->space_lock);
+}
+
+/**
+ * dbg_check_space_info - check flash space information.
+ * @c: UBIFS file-system description object
+ *
+ * This function compares current flash space information with the information
+ * which was saved when the 'dbg_save_space_info()' function was called.
+ * Returns zero if the information has not changed, and %-EINVAL it it has
+ * changed.
+ */
+int dbg_check_space_info(struct ubifs_info *c)
+{
+	struct ubifs_debug_info *d = c->dbg;
+	struct ubifs_lp_stats lst;
+	long long avail, free;
+
+	spin_lock(&c->space_lock);
+	avail = ubifs_calc_available(c, c->min_idx_lebs);
+	spin_unlock(&c->space_lock);
+	free = ubifs_get_free_space(c);
+
+	if (free != d->saved_free) {
+		ubifs_err("free space changed from %lld to %lld",
+			  d->saved_free, free);
+		goto out;
+	}
+
+	return 0;
+
+out:
+	ubifs_msg("saved lprops statistics dump");
+	dbg_dump_lstats(&d->saved_lst);
+	ubifs_get_lp_stats(c, &lst);
+	ubifs_msg("current lprops statistics dump");
+	dbg_dump_lstats(&d->saved_lst);
+	spin_lock(&c->space_lock);
+	dbg_dump_budg(c);
+	spin_unlock(&c->space_lock);
+	dump_stack();
+	return -EINVAL;
+}
+
+/**
  * dbg_check_synced_i_size - check synchronized inode size.
  * @inode: inode to check
  *
@@ -1349,7 +1407,7 @@ int dbg_check_tnc(struct ubifs_info *c, int extra)
  * @c: UBIFS file-system description object
  * @leaf_cb: called for each leaf node
  * @znode_cb: called for each indexing node
- * @priv: private date which is passed to callbacks
+ * @priv: private data which is passed to callbacks
  *
  * This function walks the UBIFS index and calls the @leaf_cb for each leaf
  * node and @znode_cb for each indexing node. Returns zero in case of success
@@ -2409,7 +2467,7 @@ void ubifs_debugging_exit(struct ubifs_info *c)
  * Root directory for UBIFS stuff in debugfs. Contains sub-directories which
  * contain the stuff specific to particular file-system mounts.
  */
-static struct dentry *debugfs_rootdir;
+static struct dentry *dfs_rootdir;
 
 /**
  * dbg_debugfs_init - initialize debugfs file-system.
@@ -2421,9 +2479,9 @@ static struct dentry *debugfs_rootdir;
  */
 int dbg_debugfs_init(void)
 {
-	debugfs_rootdir = debugfs_create_dir("ubifs", NULL);
-	if (IS_ERR(debugfs_rootdir)) {
-		int err = PTR_ERR(debugfs_rootdir);
+	dfs_rootdir = debugfs_create_dir("ubifs", NULL);
+	if (IS_ERR(dfs_rootdir)) {
+		int err = PTR_ERR(dfs_rootdir);
 		ubifs_err("cannot create \"ubifs\" debugfs directory, "
 			  "error %d\n", err);
 		return err;
@@ -2437,7 +2495,7 @@ int dbg_debugfs_init(void)
  */
 void dbg_debugfs_exit(void)
 {
-	debugfs_remove(debugfs_rootdir);
+	debugfs_remove(dfs_rootdir);
 }
 
 static int open_debugfs_file(struct inode *inode, struct file *file)
@@ -2452,13 +2510,13 @@ static ssize_t write_debugfs_file(struct file *file, const char __user *buf,
 	struct ubifs_info *c = file->private_data;
 	struct ubifs_debug_info *d = c->dbg;
 
-	if (file->f_path.dentry == d->dump_lprops)
+	if (file->f_path.dentry == d->dfs_dump_lprops)
 		dbg_dump_lprops(c);
-	else if (file->f_path.dentry == d->dump_budg) {
+	else if (file->f_path.dentry == d->dfs_dump_budg) {
 		spin_lock(&c->space_lock);
 		dbg_dump_budg(c);
 		spin_unlock(&c->space_lock);
-	} else if (file->f_path.dentry == d->dump_tnc) {
+	} else if (file->f_path.dentry == d->dfs_dump_tnc) {
 		mutex_lock(&c->tnc_mutex);
 		dbg_dump_tnc(c);
 		mutex_unlock(&c->tnc_mutex);
@@ -2469,7 +2527,7 @@ static ssize_t write_debugfs_file(struct file *file, const char __user *buf,
 	return count;
 }
 
-static const struct file_operations debugfs_fops = {
+static const struct file_operations dfs_fops = {
 	.open = open_debugfs_file,
 	.write = write_debugfs_file,
 	.owner = THIS_MODULE,
@@ -2494,36 +2552,32 @@ int dbg_debugfs_init_fs(struct ubifs_info *c)
 	struct dentry *dent;
 	struct ubifs_debug_info *d = c->dbg;
 
-	sprintf(d->debugfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id);
-	d->debugfs_dir = debugfs_create_dir(d->debugfs_dir_name,
-					      debugfs_rootdir);
-	if (IS_ERR(d->debugfs_dir)) {
-		err = PTR_ERR(d->debugfs_dir);
+	sprintf(d->dfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id);
+	d->dfs_dir = debugfs_create_dir(d->dfs_dir_name, dfs_rootdir);
+	if (IS_ERR(d->dfs_dir)) {
+		err = PTR_ERR(d->dfs_dir);
 		ubifs_err("cannot create \"%s\" debugfs directory, error %d\n",
-			  d->debugfs_dir_name, err);
+			  d->dfs_dir_name, err);
 		goto out;
 	}
 
 	fname = "dump_lprops";
-	dent = debugfs_create_file(fname, S_IWUGO, d->debugfs_dir, c,
-				   &debugfs_fops);
+	dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops);
 	if (IS_ERR(dent))
 		goto out_remove;
-	d->dump_lprops = dent;
+	d->dfs_dump_lprops = dent;
 
 	fname = "dump_budg";
-	dent = debugfs_create_file(fname, S_IWUGO, d->debugfs_dir, c,
-				   &debugfs_fops);
+	dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops);
 	if (IS_ERR(dent))
 		goto out_remove;
-	d->dump_budg = dent;
+	d->dfs_dump_budg = dent;
 
 	fname = "dump_tnc";
-	dent = debugfs_create_file(fname, S_IWUGO, d->debugfs_dir, c,
-				   &debugfs_fops);
+	dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops);
 	if (IS_ERR(dent))
 		goto out_remove;
-	d->dump_tnc = dent;
+	d->dfs_dump_tnc = dent;
 
 	return 0;
 
@@ -2531,7 +2585,7 @@ out_remove:
 	err = PTR_ERR(dent);
 	ubifs_err("cannot create \"%s\" debugfs directory, error %d\n",
 		  fname, err);
-	debugfs_remove_recursive(d->debugfs_dir);
+	debugfs_remove_recursive(d->dfs_dir);
 out:
 	return err;
 }
@@ -2542,7 +2596,7 @@ out:
  */
 void dbg_debugfs_exit_fs(struct ubifs_info *c)
 {
-	debugfs_remove_recursive(c->dbg->debugfs_dir);
+	debugfs_remove_recursive(c->dbg->dfs_dir);
 }
 
 #endif /* CONFIG_UBIFS_FS_DEBUG */
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index 9820d6999f7e..c1cd73b2e06e 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -41,15 +41,17 @@
  * @chk_lpt_wastage: used by LPT tree size checker
  * @chk_lpt_lebs: used by LPT tree size checker
  * @new_nhead_offs: used by LPT tree size checker
- * @new_ihead_lnum: used by debugging to check ihead_lnum
- * @new_ihead_offs: used by debugging to check ihead_offs
+ * @new_ihead_lnum: used by debugging to check @c->ihead_lnum
+ * @new_ihead_offs: used by debugging to check @c->ihead_offs
  *
- * debugfs_dir_name: name of debugfs directory containing this file-system's
- *                   files
- * debugfs_dir: direntry object of the file-system debugfs directory
- * dump_lprops: "dump lprops" debugfs knob
- * dump_budg: "dump budgeting information" debugfs knob
- * dump_tnc: "dump TNC" debugfs knob
+ * @saved_lst: saved lprops statistics (used by 'dbg_save_space_info()')
+ * @saved_free: saved free space (used by 'dbg_save_space_info()')
+ *
+ * dfs_dir_name: name of debugfs directory containing this file-system's files
+ * dfs_dir: direntry object of the file-system debugfs directory
+ * dfs_dump_lprops: "dump lprops" debugfs knob
+ * dfs_dump_budg: "dump budgeting information" debugfs knob
+ * dfs_dump_tnc: "dump TNC" debugfs knob
  */
 struct ubifs_debug_info {
 	void *buf;
@@ -69,11 +71,14 @@ struct ubifs_debug_info {
 	int new_ihead_lnum;
 	int new_ihead_offs;
 
-	char debugfs_dir_name[100];
-	struct dentry *debugfs_dir;
-	struct dentry *dump_lprops;
-	struct dentry *dump_budg;
-	struct dentry *dump_tnc;
+	struct ubifs_lp_stats saved_lst;
+	long long saved_free;
+
+	char dfs_dir_name[100];
+	struct dentry *dfs_dir;
+	struct dentry *dfs_dump_lprops;
+	struct dentry *dfs_dump_budg;
+	struct dentry *dfs_dump_tnc;
 };
 
 #define ubifs_assert(expr) do {                                                \
@@ -297,7 +302,8 @@ int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb,
 		   dbg_znode_callback znode_cb, void *priv);
 
 /* Checking functions */
-
+void dbg_save_space_info(struct ubifs_info *c);
+int dbg_check_space_info(struct ubifs_info *c);
 int dbg_check_lprops(struct ubifs_info *c);
 int dbg_old_index_check_init(struct ubifs_info *c, struct ubifs_zbranch *zroot);
 int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot);
@@ -439,6 +445,8 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
 
 #define dbg_walk_index(c, leaf_cb, znode_cb, priv) 0
 #define dbg_old_index_check_init(c, zroot)         0
+#define dbg_save_space_info(c)                     ({})
+#define dbg_check_space_info(c)                    0
 #define dbg_check_old_index(c, zroot)              0
 #define dbg_check_cats(c)                          0
 #define dbg_check_ltab(c)                          0
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index f448ab1f9c38..f55d523c52bb 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -482,30 +482,29 @@ static int ubifs_dir_release(struct inode *dir, struct file *file)
 }
 
 /**
- * lock_2_inodes - lock two UBIFS inodes.
+ * lock_2_inodes - a wrapper for locking two UBIFS inodes.
  * @inode1: first inode
  * @inode2: second inode
+ *
+ * We do not implement any tricks to guarantee strict lock ordering, because
+ * VFS has already done it for us on the @i_mutex. So this is just a simple
+ * wrapper function.
  */
 static void lock_2_inodes(struct inode *inode1, struct inode *inode2)
 {
-	if (inode1->i_ino < inode2->i_ino) {
-		mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_2);
-		mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_3);
-	} else {
-		mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2);
-		mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_3);
-	}
+	mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1);
+	mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2);
 }
 
 /**
- * unlock_2_inodes - unlock two UBIFS inodes inodes.
+ * unlock_2_inodes - a wrapper for unlocking two UBIFS inodes.
  * @inode1: first inode
  * @inode2: second inode
  */
 static void unlock_2_inodes(struct inode *inode1, struct inode *inode2)
 {
-	mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
 	mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
+	mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
 }
 
 static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
@@ -527,6 +526,8 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
 	dbg_gen("dent '%.*s' to ino %lu (nlink %d) in dir ino %lu",
 		dentry->d_name.len, dentry->d_name.name, inode->i_ino,
 		inode->i_nlink, dir->i_ino);
+	ubifs_assert(mutex_is_locked(&dir->i_mutex));
+	ubifs_assert(mutex_is_locked(&inode->i_mutex));
 	err = dbg_check_synced_i_size(inode);
 	if (err)
 		return err;
@@ -580,6 +581,8 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
 	dbg_gen("dent '%.*s' from ino %lu (nlink %d) in dir ino %lu",
 		dentry->d_name.len, dentry->d_name.name, inode->i_ino,
 		inode->i_nlink, dir->i_ino);
+	ubifs_assert(mutex_is_locked(&dir->i_mutex));
+	ubifs_assert(mutex_is_locked(&inode->i_mutex));
 	err = dbg_check_synced_i_size(inode);
 	if (err)
 		return err;
@@ -667,7 +670,8 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
 
 	dbg_gen("directory '%.*s', ino %lu in dir ino %lu", dentry->d_name.len,
 		dentry->d_name.name, inode->i_ino, dir->i_ino);
-
+	ubifs_assert(mutex_is_locked(&dir->i_mutex));
+	ubifs_assert(mutex_is_locked(&inode->i_mutex));
 	err = check_dir_empty(c, dentry->d_inode);
 	if (err)
 		return err;
@@ -922,59 +926,30 @@ out_budg:
 }
 
 /**
- * lock_3_inodes - lock three UBIFS inodes for rename.
+ * lock_3_inodes - a wrapper for locking three UBIFS inodes.
  * @inode1: first inode
  * @inode2: second inode
  * @inode3: third inode
  *
- * For 'ubifs_rename()', @inode1 may be the same as @inode2 whereas @inode3 may
- * be null.
+ * This function is used for 'ubifs_rename()' and @inode1 may be the same as
+ * @inode2 whereas @inode3 may be %NULL.
+ *
+ * We do not implement any tricks to guarantee strict lock ordering, because
+ * VFS has already done it for us on the @i_mutex. So this is just a simple
+ * wrapper function.
  */
 static void lock_3_inodes(struct inode *inode1, struct inode *inode2,
 			  struct inode *inode3)
 {
-	struct inode *i1, *i2, *i3;
-
-	if (!inode3) {
-		if (inode1 != inode2) {
-			lock_2_inodes(inode1, inode2);
-			return;
-		}
-		mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1);
-		return;
-	}
-
-	if (inode1 == inode2) {
-		lock_2_inodes(inode1, inode3);
-		return;
-	}
-
-	/* 3 different inodes */
-	if (inode1 < inode2) {
-		i3 = inode2;
-		if (inode1 < inode3) {
-			i1 = inode1;
-			i2 = inode3;
-		} else {
-			i1 = inode3;
-			i2 = inode1;
-		}
-	} else {
-		i3 = inode1;
-		if (inode2 < inode3) {
-			i1 = inode2;
-			i2 = inode3;
-		} else {
-			i1 = inode3;
-			i2 = inode2;
-		}
-	}
-	mutex_lock_nested(&ubifs_inode(i1)->ui_mutex, WB_MUTEX_1);
-	lock_2_inodes(i2, i3);
+	mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1);
+	if (inode2 != inode1)
+		mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2);
+	if (inode3)
+		mutex_lock_nested(&ubifs_inode(inode3)->ui_mutex, WB_MUTEX_3);
 }
 
 /**
- * unlock_3_inodes - unlock three UBIFS inodes for rename.
+ * unlock_3_inodes - a wrapper for unlocking three UBIFS inodes for rename.
  * @inode1: first inode
  * @inode2: second inode
  * @inode3: third inode
@@ -982,11 +957,11 @@ static void lock_3_inodes(struct inode *inode1, struct inode *inode2,
 static void unlock_3_inodes(struct inode *inode1, struct inode *inode2,
 			    struct inode *inode3)
 {
-	mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
-	if (inode1 != inode2)
-		mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
 	if (inode3)
 		mutex_unlock(&ubifs_inode(inode3)->ui_mutex);
+	if (inode1 != inode2)
+		mutex_unlock(&ubifs_inode(inode2)->ui_mutex);
+	mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
 }
 
 static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
@@ -1020,6 +995,11 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
 		"dir ino %lu", old_dentry->d_name.len, old_dentry->d_name.name,
 		old_inode->i_ino, old_dir->i_ino, new_dentry->d_name.len,
 		new_dentry->d_name.name, new_dir->i_ino);
+	ubifs_assert(mutex_is_locked(&old_dir->i_mutex));
+	ubifs_assert(mutex_is_locked(&new_dir->i_mutex));
+	if (unlink)
+		ubifs_assert(mutex_is_locked(&new_inode->i_mutex));
+
 
 	if (unlink && is_dir) {
 		err = check_dir_empty(c, new_inode);
@@ -1199,7 +1179,7 @@ int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
 	return 0;
 }
 
-struct inode_operations ubifs_dir_inode_operations = {
+const struct inode_operations ubifs_dir_inode_operations = {
 	.lookup      = ubifs_lookup,
 	.create      = ubifs_create,
 	.link        = ubifs_link,
@@ -1219,7 +1199,7 @@ struct inode_operations ubifs_dir_inode_operations = {
 #endif
 };
 
-struct file_operations ubifs_dir_operations = {
+const struct file_operations ubifs_dir_operations = {
 	.llseek         = ubifs_dir_llseek,
 	.release        = ubifs_dir_release,
 	.read           = generic_read_dir,
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index bf37374567fa..93b6de51f261 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -432,7 +432,6 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
 	int uninitialized_var(err), appending = !!(pos + len > inode->i_size);
 	struct page *page;
 
-
 	ubifs_assert(ubifs_inode(inode)->ui_size == inode->i_size);
 
 	if (unlikely(c->ro_media))
@@ -1541,7 +1540,7 @@ static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
 	return 0;
 }
 
-struct address_space_operations ubifs_file_address_operations = {
+const struct address_space_operations ubifs_file_address_operations = {
 	.readpage       = ubifs_readpage,
 	.writepage      = ubifs_writepage,
 	.write_begin    = ubifs_write_begin,
@@ -1551,7 +1550,7 @@ struct address_space_operations ubifs_file_address_operations = {
 	.releasepage    = ubifs_releasepage,
 };
 
-struct inode_operations ubifs_file_inode_operations = {
+const struct inode_operations ubifs_file_inode_operations = {
 	.setattr     = ubifs_setattr,
 	.getattr     = ubifs_getattr,
 #ifdef CONFIG_UBIFS_FS_XATTR
@@ -1562,14 +1561,14 @@ struct inode_operations ubifs_file_inode_operations = {
 #endif
 };
 
-struct inode_operations ubifs_symlink_inode_operations = {
+const struct inode_operations ubifs_symlink_inode_operations = {
 	.readlink    = generic_readlink,
 	.follow_link = ubifs_follow_link,
 	.setattr     = ubifs_setattr,
 	.getattr     = ubifs_getattr,
 };
 
-struct file_operations ubifs_file_operations = {
+const struct file_operations ubifs_file_operations = {
 	.llseek         = generic_file_llseek,
 	.read           = do_sync_read,
 	.write          = do_sync_write,
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c
index 9832f9abe28e..a711d33b3d3e 100644
--- a/fs/ubifs/gc.c
+++ b/fs/ubifs/gc.c
@@ -31,6 +31,26 @@
  * to be reused. Garbage collection will cause the number of dirty index nodes
  * to grow, however sufficient space is reserved for the index to ensure the
  * commit will never run out of space.
+ *
+ * Notes about dead watermark. At current UBIFS implementation we assume that
+ * LEBs which have less than @c->dead_wm bytes of free + dirty space are full
+ * and not worth garbage-collecting. The dead watermark is one min. I/O unit
+ * size, or min. UBIFS node size, depending on what is greater. Indeed, UBIFS
+ * Garbage Collector has to synchronize the GC head's write buffer before
+ * returning, so this is about wasting one min. I/O unit. However, UBIFS GC can
+ * actually reclaim even very small pieces of dirty space by garbage collecting
+ * enough dirty LEBs, but we do not bother doing this at this implementation.
+ *
+ * Notes about dark watermark. The results of GC work depends on how big are
+ * the UBIFS nodes GC deals with. Large nodes make GC waste more space. Indeed,
+ * if GC move data from LEB A to LEB B and nodes in LEB A are large, GC would
+ * have to waste large pieces of free space at the end of LEB B, because nodes
+ * from LEB A would not fit. And the worst situation is when all nodes are of
+ * maximum size. So dark watermark is the amount of free + dirty space in LEB
+ * which are guaranteed to be reclaimable. If LEB has less space, the GC migh
+ * be unable to reclaim it. So, LEBs with free + dirty greater than dark
+ * watermark are "good" LEBs from GC's point of few. The other LEBs are not so
+ * good, and GC takes extra care when moving them.
  */
 
 #include <linux/pagemap.h>
@@ -381,7 +401,7 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
 
 		/*
 		 * Don't release the LEB until after the next commit, because
-		 * it may contain date which is needed for recovery. So
+		 * it may contain data which is needed for recovery. So
 		 * although we freed this LEB, it will become usable only after
 		 * the commit.
 		 */
@@ -810,8 +830,9 @@ out:
  * ubifs_destroy_idx_gc - destroy idx_gc list.
  * @c: UBIFS file-system description object
  *
- * This function destroys the idx_gc list. It is called when unmounting or
- * remounting read-only so locks are not needed.
+ * This function destroys the @c->idx_gc list. It is called when unmounting
+ * so locks are not needed. Returns zero in case of success and a negative
+ * error code in case of failure.
  */
 void ubifs_destroy_idx_gc(struct ubifs_info *c)
 {
@@ -824,7 +845,6 @@ void ubifs_destroy_idx_gc(struct ubifs_info *c)
 		list_del(&idx_gc->list);
 		kfree(idx_gc);
 	}
-
 }
 
 /**
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index 01682713af69..e8e632a1dcdf 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -29,7 +29,7 @@
  * would have been wasted for padding to the nearest minimal I/O unit boundary.
  * Instead, data first goes to the write-buffer and is flushed when the
  * buffer is full or when it is not used for some time (by timer). This is
- * similarto the mechanism is used by JFFS2.
+ * similar to the mechanism is used by JFFS2.
  *
  * Write-buffers are defined by 'struct ubifs_wbuf' objects and protected by
  * mutexes defined inside these objects. Since sometimes upper-level code
@@ -75,7 +75,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
  * @lnum: logical eraseblock number
  * @offs: offset within the logical eraseblock
  * @quiet: print no messages
- * @chk_crc: indicates whether to always check the CRC
+ * @must_chk_crc: indicates whether to always check the CRC
  *
  * This function checks node magic number and CRC checksum. This function also
  * validates node length to prevent UBIFS from becoming crazy when an attacker
@@ -83,11 +83,17 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
  * node length in the common header could cause UBIFS to read memory outside of
  * allocated buffer when checking the CRC checksum.
  *
- * This function returns zero in case of success %-EUCLEAN in case of bad CRC
- * or magic.
+ * This function may skip data nodes CRC checking if @c->no_chk_data_crc is
+ * true, which is controlled by corresponding UBIFS mount option. However, if
+ * @must_chk_crc is true, then @c->no_chk_data_crc is ignored and CRC is
+ * checked. Similarly, if @c->always_chk_crc is true, @c->no_chk_data_crc is
+ * ignored and CRC is checked.
+ *
+ * This function returns zero in case of success and %-EUCLEAN in case of bad
+ * CRC or magic.
  */
 int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
-		     int offs, int quiet, int chk_crc)
+		     int offs, int quiet, int must_chk_crc)
 {
 	int err = -EINVAL, type, node_len;
 	uint32_t crc, node_crc, magic;
@@ -123,9 +129,9 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
 		   node_len > c->ranges[type].max_len)
 		goto out_len;
 
-	if (!chk_crc && type == UBIFS_DATA_NODE && !c->always_chk_crc)
-		if (c->no_chk_data_crc)
-			return 0;
+	if (!must_chk_crc && type == UBIFS_DATA_NODE && !c->always_chk_crc &&
+	     c->no_chk_data_crc)
+		return 0;
 
 	crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8);
 	node_crc = le32_to_cpu(ch->crc);
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index 9b7c54e0cd2a..a11ca0958a23 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -208,7 +208,7 @@ again:
 	offs = 0;
 
 out:
-	err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs, UBI_SHORTTERM);
+	err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs, wbuf->dtype);
 	if (err)
 		goto out_unlock;
 
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
index dfd2bcece27a..4cdd284dea56 100644
--- a/fs/ubifs/lprops.c
+++ b/fs/ubifs/lprops.c
@@ -635,10 +635,10 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c,
  * @c: UBIFS file-system description object
  * @st: return statistics
  */
-void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *st)
+void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *lst)
 {
 	spin_lock(&c->space_lock);
-	memcpy(st, &c->lst, sizeof(struct ubifs_lp_stats));
+	memcpy(lst, &c->lst, sizeof(struct ubifs_lp_stats));
 	spin_unlock(&c->space_lock);
 }
 
@@ -678,6 +678,9 @@ int ubifs_change_one_lp(struct ubifs_info *c, int lnum, int free, int dirty,
 
 out:
 	ubifs_release_lprops(c);
+	if (err)
+		ubifs_err("cannot change properties of LEB %d, error %d",
+			  lnum, err);
 	return err;
 }
 
@@ -714,6 +717,9 @@ int ubifs_update_one_lp(struct ubifs_info *c, int lnum, int free, int dirty,
 
 out:
 	ubifs_release_lprops(c);
+	if (err)
+		ubifs_err("cannot update properties of LEB %d, error %d",
+			  lnum, err);
 	return err;
 }
 
@@ -737,6 +743,8 @@ int ubifs_read_one_lp(struct ubifs_info *c, int lnum, struct ubifs_lprops *lp)
 	lpp = ubifs_lpt_lookup(c, lnum);
 	if (IS_ERR(lpp)) {
 		err = PTR_ERR(lpp);
+		ubifs_err("cannot read properties of LEB %d, error %d",
+			  lnum, err);
 		goto out;
 	}
 
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index 96ca95707175..3216a1f277f8 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -556,23 +556,23 @@ no_space:
 }
 
 /**
- * next_pnode - find next pnode.
+ * next_pnode_to_dirty - find next pnode to dirty.
  * @c: UBIFS file-system description object
  * @pnode: pnode
  *
- * This function returns the next pnode or %NULL if there are no more pnodes.
+ * This function returns the next pnode to dirty or %NULL if there are no more
+ * pnodes.  Note that pnodes that have never been written (lnum == 0) are
+ * skipped.
  */
-static struct ubifs_pnode *next_pnode(struct ubifs_info *c,
-				      struct ubifs_pnode *pnode)
+static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c,
+					       struct ubifs_pnode *pnode)
 {
 	struct ubifs_nnode *nnode;
 	int iip;
 
 	/* Try to go right */
 	nnode = pnode->parent;
-	iip = pnode->iip + 1;
-	if (iip < UBIFS_LPT_FANOUT) {
-		/* We assume here that LEB zero is never an LPT LEB */
+	for (iip = pnode->iip + 1; iip < UBIFS_LPT_FANOUT; iip++) {
 		if (nnode->nbranch[iip].lnum)
 			return ubifs_get_pnode(c, nnode, iip);
 	}
@@ -583,8 +583,11 @@ static struct ubifs_pnode *next_pnode(struct ubifs_info *c,
 		nnode = nnode->parent;
 		if (!nnode)
 			return NULL;
-		/* We assume here that LEB zero is never an LPT LEB */
-	} while (iip >= UBIFS_LPT_FANOUT || !nnode->nbranch[iip].lnum);
+		for (; iip < UBIFS_LPT_FANOUT; iip++) {
+			if (nnode->nbranch[iip].lnum)
+				break;
+		}
+       } while (iip >= UBIFS_LPT_FANOUT);
 
 	/* Go right */
 	nnode = ubifs_get_nnode(c, nnode, iip);
@@ -593,12 +596,29 @@ static struct ubifs_pnode *next_pnode(struct ubifs_info *c,
 
 	/* Go down to level 1 */
 	while (nnode->level > 1) {
-		nnode = ubifs_get_nnode(c, nnode, 0);
+		for (iip = 0; iip < UBIFS_LPT_FANOUT; iip++) {
+			if (nnode->nbranch[iip].lnum)
+				break;
+		}
+		if (iip >= UBIFS_LPT_FANOUT) {
+			/*
+			 * Should not happen, but we need to keep going
+			 * if it does.
+			 */
+			iip = 0;
+		}
+		nnode = ubifs_get_nnode(c, nnode, iip);
 		if (IS_ERR(nnode))
 			return (void *)nnode;
 	}
 
-	return ubifs_get_pnode(c, nnode, 0);
+	for (iip = 0; iip < UBIFS_LPT_FANOUT; iip++)
+		if (nnode->nbranch[iip].lnum)
+			break;
+	if (iip >= UBIFS_LPT_FANOUT)
+		/* Should not happen, but we need to keep going if it does */
+		iip = 0;
+	return ubifs_get_pnode(c, nnode, iip);
 }
 
 /**
@@ -688,7 +708,7 @@ static int make_tree_dirty(struct ubifs_info *c)
 	pnode = pnode_lookup(c, 0);
 	while (pnode) {
 		do_make_pnode_dirty(c, pnode);
-		pnode = next_pnode(c, pnode);
+		pnode = next_pnode_to_dirty(c, pnode);
 		if (IS_ERR(pnode))
 			return PTR_ERR(pnode);
 	}
diff --git a/fs/ubifs/master.c b/fs/ubifs/master.c
index 71d5493bf565..a88f33801b98 100644
--- a/fs/ubifs/master.c
+++ b/fs/ubifs/master.c
@@ -354,7 +354,7 @@ int ubifs_write_master(struct ubifs_info *c)
 	int err, lnum, offs, len;
 
 	if (c->ro_media)
-		return -EINVAL;
+		return -EROFS;
 
 	lnum = UBIFS_MST_LNUM;
 	offs = c->mst_offs + c->mst_node_alsz;
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c
index 9e6f403f170e..152a7b34a141 100644
--- a/fs/ubifs/orphan.c
+++ b/fs/ubifs/orphan.c
@@ -46,7 +46,7 @@
  * Orphans are accumulated in a rb-tree. When an inode's link count drops to
  * zero, the inode number is added to the rb-tree. It is removed from the tree
  * when the inode is deleted.  Any new orphans that are in the orphan tree when
- * the commit is run, are written to the orphan area in 1 or more orph nodes.
+ * the commit is run, are written to the orphan area in 1 or more orphan nodes.
  * If the orphan area is full, it is consolidated to make space.  There is
  * always enough space because validation prevents the user from creating more
  * than the maximum number of orphans allowed.
@@ -231,7 +231,7 @@ static int tot_avail_orphs(struct ubifs_info *c)
 }
 
 /**
- * do_write_orph_node - write a node
+ * do_write_orph_node - write a node to the orphan head.
  * @c: UBIFS file-system description object
  * @len: length of node
  * @atomic: write atomically
@@ -264,11 +264,11 @@ static int do_write_orph_node(struct ubifs_info *c, int len, int atomic)
 }
 
 /**
- * write_orph_node - write an orph node
+ * write_orph_node - write an orphan node.
  * @c: UBIFS file-system description object
  * @atomic: write atomically
  *
- * This function builds an orph node from the cnext list and writes it to the
+ * This function builds an orphan node from the cnext list and writes it to the
  * orphan head. On success, %0 is returned, otherwise a negative error code
  * is returned.
  */
@@ -326,11 +326,11 @@ static int write_orph_node(struct ubifs_info *c, int atomic)
 }
 
 /**
- * write_orph_nodes - write orph nodes until there are no more to commit
+ * write_orph_nodes - write orphan nodes until there are no more to commit.
  * @c: UBIFS file-system description object
  * @atomic: write atomically
  *
- * This function writes orph nodes for all the orphans to commit. On success,
+ * This function writes orphan nodes for all the orphans to commit. On success,
  * %0 is returned, otherwise a negative error code is returned.
  */
 static int write_orph_nodes(struct ubifs_info *c, int atomic)
@@ -478,14 +478,14 @@ int ubifs_orphan_end_commit(struct ubifs_info *c)
 }
 
 /**
- * clear_orphans - erase all LEBs used for orphans.
+ * ubifs_clear_orphans - erase all LEBs used for orphans.
  * @c: UBIFS file-system description object
  *
  * If recovery is not required, then the orphans from the previous session
  * are not needed. This function locates the LEBs used to record
  * orphans, and un-maps them.
  */
-static int clear_orphans(struct ubifs_info *c)
+int ubifs_clear_orphans(struct ubifs_info *c)
 {
 	int lnum, err;
 
@@ -547,9 +547,9 @@ static int insert_dead_orphan(struct ubifs_info *c, ino_t inum)
  * do_kill_orphans - remove orphan inodes from the index.
  * @c: UBIFS file-system description object
  * @sleb: scanned LEB
- * @last_cmt_no: cmt_no of last orph node read is passed and returned here
+ * @last_cmt_no: cmt_no of last orphan node read is passed and returned here
  * @outofdate: whether the LEB is out of date is returned here
- * @last_flagged: whether the end orph node is encountered
+ * @last_flagged: whether the end orphan node is encountered
  *
  * This function is a helper to the 'kill_orphans()' function. It goes through
  * every orphan node in a LEB and for every inode number recorded, removes
@@ -580,8 +580,8 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
 		/*
 		 * The commit number on the master node may be less, because
 		 * of a failed commit. If there are several failed commits in a
-		 * row, the commit number written on orph nodes will continue to
-		 * increase (because the commit number is adjusted here) even
+		 * row, the commit number written on orphan nodes will continue
+		 * to increase (because the commit number is adjusted here) even
 		 * though the commit number on the master node stays the same
 		 * because the master node has not been re-written.
 		 */
@@ -589,9 +589,9 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
 			c->cmt_no = cmt_no;
 		if (cmt_no < *last_cmt_no && *last_flagged) {
 			/*
-			 * The last orph node had a higher commit number and was
-			 * flagged as the last written for that commit number.
-			 * That makes this orph node, out of date.
+			 * The last orphan node had a higher commit number and
+			 * was flagged as the last written for that commit
+			 * number. That makes this orphan node, out of date.
 			 */
 			if (!first) {
 				ubifs_err("out of order commit number %llu in "
@@ -658,10 +658,10 @@ static int kill_orphans(struct ubifs_info *c)
 	/*
 	 * Orph nodes always start at c->orph_first and are written to each
 	 * successive LEB in turn. Generally unused LEBs will have been unmapped
-	 * but may contain out of date orph nodes if the unmap didn't go
-	 * through. In addition, the last orph node written for each commit is
+	 * but may contain out of date orphan nodes if the unmap didn't go
+	 * through. In addition, the last orphan node written for each commit is
 	 * marked (top bit of orph->cmt_no is set to 1). It is possible that
-	 * there are orph nodes from the next commit (i.e. the commit did not
+	 * there are orphan nodes from the next commit (i.e. the commit did not
 	 * complete successfully). In that case, no orphans will have been lost
 	 * due to the way that orphans are written, and any orphans added will
 	 * be valid orphans anyway and so can be deleted.
@@ -718,7 +718,7 @@ int ubifs_mount_orphans(struct ubifs_info *c, int unclean, int read_only)
 	if (unclean)
 		err = kill_orphans(c);
 	else if (!read_only)
-		err = clear_orphans(c);
+		err = ubifs_clear_orphans(c);
 
 	return err;
 }
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 89556ee72518..1182b66a5491 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -397,6 +397,7 @@ static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf)
 	buf->f_namelen = UBIFS_MAX_NLEN;
 	buf->f_fsid.val[0] = le32_to_cpu(uuid[0]) ^ le32_to_cpu(uuid[2]);
 	buf->f_fsid.val[1] = le32_to_cpu(uuid[1]) ^ le32_to_cpu(uuid[3]);
+	ubifs_assert(buf->f_bfree <= c->block_cnt);
 	return 0;
 }
 
@@ -432,33 +433,24 @@ static int ubifs_sync_fs(struct super_block *sb, int wait)
 	int i, err;
 	struct ubifs_info *c = sb->s_fs_info;
 	struct writeback_control wbc = {
-		.sync_mode   = wait ? WB_SYNC_ALL : WB_SYNC_NONE,
+		.sync_mode   = WB_SYNC_ALL,
 		.range_start = 0,
 		.range_end   = LLONG_MAX,
 		.nr_to_write = LONG_MAX,
 	};
 
 	/*
-	 * Note by akpm about WB_SYNC_NONE used above: zero @wait is just an
-	 * advisory thing to help the file system shove lots of data into the
-	 * queues. If some gets missed then it'll be picked up on the second
+	 * Zero @wait is just an advisory thing to help the file system shove
+	 * lots of data into the queues, and there will be the second
 	 * '->sync_fs()' call, with non-zero @wait.
 	 */
+	if (!wait)
+		return 0;
 
 	if (sb->s_flags & MS_RDONLY)
 		return 0;
 
 	/*
-	 * Synchronize write buffers, because 'ubifs_run_commit()' does not
-	 * do this if it waits for an already running commit.
-	 */
-	for (i = 0; i < c->jhead_cnt; i++) {
-		err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
-		if (err)
-			return err;
-	}
-
-	/*
 	 * VFS calls '->sync_fs()' before synchronizing all dirty inodes and
 	 * pages, so synchronize them first, then commit the journal. Strictly
 	 * speaking, it is not necessary to commit the journal here,
@@ -469,6 +461,16 @@ static int ubifs_sync_fs(struct super_block *sb, int wait)
 	 */
 	generic_sync_sb_inodes(sb, &wbc);
 
+	/*
+	 * Synchronize write buffers, because 'ubifs_run_commit()' does not
+	 * do this if it waits for an already running commit.
+	 */
+	for (i = 0; i < c->jhead_cnt; i++) {
+		err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
+		if (err)
+			return err;
+	}
+
 	err = ubifs_run_commit(c);
 	if (err)
 		return err;
@@ -572,15 +574,8 @@ static int init_constants_early(struct ubifs_info *c)
 	c->ranges[UBIFS_IDX_NODE].max_len = INT_MAX;
 
 	/*
-	 * Initialize dead and dark LEB space watermarks.
-	 *
-	 * Dead space is the space which cannot be used. Its watermark is
-	 * equivalent to min. I/O unit or minimum node size if it is greater
-	 * then min. I/O unit.
-	 *
-	 * Dark space is the space which might be used, or might not, depending
-	 * on which node should be written to the LEB. Its watermark is
-	 * equivalent to maximum UBIFS node size.
+	 * Initialize dead and dark LEB space watermarks. See gc.c for comments
+	 * about these values.
 	 */
 	c->dead_wm = ALIGN(MIN_WRITE_SZ, c->min_io_size);
 	c->dark_wm = ALIGN(UBIFS_MAX_NODE_SZ, c->min_io_size);
@@ -741,12 +736,12 @@ static void init_constants_master(struct ubifs_info *c)
  * take_gc_lnum - reserve GC LEB.
  * @c: UBIFS file-system description object
  *
- * This function ensures that the LEB reserved for garbage collection is
- * unmapped and is marked as "taken" in lprops. We also have to set free space
- * to LEB size and dirty space to zero, because lprops may contain out-of-date
- * information if the file-system was un-mounted before it has been committed.
- * This function returns zero in case of success and a negative error code in
- * case of failure.
+ * This function ensures that the LEB reserved for garbage collection is marked
+ * as "taken" in lprops. We also have to set free space to LEB size and dirty
+ * space to zero, because lprops may contain out-of-date information if the
+ * file-system was un-mounted before it has been committed. This function
+ * returns zero in case of success and a negative error code in case of
+ * failure.
  */
 static int take_gc_lnum(struct ubifs_info *c)
 {
@@ -757,10 +752,6 @@ static int take_gc_lnum(struct ubifs_info *c)
 		return -EINVAL;
 	}
 
-	err = ubifs_leb_unmap(c, c->gc_lnum);
-	if (err)
-		return err;
-
 	/* And we have to tell lprops that this LEB is taken */
 	err = ubifs_change_one_lp(c, c->gc_lnum, c->leb_size, 0,
 				  LPROPS_TAKEN, 0, 0);
@@ -966,13 +957,16 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
 
 		token = match_token(p, tokens, args);
 		switch (token) {
+		/*
+		 * %Opt_fast_unmount and %Opt_norm_unmount options are ignored.
+		 * We accepte them in order to be backware-compatible. But this
+		 * should be removed at some point.
+		 */
 		case Opt_fast_unmount:
 			c->mount_opts.unmount_mode = 2;
-			c->fast_unmount = 1;
 			break;
 		case Opt_norm_unmount:
 			c->mount_opts.unmount_mode = 1;
-			c->fast_unmount = 0;
 			break;
 		case Opt_bulk_read:
 			c->mount_opts.bulk_read = 2;
@@ -1094,12 +1088,7 @@ static int check_free_space(struct ubifs_info *c)
 		ubifs_err("insufficient free space to mount in read/write mode");
 		dbg_dump_budg(c);
 		dbg_dump_lprops(c);
-		/*
-		 * We return %-EINVAL instead of %-ENOSPC because it seems to
-		 * be the closest error code mentioned in the mount function
-		 * documentation.
-		 */
-		return -EINVAL;
+		return -ENOSPC;
 	}
 	return 0;
 }
@@ -1286,10 +1275,19 @@ static int mount_ubifs(struct ubifs_info *c)
 			if (err)
 				goto out_orphans;
 			err = ubifs_rcvry_gc_commit(c);
-		} else
+		} else {
 			err = take_gc_lnum(c);
-		if (err)
-			goto out_orphans;
+			if (err)
+				goto out_orphans;
+
+			/*
+			 * GC LEB may contain garbage if there was an unclean
+			 * reboot, and it should be un-mapped.
+			 */
+			err = ubifs_leb_unmap(c, c->gc_lnum);
+			if (err)
+				return err;
+		}
 
 		err = dbg_check_lprops(c);
 		if (err)
@@ -1298,6 +1296,16 @@ static int mount_ubifs(struct ubifs_info *c)
 		err = ubifs_recover_size(c);
 		if (err)
 			goto out_orphans;
+	} else {
+		/*
+		 * Even if we mount read-only, we have to set space in GC LEB
+		 * to proper value because this affects UBIFS free space
+		 * reporting. We do not want to have a situation when
+		 * re-mounting from R/O to R/W changes amount of free space.
+		 */
+		err = take_gc_lnum(c);
+		if (err)
+			goto out_orphans;
 	}
 
 	spin_lock(&ubifs_infos_lock);
@@ -1310,14 +1318,17 @@ static int mount_ubifs(struct ubifs_info *c)
 		else {
 			c->need_recovery = 0;
 			ubifs_msg("recovery completed");
+			/* GC LEB has to be empty and taken at this point */
+			ubifs_assert(c->lst.taken_empty_lebs == 1);
 		}
-	}
+	} else
+		ubifs_assert(c->lst.taken_empty_lebs == 1);
 
-	err = dbg_debugfs_init_fs(c);
+	err = dbg_check_filesystem(c);
 	if (err)
 		goto out_infos;
 
-	err = dbg_check_filesystem(c);
+	err = dbg_debugfs_init_fs(c);
 	if (err)
 		goto out_infos;
 
@@ -1351,7 +1362,6 @@ static int mount_ubifs(struct ubifs_info *c)
 	       c->uuid[4], c->uuid[5], c->uuid[6], c->uuid[7],
 	       c->uuid[8], c->uuid[9], c->uuid[10], c->uuid[11],
 	       c->uuid[12], c->uuid[13], c->uuid[14], c->uuid[15]);
-	dbg_msg("fast unmount:        %d", c->fast_unmount);
 	dbg_msg("big_lpt              %d", c->big_lpt);
 	dbg_msg("log LEBs:            %d (%d - %d)",
 		c->log_lebs, UBIFS_LOG_LNUM, c->log_last);
@@ -1475,10 +1485,8 @@ static int ubifs_remount_rw(struct ubifs_info *c)
 {
 	int err, lnum;
 
-	if (c->ro_media)
-		return -EINVAL;
-
 	mutex_lock(&c->umount_mutex);
+	dbg_save_space_info(c);
 	c->remounting_rw = 1;
 	c->always_chk_crc = 1;
 
@@ -1514,6 +1522,12 @@ static int ubifs_remount_rw(struct ubifs_info *c)
 		err = ubifs_recover_inl_heads(c, c->sbuf);
 		if (err)
 			goto out;
+	} else {
+		/* A readonly mount is not allowed to have orphans */
+		ubifs_assert(c->tot_orphans == 0);
+		err = ubifs_clear_orphans(c);
+		if (err)
+			goto out;
 	}
 
 	if (!(c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY))) {
@@ -1569,7 +1583,7 @@ static int ubifs_remount_rw(struct ubifs_info *c)
 	if (c->need_recovery)
 		err = ubifs_rcvry_gc_commit(c);
 	else
-		err = take_gc_lnum(c);
+		err = ubifs_leb_unmap(c, c->gc_lnum);
 	if (err)
 		goto out;
 
@@ -1582,8 +1596,9 @@ static int ubifs_remount_rw(struct ubifs_info *c)
 	c->vfs_sb->s_flags &= ~MS_RDONLY;
 	c->remounting_rw = 0;
 	c->always_chk_crc = 0;
+	err = dbg_check_space_info(c);
 	mutex_unlock(&c->umount_mutex);
-	return 0;
+	return err;
 
 out:
 	vfree(c->orph_buf);
@@ -1603,43 +1618,18 @@ out:
 }
 
 /**
- * commit_on_unmount - commit the journal when un-mounting.
- * @c: UBIFS file-system description object
- *
- * This function is called during un-mounting and re-mounting, and it commits
- * the journal unless the "fast unmount" mode is enabled.
- */
-static void commit_on_unmount(struct ubifs_info *c)
-{
-	struct super_block *sb = c->vfs_sb;
-	long long bud_bytes;
-
-	/*
-	 * This function is called before the background thread is stopped, so
-	 * we may race with ongoing commit, which means we have to take
-	 * @c->bud_lock to access @c->bud_bytes.
-	 */
-	spin_lock(&c->buds_lock);
-	bud_bytes = c->bud_bytes;
-	spin_unlock(&c->buds_lock);
-
-	if (!c->fast_unmount && !(sb->s_flags & MS_RDONLY) && bud_bytes)
-		ubifs_run_commit(c);
-}
-
-/**
  * ubifs_remount_ro - re-mount in read-only mode.
  * @c: UBIFS file-system description object
  *
- * We rely on VFS to have stopped writing. Possibly the background thread could
- * be running a commit, however kthread_stop will wait in that case.
+ * We assume VFS has stopped writing. Possibly the background thread could be
+ * running a commit, however kthread_stop will wait in that case.
  */
 static void ubifs_remount_ro(struct ubifs_info *c)
 {
 	int i, err;
 
 	ubifs_assert(!c->need_recovery);
-	commit_on_unmount(c);
+	ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY));
 
 	mutex_lock(&c->umount_mutex);
 	if (c->bgt) {
@@ -1647,27 +1637,29 @@ static void ubifs_remount_ro(struct ubifs_info *c)
 		c->bgt = NULL;
 	}
 
+	dbg_save_space_info(c);
+
 	for (i = 0; i < c->jhead_cnt; i++) {
 		ubifs_wbuf_sync(&c->jheads[i].wbuf);
 		del_timer_sync(&c->jheads[i].wbuf.timer);
 	}
 
-	if (!c->ro_media) {
-		c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY);
-		c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS);
-		c->mst_node->gc_lnum = cpu_to_le32(c->gc_lnum);
-		err = ubifs_write_master(c);
-		if (err)
-			ubifs_ro_mode(c, err);
-	}
+	c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY);
+	c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS);
+	c->mst_node->gc_lnum = cpu_to_le32(c->gc_lnum);
+	err = ubifs_write_master(c);
+	if (err)
+		ubifs_ro_mode(c, err);
 
-	ubifs_destroy_idx_gc(c);
 	free_wbufs(c);
 	vfree(c->orph_buf);
 	c->orph_buf = NULL;
 	vfree(c->ileb_buf);
 	c->ileb_buf = NULL;
 	ubifs_lpt_free(c, 1);
+	err = dbg_check_space_info(c);
+	if (err)
+		ubifs_ro_mode(c, err);
 	mutex_unlock(&c->umount_mutex);
 }
 
@@ -1760,11 +1752,20 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 	}
 
 	if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
+		if (c->ro_media) {
+			ubifs_msg("cannot re-mount due to prior errors");
+			return -EROFS;
+		}
 		err = ubifs_remount_rw(c);
 		if (err)
 			return err;
-	} else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY))
+	} else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {
+		if (c->ro_media) {
+			ubifs_msg("cannot re-mount due to prior errors");
+			return -EROFS;
+		}
 		ubifs_remount_ro(c);
+	}
 
 	if (c->bulk_read == 1)
 		bu_init(c);
@@ -1774,10 +1775,11 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 		c->bu.buf = NULL;
 	}
 
+	ubifs_assert(c->lst.taken_empty_lebs == 1);
 	return 0;
 }
 
-struct super_operations ubifs_super_operations = {
+const struct super_operations ubifs_super_operations = {
 	.alloc_inode   = ubifs_alloc_inode,
 	.destroy_inode = ubifs_destroy_inode,
 	.put_super     = ubifs_put_super,
@@ -2044,15 +2046,6 @@ out_close:
 
 static void ubifs_kill_sb(struct super_block *sb)
 {
-	struct ubifs_info *c = sb->s_fs_info;
-
-	/*
-	 * We do 'commit_on_unmount()' here instead of 'ubifs_put_super()'
-	 * in order to be outside BKL.
-	 */
-	if (sb->s_root)
-		commit_on_unmount(c);
-	/* The un-mount routine is actually done in put_super() */
 	generic_shutdown_super(sb);
 }
 
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index f7e36f545527..fa28a84c6a1b 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -443,6 +443,11 @@ static int tnc_read_node_nm(struct ubifs_info *c, struct ubifs_zbranch *zbr,
  * This function performs that same function as ubifs_read_node except that
  * it does not require that there is actually a node present and instead
  * the return code indicates if a node was read.
+ *
+ * Note, this function does not check CRC of data nodes if @c->no_chk_data_crc
+ * is true (it is controlled by corresponding mount option). However, if
+ * @c->always_chk_crc is true, @c->no_chk_data_crc is ignored and CRC is always
+ * checked.
  */
 static int try_read_node(const struct ubifs_info *c, void *buf, int type,
 			 int len, int lnum, int offs)
@@ -470,9 +475,8 @@ static int try_read_node(const struct ubifs_info *c, void *buf, int type,
 	if (node_len != len)
 		return 0;
 
-	if (type == UBIFS_DATA_NODE && !c->always_chk_crc)
-		if (c->no_chk_data_crc)
-			return 0;
+	if (type == UBIFS_DATA_NODE && !c->always_chk_crc && c->no_chk_data_crc)
+		return 1;
 
 	crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8);
 	node_crc = le32_to_cpu(ch->crc);
@@ -1506,7 +1510,7 @@ out:
  *
  * Note, if the bulk-read buffer length (@bu->buf_len) is known, this function
  * makes sure bulk-read nodes fit the buffer. Otherwise, this function prepares
- * maxumum possible amount of nodes for bulk-read.
+ * maximum possible amount of nodes for bulk-read.
  */
 int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu)
 {
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index fc2a4cc66d03..039a68bee29a 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -426,9 +426,9 @@ struct ubifs_unclean_leb {
  * LEB properties flags.
  *
  * LPROPS_UNCAT: not categorized
- * LPROPS_DIRTY: dirty > 0, not index
+ * LPROPS_DIRTY: dirty > free, dirty >= @c->dead_wm, not index
  * LPROPS_DIRTY_IDX: dirty + free > @c->min_idx_node_sze and index
- * LPROPS_FREE: free > 0, not empty, not index
+ * LPROPS_FREE: free > 0, dirty < @c->dead_wm, not empty, not index
  * LPROPS_HEAP_CNT: number of heaps used for storing categorized LEBs
  * LPROPS_EMPTY: LEB is empty, not taken
  * LPROPS_FREEABLE: free + dirty == leb_size, not index, not taken
@@ -961,7 +961,6 @@ struct ubifs_debug_info;
  * @cs_lock: commit state lock
  * @cmt_wq: wait queue to sleep on if the log is full and a commit is running
  *
- * @fast_unmount: do not run journal commit before un-mounting
  * @big_lpt: flag that LPT is too big to write whole during commit
  * @no_chk_data_crc: do not check CRCs when reading data nodes (except during
  *                   recovery)
@@ -1202,7 +1201,6 @@ struct ubifs_info {
 	spinlock_t cs_lock;
 	wait_queue_head_t cmt_wq;
 
-	unsigned int fast_unmount:1;
 	unsigned int big_lpt:1;
 	unsigned int no_chk_data_crc:1;
 	unsigned int bulk_read:1;
@@ -1405,13 +1403,13 @@ extern struct list_head ubifs_infos;
 extern spinlock_t ubifs_infos_lock;
 extern atomic_long_t ubifs_clean_zn_cnt;
 extern struct kmem_cache *ubifs_inode_slab;
-extern struct super_operations ubifs_super_operations;
-extern struct address_space_operations ubifs_file_address_operations;
-extern struct file_operations ubifs_file_operations;
-extern struct inode_operations ubifs_file_inode_operations;
-extern struct file_operations ubifs_dir_operations;
-extern struct inode_operations ubifs_dir_inode_operations;
-extern struct inode_operations ubifs_symlink_inode_operations;
+extern const struct super_operations ubifs_super_operations;
+extern const struct address_space_operations ubifs_file_address_operations;
+extern const struct file_operations ubifs_file_operations;
+extern const struct inode_operations ubifs_file_inode_operations;
+extern const struct file_operations ubifs_dir_operations;
+extern const struct inode_operations ubifs_dir_inode_operations;
+extern const struct inode_operations ubifs_symlink_inode_operations;
 extern struct backing_dev_info ubifs_backing_dev_info;
 extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
 
@@ -1428,7 +1426,7 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
 int ubifs_write_node(struct ubifs_info *c, void *node, int len, int lnum,
 		     int offs, int dtype);
 int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
-		     int offs, int quiet, int chk_crc);
+		     int offs, int quiet, int must_chk_crc);
 void ubifs_prepare_node(struct ubifs_info *c, void *buf, int len, int pad);
 void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last);
 int ubifs_io_init(struct ubifs_info *c);
@@ -1495,6 +1493,7 @@ void ubifs_release_ino_dirty(struct ubifs_info *c, struct inode *inode,
 void ubifs_cancel_ino_op(struct ubifs_info *c, struct inode *inode,
 			 struct ubifs_budget_req *req);
 long long ubifs_get_free_space(struct ubifs_info *c);
+long long ubifs_get_free_space_nolock(struct ubifs_info *c);
 int ubifs_calc_min_idx_lebs(struct ubifs_info *c);
 void ubifs_convert_page_budget(struct ubifs_info *c);
 long long ubifs_reported_space(const struct ubifs_info *c, long long free);
@@ -1603,6 +1602,7 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum);
 int ubifs_orphan_start_commit(struct ubifs_info *c);
 int ubifs_orphan_end_commit(struct ubifs_info *c);
 int ubifs_mount_orphans(struct ubifs_info *c, int unclean, int read_only);
+int ubifs_clear_orphans(struct ubifs_info *c);
 
 /* lpt.c */
 int ubifs_calc_lpt_geom(struct ubifs_info *c);
@@ -1646,7 +1646,7 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c,
 					   const struct ubifs_lprops *lp,
 					   int free, int dirty, int flags,
 					   int idx_gc_cnt);
-void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *stats);
+void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *lst);
 void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops,
 		      int cat);
 void ubifs_replace_cat(struct ubifs_info *c, struct ubifs_lprops *old_lprops,
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index 2ed035354c26..a608e72fa405 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -371,7 +371,11 @@ xfs_quiesce_attr(
 	/* flush inodes and push all remaining buffers out to disk */
 	xfs_quiesce_fs(mp);
 
-	ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0);
+	/*
+	 * Just warn here till VFS can correctly support
+	 * read-only remount without racing.
+	 */
+	WARN_ON(atomic_read(&mp->m_active_trans) != 0);
 
 	/* Push the superblock and write an unmount record */
 	error = xfs_log_sbcount(mp, 1);
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index b4c1ee713492..f8278cfcc1d3 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -55,17 +55,11 @@ xfs_swapext(
 	struct file	*file, *target_file;
 	int		error = 0;
 
-	sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL);
-	if (!sxp) {
-		error = XFS_ERROR(ENOMEM);
-		goto out;
-	}
-
 	/* Pull information for the target fd */
 	file = fget((int)sxp->sx_fdtarget);
 	if (!file) {
 		error = XFS_ERROR(EINVAL);
-		goto out_free_sxp;
+		goto out;
 	}
 
 	if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) {
@@ -109,8 +103,6 @@ xfs_swapext(
 	fput(target_file);
  out_put_file:
 	fput(file);
- out_free_sxp:
-	kmem_free(sxp);
  out:
 	return error;
 }
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 35cca98bd94c..b1047de2fffd 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -70,16 +70,21 @@ STATIC void	xlog_recover_check_summary(xlog_t *);
 xfs_buf_t *
 xlog_get_bp(
 	xlog_t		*log,
-	int		num_bblks)
+	int		nbblks)
 {
-	ASSERT(num_bblks > 0);
+	if (nbblks <= 0 || nbblks > log->l_logBBsize) {
+		xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks);
+		XFS_ERROR_REPORT("xlog_get_bp(1)",
+				 XFS_ERRLEVEL_HIGH, log->l_mp);
+		return NULL;
+	}
 
 	if (log->l_sectbb_log) {
-		if (num_bblks > 1)
-			num_bblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1);
-		num_bblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, num_bblks);
+		if (nbblks > 1)
+			nbblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1);
+		nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
 	}
-	return xfs_buf_get_noaddr(BBTOB(num_bblks), log->l_mp->m_logdev_targp);
+	return xfs_buf_get_noaddr(BBTOB(nbblks), log->l_mp->m_logdev_targp);
 }
 
 void
@@ -102,6 +107,13 @@ xlog_bread(
 {
 	int		error;
 
+	if (nbblks <= 0 || nbblks > log->l_logBBsize) {
+		xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks);
+		XFS_ERROR_REPORT("xlog_bread(1)",
+				 XFS_ERRLEVEL_HIGH, log->l_mp);
+		return EFSCORRUPTED;
+	}
+
 	if (log->l_sectbb_log) {
 		blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no);
 		nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
@@ -139,6 +151,13 @@ xlog_bwrite(
 {
 	int		error;
 
+	if (nbblks <= 0 || nbblks > log->l_logBBsize) {
+		xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks);
+		XFS_ERROR_REPORT("xlog_bwrite(1)",
+				 XFS_ERRLEVEL_HIGH, log->l_mp);
+		return EFSCORRUPTED;
+	}
+
 	if (log->l_sectbb_log) {
 		blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no);
 		nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
diff --git a/include/acpi/pdc_intel.h b/include/acpi/pdc_intel.h
index e72bfdd887f9..552637b0d051 100644
--- a/include/acpi/pdc_intel.h
+++ b/include/acpi/pdc_intel.h
@@ -14,6 +14,7 @@
 #define ACPI_PDC_SMP_T_SWCOORD		(0x0080)
 #define ACPI_PDC_C_C1_FFH		(0x0100)
 #define ACPI_PDC_C_C2C3_FFH		(0x0200)
+#define ACPI_PDC_SMP_P_HWCOORD		(0x0800)
 
 #define ACPI_PDC_EST_CAPABILITY_SMP	(ACPI_PDC_SMP_C1PT | \
 					 ACPI_PDC_C_C1_HALT | \
@@ -22,6 +23,7 @@
 #define ACPI_PDC_EST_CAPABILITY_SWSMP	(ACPI_PDC_SMP_C1PT | \
 					 ACPI_PDC_C_C1_HALT | \
 					 ACPI_PDC_SMP_P_SWCOORD | \
+					 ACPI_PDC_SMP_P_HWCOORD | \
 					 ACPI_PDC_P_FFH)
 
 #define ACPI_PDC_C_CAPABILITY_SMP	(ACPI_PDC_SMP_C2C3  | \
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 2124c063a7ef..b97cdc516a8f 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -90,7 +90,6 @@ header-y += if_ppp.h
 header-y += if_slip.h
 header-y += if_strip.h
 header-y += if_tun.h
-header-y += if_tunnel.h
 header-y += in_route.h
 header-y += ioctl.h
 header-y += ip6_tunnel.h
@@ -236,6 +235,7 @@ unifdef-y += if_phonet.h
 unifdef-y += if_pppol2tp.h
 unifdef-y += if_pppox.h
 unifdef-y += if_tr.h
+unifdef-y += if_tunnel.h
 unifdef-y += if_vlan.h
 unifdef-y += igmp.h
 unifdef-y += inet_diag.h
diff --git a/include/linux/aio_abi.h b/include/linux/aio_abi.h
index 9e0172931315..2c8731664180 100644
--- a/include/linux/aio_abi.h
+++ b/include/linux/aio_abi.h
@@ -27,6 +27,7 @@
 #ifndef __LINUX__AIO_ABI_H
 #define __LINUX__AIO_ABI_H
 
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
 typedef unsigned long	aio_context_t;
diff --git a/include/linux/async.h b/include/linux/async.h
index c4ecacd0b327..68a9530196f2 100644
--- a/include/linux/async.h
+++ b/include/linux/async.h
@@ -17,9 +17,11 @@ typedef u64 async_cookie_t;
 typedef void (async_func_ptr) (void *data, async_cookie_t cookie);
 
 extern async_cookie_t async_schedule(async_func_ptr *ptr, void *data);
-extern async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *list);
+extern async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data,
+					    struct list_head *list);
 extern void async_synchronize_full(void);
-extern void async_synchronize_full_special(struct list_head *list);
+extern void async_synchronize_full_domain(struct list_head *list);
 extern void async_synchronize_cookie(async_cookie_t cookie);
-extern void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *list);
+extern void async_synchronize_cookie_domain(async_cookie_t cookie,
+					    struct list_head *list);
 
diff --git a/include/linux/ata.h b/include/linux/ata.h
index a53318b8cbd0..08a86d5cdf1b 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -731,12 +731,17 @@ static inline int ata_id_current_chs_valid(const u16 *id)
 
 static inline int ata_id_is_cfa(const u16 *id)
 {
-	if (id[ATA_ID_CONFIG] == 0x848A)	/* Standard CF */
+	if (id[ATA_ID_CONFIG] == 0x848A)	/* Traditional CF */
 		return 1;
-	/* Could be CF hiding as standard ATA */
-	if (ata_id_major_version(id) >= 3 &&
-	    id[ATA_ID_COMMAND_SET_1] != 0xFFFF &&
-	   (id[ATA_ID_COMMAND_SET_1] & (1 << 2)))
+	/*
+	 * CF specs don't require specific value in the word 0 anymore and yet
+	 * they forbid to report the ATA version in the word 80 and require the
+	 * CFA feature set support to be indicated in the word 83 in this case.
+	 * Unfortunately, some cards only follow either of this requirements,
+	 * and while those that don't indicate CFA feature support need some
+	 * sort of quirk list, it seems impractical for the ones that do...
+	 */
+	if ((id[ATA_ID_COMMAND_SET_2] & 0xC004) == 0x4004)
 		return 1;
 	return 0;
 }
diff --git a/include/linux/atalk.h b/include/linux/atalk.h
index e9ebac2e2ecc..d34c187432ed 100644
--- a/include/linux/atalk.h
+++ b/include/linux/atalk.h
@@ -1,6 +1,7 @@
 #ifndef __LINUX_ATALK_H__
 #define __LINUX_ATALK_H__
 
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
 /*
diff --git a/include/linux/atmbr2684.h b/include/linux/atmbr2684.h
index 52bf72affbba..fdb2629b6189 100644
--- a/include/linux/atmbr2684.h
+++ b/include/linux/atmbr2684.h
@@ -1,6 +1,7 @@
 #ifndef _LINUX_ATMBR2684_H
 #define _LINUX_ATMBR2684_H
 
+#include <linux/types.h>
 #include <linux/atm.h>
 #include <linux/if.h>		/* For IFNAMSIZ */
 
diff --git a/include/linux/auto_fs4.h b/include/linux/auto_fs4.h
index 55fa478bd639..8b49ac48a5b7 100644
--- a/include/linux/auto_fs4.h
+++ b/include/linux/auto_fs4.h
@@ -12,6 +12,7 @@
 #define _LINUX_AUTO_FS4_H
 
 /* Include common v3 definitions */
+#include <linux/types.h>
 #include <linux/auto_fs.h>
 
 /* autofs v4 definitions */
diff --git a/include/linux/bfs_fs.h b/include/linux/bfs_fs.h
index 8ed6dfdcd783..1c0b355aa515 100644
--- a/include/linux/bfs_fs.h
+++ b/include/linux/bfs_fs.h
@@ -6,6 +6,8 @@
 #ifndef _LINUX_BFS_FS_H
 #define _LINUX_BFS_FS_H
 
+#include <linux/types.h>
+
 #define BFS_BSIZE_BITS		9
 #define BFS_BSIZE		(1<<BFS_BSIZE_BITS)
 
@@ -17,7 +19,6 @@
 #define BFS_VDIR 2L
 #define BFS_VREG 1L
 
-
 /* BFS inode layout on disk */
 struct bfs_inode {
 	__le16 i_ino;
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 0942765cf8c0..2aa283ab062b 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -451,12 +451,13 @@ extern struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly;
 
 #ifdef CONFIG_HIGHMEM
 /*
- * remember to add offset! and never ever reenable interrupts between a
- * bvec_kmap_irq and bvec_kunmap_irq!!
+ * remember never ever reenable interrupts between a bvec_kmap_irq and
+ * bvec_kunmap_irq!
  *
  * This function MUST be inlined - it plays with the CPU interrupt flags.
  */
-static inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags)
+static __always_inline char *bvec_kmap_irq(struct bio_vec *bvec,
+		unsigned long *flags)
 {
 	unsigned long addr;
 
@@ -472,7 +473,8 @@ static inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags)
 	return (char *) addr + bvec->bv_offset;
 }
 
-static inline void bvec_kunmap_irq(char *buffer, unsigned long *flags)
+static __always_inline void bvec_kunmap_irq(char *buffer,
+		unsigned long *flags)
 {
 	unsigned long ptr = (unsigned long) buffer & PAGE_MASK;
 
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index d08c4b8219a6..dcaa0fd84b02 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -455,7 +455,7 @@ struct request_queue
 
 #define QUEUE_FLAG_DEFAULT	((1 << QUEUE_FLAG_IO_STAT) |		\
 				 (1 << QUEUE_FLAG_CLUSTER) |		\
-				  1 << QUEUE_FLAG_STACKABLE)
+				 (1 << QUEUE_FLAG_STACKABLE))
 
 static inline int queue_is_locked(struct request_queue *q)
 {
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 1dba3493d520..25379cba2370 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -1,6 +1,7 @@
 #ifndef BLKTRACE_H
 #define BLKTRACE_H
 
+#include <linux/types.h>
 #ifdef __KERNEL__
 #include <linux/blkdev.h>
 #include <linux/relay.h>
diff --git a/include/linux/can/bcm.h b/include/linux/can/bcm.h
index 7f293273c444..1432b278c52d 100644
--- a/include/linux/can/bcm.h
+++ b/include/linux/can/bcm.h
@@ -14,6 +14,8 @@
 #ifndef CAN_BCM_H
 #define CAN_BCM_H
 
+#include <linux/types.h>
+
 /**
  * struct bcm_msg_head - head of messages to/from the broadcast manager
  * @opcode:    opcode, see enum below.
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 02bdb768d43b..1b9872556131 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -69,10 +69,6 @@ typedef struct __user_cap_data_struct {
 #define VFS_CAP_U32             VFS_CAP_U32_2
 #define VFS_CAP_REVISION	VFS_CAP_REVISION_2
 
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
-extern int file_caps_enabled;
-#endif
-
 struct vfs_cap_data {
 	__le32 magic_etc;            /* Little endian */
 	struct {
@@ -96,6 +92,10 @@ struct vfs_cap_data {
 #define _KERNEL_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3
 #define _KERNEL_CAPABILITY_U32S    _LINUX_CAPABILITY_U32S_3
 
+#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
+extern int file_caps_enabled;
+#endif
+
 typedef struct kernel_cap_struct {
 	__u32 cap[_KERNEL_CAPABILITY_U32S];
 } kernel_cap_t;
diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h
index 0b49e08d3cb0..78e904796622 100644
--- a/include/linux/cdrom.h
+++ b/include/linux/cdrom.h
@@ -11,6 +11,7 @@
 #ifndef	_LINUX_CDROM_H
 #define	_LINUX_CDROM_H
 
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
 /*******************************************************
diff --git a/include/linux/cgroupstats.h b/include/linux/cgroupstats.h
index 4f53abf6855d..3753c33160d1 100644
--- a/include/linux/cgroupstats.h
+++ b/include/linux/cgroupstats.h
@@ -15,6 +15,7 @@
 #ifndef _LINUX_CGROUPSTATS_H
 #define _LINUX_CGROUPSTATS_H
 
+#include <linux/types.h>
 #include <linux/taskstats.h>
 
 /*
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index cea153697ec7..3a1dbba4d3ae 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -36,6 +36,7 @@ enum clock_event_nofitiers {
 	CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
 	CLOCK_EVT_NOTIFY_SUSPEND,
 	CLOCK_EVT_NOTIFY_RESUME,
+	CLOCK_EVT_NOTIFY_CPU_DYING,
 	CLOCK_EVT_NOTIFY_CPU_DEAD,
 };
 
diff --git a/include/linux/dlm_plock.h b/include/linux/dlm_plock.h
index 18d5fdbceb74..2dd21243104f 100644
--- a/include/linux/dlm_plock.h
+++ b/include/linux/dlm_plock.h
@@ -9,6 +9,8 @@
 #ifndef __DLM_PLOCK_DOT_H__
 #define __DLM_PLOCK_DOT_H__
 
+#include <linux/types.h>
+
 #define DLM_PLOCK_MISC_NAME		"dlm_plock"
 
 #define DLM_PLOCK_VERSION_MAJOR	1
diff --git a/include/linux/dn.h b/include/linux/dn.h
index 02bba040fcfb..fe9990823193 100644
--- a/include/linux/dn.h
+++ b/include/linux/dn.h
@@ -1,6 +1,8 @@
 #ifndef _LINUX_DN_H
 #define _LINUX_DN_H
 
+#include <linux/types.h>
+
 /*
 
 	DECnet Data Structures and Constants
diff --git a/include/linux/dvb/audio.h b/include/linux/dvb/audio.h
index 89412e18f571..bb0df2aaebfa 100644
--- a/include/linux/dvb/audio.h
+++ b/include/linux/dvb/audio.h
@@ -24,12 +24,7 @@
 #ifndef _DVBAUDIO_H_
 #define _DVBAUDIO_H_
 
-#ifdef __KERNEL__
 #include <linux/types.h>
-#else
-#include <stdint.h>
-#endif
-
 
 typedef enum {
 	AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */
diff --git a/include/linux/dvb/dmx.h b/include/linux/dvb/dmx.h
index 402fb7a8d922..fef943738a24 100644
--- a/include/linux/dvb/dmx.h
+++ b/include/linux/dvb/dmx.h
@@ -24,7 +24,7 @@
 #ifndef _DVBDMX_H_
 #define _DVBDMX_H_
 
-#include <asm/types.h>
+#include <linux/types.h>
 #ifdef __KERNEL__
 #include <linux/time.h>
 #else
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
index 55026b1a40bd..51c8d2d49e42 100644
--- a/include/linux/dvb/frontend.h
+++ b/include/linux/dvb/frontend.h
@@ -26,8 +26,7 @@
 #ifndef _DVBFRONTEND_H_
 #define _DVBFRONTEND_H_
 
-#include <asm/types.h>
-
+#include <linux/types.h>
 
 typedef enum fe_type {
 	FE_QPSK,
diff --git a/include/linux/dvb/net.h b/include/linux/dvb/net.h
index 5be474bf0d2b..f451e7eb0b0b 100644
--- a/include/linux/dvb/net.h
+++ b/include/linux/dvb/net.h
@@ -24,8 +24,7 @@
 #ifndef _DVBNET_H_
 #define _DVBNET_H_
 
-#include <asm/types.h>
-
+#include <linux/types.h>
 
 struct dvb_net_if {
 	__u16 pid;
diff --git a/include/linux/dvb/video.h b/include/linux/dvb/video.h
index 50839fe9e39e..bd49c3ebf916 100644
--- a/include/linux/dvb/video.h
+++ b/include/linux/dvb/video.h
@@ -24,17 +24,14 @@
 #ifndef _DVBVIDEO_H_
 #define _DVBVIDEO_H_
 
-#include <linux/compiler.h>
-
-#ifdef __KERNEL__
 #include <linux/types.h>
+#ifdef __KERNEL__
+#include <linux/compiler.h>
 #else
-#include <asm/types.h>
 #include <stdint.h>
 #include <time.h>
 #endif
 
-
 typedef enum {
 	VIDEO_FORMAT_4_3,     /* Select 4:3 format */
 	VIDEO_FORMAT_16_9,    /* Select 16:9 format. */
diff --git a/include/linux/edd.h b/include/linux/edd.h
index 5d747c5cd0fe..4cbd0fe9df08 100644
--- a/include/linux/edd.h
+++ b/include/linux/edd.h
@@ -30,6 +30,8 @@
 #ifndef _LINUX_EDD_H
 #define _LINUX_EDD_H
 
+#include <linux/types.h>
+
 #define EDDNR 0x1e9		/* addr of number of edd_info structs at EDDBUF
 				   in boot_params - treat this as 1 byte  */
 #define EDDBUF	0xd00		/* addr of edd_info structs in boot_params */
diff --git a/include/linux/efs_fs_sb.h b/include/linux/efs_fs_sb.h
index ff1945e37790..a01be90c58cc 100644
--- a/include/linux/efs_fs_sb.h
+++ b/include/linux/efs_fs_sb.h
@@ -9,6 +9,7 @@
 #ifndef __EFS_FS_SB_H__
 #define __EFS_FS_SB_H__
 
+#include <linux/types.h>
 #include <linux/magic.h>
 
 /* EFS superblock magic numbers */
diff --git a/include/linux/elf-fdpic.h b/include/linux/elf-fdpic.h
index 9f5b7456bff3..7cd2e80cebc8 100644
--- a/include/linux/elf-fdpic.h
+++ b/include/linux/elf-fdpic.h
@@ -58,11 +58,13 @@ struct elf_fdpic_params {
 #define ELF_FDPIC_FLAG_PRESENT		0x80000000	/* T if this object is present */
 };
 
+#ifdef __KERNEL__
 #ifdef CONFIG_MMU
 extern void elf_fdpic_arch_lay_out_mm(struct elf_fdpic_params *exec_params,
 				      struct elf_fdpic_params *interp_params,
 				      unsigned long *start_stack,
 				      unsigned long *start_brk);
 #endif
+#endif /* __KERNEL__ */
 
 #endif /* _LINUX_ELF_FDPIC_H */
diff --git a/include/linux/elf.h b/include/linux/elf.h
index 0b61ca41a044..45a937be6d38 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -377,6 +377,7 @@ typedef struct elf64_note {
   Elf64_Word n_type;	/* Content type */
 } Elf64_Nhdr;
 
+#ifdef __KERNEL__
 #if ELF_CLASS == ELFCLASS32
 
 extern Elf32_Dyn _DYNAMIC [];
@@ -404,5 +405,5 @@ static inline int elf_coredump_extra_notes_write(struct file *file,
 extern int elf_coredump_extra_notes_size(void);
 extern int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset);
 #endif
-
+#endif /* __KERNEL__ */
 #endif /* _LINUX_ELF_H */
diff --git a/include/linux/errqueue.h b/include/linux/errqueue.h
index 92f8d4fab32b..ceb1454b6977 100644
--- a/include/linux/errqueue.h
+++ b/include/linux/errqueue.h
@@ -1,6 +1,8 @@
 #ifndef _LINUX_ERRQUEUE_H
 #define _LINUX_ERRQUEUE_H 1
 
+#include <linux/types.h>
+
 struct sock_extended_err
 {
 	__u32	ee_errno;	
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 818fe21257e8..31527e17076b 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -960,6 +960,21 @@ extern struct fb_info *registered_fb[FB_MAX];
 extern int num_registered_fb;
 extern struct class *fb_class;
 
+static inline int lock_fb_info(struct fb_info *info)
+{
+	mutex_lock(&info->lock);
+	if (!info->fbops) {
+		mutex_unlock(&info->lock);
+		return 0;
+	}
+	return 1;
+}
+
+static inline void unlock_fb_info(struct fb_info *info)
+{
+	mutex_unlock(&info->lock);
+}
+
 static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch,
 					   u8 *src, u32 s_pitch, u32 height)
 {
diff --git a/include/linux/genetlink.h b/include/linux/genetlink.h
index 7da02c93002b..b834ef6d59fa 100644
--- a/include/linux/genetlink.h
+++ b/include/linux/genetlink.h
@@ -1,6 +1,7 @@
 #ifndef __LINUX_GENERIC_NETLINK_H
 #define __LINUX_GENERIC_NETLINK_H
 
+#include <linux/types.h>
 #include <linux/netlink.h>
 
 #define GENL_NAMSIZ	16	/* length of family name */
diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h
index 14d0df0b5749..c56b4bce56d0 100644
--- a/include/linux/gfs2_ondisk.h
+++ b/include/linux/gfs2_ondisk.h
@@ -10,6 +10,8 @@
 #ifndef __GFS2_ONDISK_DOT_H__
 #define __GFS2_ONDISK_DOT_H__
 
+#include <linux/types.h>
+
 #define GFS2_MAGIC		0x01161970
 #define GFS2_BASIC_BLOCK	512
 #define GFS2_BASIC_BLOCK_SHIFT	9
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 81aa84d60c6b..fa8ee9cef7be 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -791,6 +791,7 @@ dbg_hid(const char *fmt, ...)
 		__FILE__ , ## arg)
 #endif /* HID_FF */
 
+#ifdef __KERNEL__
 #ifdef CONFIG_HID_COMPAT
 #define HID_COMPAT_LOAD_DRIVER(name)	\
 /* prototype to avoid sparse warning */	\
@@ -804,6 +805,7 @@ EXPORT_SYMBOL(hid_compat_##name)
 	extern void hid_compat_##name(void);	\
 	hid_compat_##name();			\
 } while (0)
+#endif /* __KERNEL__ */
 
 #endif
 
diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h
index c760ae0eb6a1..bb6f58baf319 100644
--- a/include/linux/hiddev.h
+++ b/include/linux/hiddev.h
@@ -27,6 +27,8 @@
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
+#include <linux/types.h>
+
 /*
  * The event structure itself
  */
diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index a93a8dd33118..10d701eec484 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -1,6 +1,7 @@
 #ifndef _LINUX_ICMPV6_H
 #define _LINUX_ICMPV6_H
 
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
 struct icmp6hdr {
diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h
index 43f3bedaafd3..a60c821be44c 100644
--- a/include/linux/if_addr.h
+++ b/include/linux/if_addr.h
@@ -1,6 +1,7 @@
 #ifndef __LINUX_IF_ADDR_H
 #define __LINUX_IF_ADDR_H
 
+#include <linux/types.h>
 #include <linux/netlink.h>
 
 struct ifaddrmsg
diff --git a/include/linux/if_addrlabel.h b/include/linux/if_addrlabel.h
index 9fe79c95dd28..89571f65d6de 100644
--- a/include/linux/if_addrlabel.h
+++ b/include/linux/if_addrlabel.h
@@ -10,6 +10,8 @@
 #ifndef __LINUX_IF_ADDRLABEL_H
 #define __LINUX_IF_ADDRLABEL_H
 
+#include <linux/types.h>
+
 struct ifaddrlblmsg
 {
 	__u8		ifal_family;		/* Address family */
diff --git a/include/linux/if_fc.h b/include/linux/if_fc.h
index 376a34ea4723..6ed7f1bf35c8 100644
--- a/include/linux/if_fc.h
+++ b/include/linux/if_fc.h
@@ -20,6 +20,7 @@
 #ifndef _LINUX_IF_FC_H
 #define _LINUX_IF_FC_H
 
+#include <linux/types.h>
 
 #define FC_ALEN	6		/* Octets in one ethernet addr	 */
 #define FC_HLEN   (sizeof(struct fch_hdr)+sizeof(struct fcllc))
diff --git a/include/linux/if_hippi.h b/include/linux/if_hippi.h
index f0f23516bb59..4a7c9940b080 100644
--- a/include/linux/if_hippi.h
+++ b/include/linux/if_hippi.h
@@ -22,6 +22,7 @@
 #ifndef _LINUX_IF_HIPPI_H
 #define _LINUX_IF_HIPPI_H
 
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
 /*
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index f9032c88716a..176c5182c515 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -1,6 +1,7 @@
 #ifndef _LINUX_IF_LINK_H
 #define _LINUX_IF_LINK_H
 
+#include <linux/types.h>
 #include <linux/netlink.h>
 
 /* The struct should be in sync with struct net_device_stats */
diff --git a/include/linux/if_ppp.h b/include/linux/if_ppp.h
index c3b1f8562709..fcef103aa3f6 100644
--- a/include/linux/if_ppp.h
+++ b/include/linux/if_ppp.h
@@ -33,6 +33,7 @@
 #ifndef _IF_PPP_H_
 #define _IF_PPP_H_
 
+#include <linux/types.h>
 #include <linux/compiler.h>
 
 /*
diff --git a/include/linux/if_strip.h b/include/linux/if_strip.h
index fb5c5c98442f..6526a6235832 100644
--- a/include/linux/if_strip.h
+++ b/include/linux/if_strip.h
@@ -18,6 +18,8 @@
 #ifndef __LINUX_STRIP_H
 #define __LINUX_STRIP_H
 
+#include <linux/types.h>
+
 typedef struct {
     __u8 c[6];
 } MetricomAddress;
diff --git a/include/linux/if_tr.h b/include/linux/if_tr.h
index 5bcec8b2c5e2..fc23aeb0f201 100644
--- a/include/linux/if_tr.h
+++ b/include/linux/if_tr.h
@@ -19,6 +19,7 @@
 #ifndef _LINUX_IF_TR_H
 #define _LINUX_IF_TR_H
 
+#include <linux/types.h>
 #include <asm/byteorder.h>	/* For __be16 */
 
 /* IEEE 802.5 Token-Ring magic constants.  The frame sizes omit the preamble
diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h
index aeab2cb32a9c..82c43624c067 100644
--- a/include/linux/if_tunnel.h
+++ b/include/linux/if_tunnel.h
@@ -2,7 +2,10 @@
 #define _IF_TUNNEL_H_
 
 #include <linux/types.h>
+
+#ifdef __KERNEL__
 #include <linux/ip.h>
+#endif
 
 #define SIOCGETTUNNEL   (SIOCDEVPRIVATE + 0)
 #define SIOCADDTUNNEL   (SIOCDEVPRIVATE + 1)
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index f734a0ba0698..92fbd8cbd68f 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -16,6 +16,7 @@
 #ifndef _LINUX_IGMP_H
 #define _LINUX_IGMP_H
 
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
 /*
diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
index 6e8bc548635a..bc8c49022084 100644
--- a/include/linux/inet_diag.h
+++ b/include/linux/inet_diag.h
@@ -1,6 +1,8 @@
 #ifndef _INET_DIAG_H_
 #define _INET_DIAG_H_ 1
 
+#include <linux/types.h>
+
 /* Just some random number */
 #define TCPDIAG_GETSOCK 18
 #define DCCPDIAG_GETSOCK 19
diff --git a/include/linux/ip6_tunnel.h b/include/linux/ip6_tunnel.h
index 1e7cc4af40de..acb9ad684d63 100644
--- a/include/linux/ip6_tunnel.h
+++ b/include/linux/ip6_tunnel.h
@@ -1,6 +1,8 @@
 #ifndef _IP6_TUNNEL_H
 #define _IP6_TUNNEL_H
 
+#include <linux/types.h>
+
 #define IPV6_TLV_TNL_ENCAP_LIMIT 4
 #define IPV6_DEFAULT_TNL_ENCAP_LIMIT 4
 
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 0b816cae533e..476d9464ac82 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -1,6 +1,7 @@
 #ifndef _IPV6_H
 #define _IPV6_H
 
+#include <linux/types.h>
 #include <linux/in6.h>
 #include <asm/byteorder.h>
 
diff --git a/include/linux/ipv6_route.h b/include/linux/ipv6_route.h
index b323ff577967..1e7d8af2defe 100644
--- a/include/linux/ipv6_route.h
+++ b/include/linux/ipv6_route.h
@@ -13,6 +13,8 @@
 #ifndef _LINUX_IPV6_ROUTE_H
 #define _LINUX_IPV6_ROUTE_H
 
+#include <linux/types.h>
+
 #define RTF_DEFAULT	0x00010000	/* default - learned via ND	*/
 #define RTF_ALLONLINK	0x00020000	/* (deprecated and will be removed)
 					   fallback, no routers on link */
diff --git a/include/linux/ipx.h b/include/linux/ipx.h
index eb19b4ea84f4..aabb1d294025 100644
--- a/include/linux/ipx.h
+++ b/include/linux/ipx.h
@@ -1,5 +1,6 @@
 #ifndef _IPX_H_
 #define _IPX_H_
+#include <linux/types.h>
 #include <linux/sockios.h>
 #include <linux/socket.h>
 #define IPX_NODE_LEN	6
diff --git a/include/linux/irda.h b/include/linux/irda.h
index 28f88ecba344..00bdad0e8515 100644
--- a/include/linux/irda.h
+++ b/include/linux/irda.h
@@ -25,6 +25,8 @@
 #ifndef KERNEL_IRDA_H
 #define KERNEL_IRDA_H
 
+#include <linux/types.h>
+
 /* Please do *not* add any #include in this file, this file is
  * included as-is in user space.
  * Please fix the calling file to properly included needed files before
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 343df9ef2412..7fa371898e3e 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -480,7 +480,8 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
 /*
  * swap - swap value of @a and @b
  */
-#define swap(a, b) ({ typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; })
+#define swap(a, b) \
+	do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
 
 /**
  * container_of - cast a member of a structure out to the containing structure
diff --git a/include/linux/libata.h b/include/linux/libata.h
index bca3ba25f52a..5d87bc09a1f5 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -380,6 +380,7 @@ enum {
 	ATA_HORKAGE_ATAPI_MOD16_DMA = (1 << 11), /* use ATAPI DMA for commands
 						    not multiple of 16 bytes */
 	ATA_HORKAGE_FIRMWARE_WARN = (1 << 12),	/* firwmare update warning */
+	ATA_HORKAGE_1_5_GBPS	= (1 << 13),	/* force 1.5 Gbps */
 
 	 /* DMA mask for user DMA control: User visible values; DO NOT
 	    renumber */
@@ -580,7 +581,7 @@ struct ata_device {
 	acpi_handle		acpi_handle;
 	union acpi_object	*gtf_cache;
 #endif
-	/* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
+	/* n_sector is CLEAR_BEGIN, read comment above CLEAR_BEGIN */
 	u64			n_sectors;	/* size of device, if ATA */
 	unsigned int		class;		/* ATA_DEV_xxx */
 	unsigned long		unpark_deadline;
@@ -605,20 +606,22 @@ struct ata_device {
 	u16			heads;		/* Number of heads */
 	u16			sectors;	/* Number of sectors per track */
 
-	/* error history */
-	int			spdn_cnt;
-	struct ata_ering	ering;
-
 	union {
 		u16		id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
 		u32		gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */
 	};
+
+	/* error history */
+	int			spdn_cnt;
+	/* ering is CLEAR_END, read comment above CLEAR_END */
+	struct ata_ering	ering;
 };
 
-/* Offset into struct ata_device.  Fields above it are maintained
- * acress device init.  Fields below are zeroed.
+/* Fields between ATA_DEVICE_CLEAR_BEGIN and ATA_DEVICE_CLEAR_END are
+ * cleared to zero on ata_dev_init().
  */
-#define ATA_DEVICE_CLEAR_OFFSET		offsetof(struct ata_device, n_sectors)
+#define ATA_DEVICE_CLEAR_BEGIN		offsetof(struct ata_device, n_sectors)
+#define ATA_DEVICE_CLEAR_END		offsetof(struct ata_device, ering)
 
 struct ata_eh_info {
 	struct ata_device	*dev;		/* offending device */
diff --git a/include/linux/minix_fs.h b/include/linux/minix_fs.h
index 0e39745f5111..13fe09e0576a 100644
--- a/include/linux/minix_fs.h
+++ b/include/linux/minix_fs.h
@@ -1,6 +1,7 @@
 #ifndef _LINUX_MINIX_FS_H
 #define _LINUX_MINIX_FS_H
 
+#include <linux/types.h>
 #include <linux/magic.h>
 
 /*
diff --git a/include/linux/module.h b/include/linux/module.h
index 4f7ea12463d3..145a75528cc1 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -219,11 +219,6 @@ void *__symbol_get_gpl(const char *symbol);
 
 #endif
 
-struct module_ref
-{
-	local_t count;
-} ____cacheline_aligned;
-
 enum module_state
 {
 	MODULE_STATE_LIVE,
@@ -344,8 +339,11 @@ struct module
 	/* Destruction function. */
 	void (*exit)(void);
 
-	/* Reference counts */
-	struct module_ref ref[NR_CPUS];
+#ifdef CONFIG_SMP
+	char *refptr;
+#else
+	local_t ref;
+#endif
 #endif
 };
 #ifndef MODULE_ARCH_INIT
@@ -395,13 +393,21 @@ void __symbol_put(const char *symbol);
 #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x)
 void symbol_put_addr(void *addr);
 
+static inline local_t *__module_ref_addr(struct module *mod, int cpu)
+{
+#ifdef CONFIG_SMP
+	return (local_t *) (mod->refptr + per_cpu_offset(cpu));
+#else
+	return &mod->ref;
+#endif
+}
+
 /* Sometimes we know we already have a refcount, and it's easier not
    to handle the error case (which only happens with rmmod --wait). */
 static inline void __module_get(struct module *module)
 {
 	if (module) {
-		BUG_ON(module_refcount(module) == 0);
-		local_inc(&module->ref[get_cpu()].count);
+		local_inc(__module_ref_addr(module, get_cpu()));
 		put_cpu();
 	}
 }
@@ -413,7 +419,7 @@ static inline int try_module_get(struct module *module)
 	if (module) {
 		unsigned int cpu = get_cpu();
 		if (likely(module_is_live(module)))
-			local_inc(&module->ref[cpu].count);
+			local_inc(__module_ref_addr(module, cpu));
 		else
 			ret = 0;
 		put_cpu();
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index e0a9b207920d..ce38f1caa5e1 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -1,6 +1,7 @@
 #ifndef _LINUX_MSDOS_FS_H
 #define _LINUX_MSDOS_FS_H
 
+#include <linux/types.h>
 #include <linux/magic.h>
 #include <asm/byteorder.h>
 
diff --git a/include/linux/neighbour.h b/include/linux/neighbour.h
index bd3bbf668cdb..8730d5dae1bc 100644
--- a/include/linux/neighbour.h
+++ b/include/linux/neighbour.h
@@ -1,6 +1,7 @@
 #ifndef __LINUX_NEIGHBOUR_H
 #define __LINUX_NEIGHBOUR_H
 
+#include <linux/types.h>
 #include <linux/netlink.h>
 
 struct ndmsg
diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h
index f3fd83e46bab..8f5345275393 100644
--- a/include/linux/netfilter/xt_conntrack.h
+++ b/include/linux/netfilter/xt_conntrack.h
@@ -5,6 +5,7 @@
 #ifndef _XT_CONNTRACK_H
 #define _XT_CONNTRACK_H
 
+#include <linux/types.h>
 #include <linux/netfilter/nf_conntrack_tuple_common.h>
 
 #define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
diff --git a/include/linux/nfs_idmap.h b/include/linux/nfs_idmap.h
index 15a9f3b7289a..91a1c24e0cbf 100644
--- a/include/linux/nfs_idmap.h
+++ b/include/linux/nfs_idmap.h
@@ -37,6 +37,8 @@
 #ifndef NFS_IDMAP_H
 #define NFS_IDMAP_H
 
+#include <linux/types.h>
+
 /* XXX from bits/utmp.h  */
 #define IDMAP_NAMESZ  128
 
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index 5431512b2757..bcd0201589f8 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -10,9 +10,8 @@
 #ifndef NFSD_EXPORT_H
 #define NFSD_EXPORT_H
 
-#include <asm/types.h>
-#ifdef __KERNEL__
 # include <linux/types.h>
+#ifdef __KERNEL__
 # include <linux/in.h>
 #endif
 
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h
index b2e093870bc6..fa317f6c154b 100644
--- a/include/linux/nfsd/nfsfh.h
+++ b/include/linux/nfsd/nfsfh.h
@@ -14,9 +14,8 @@
 #ifndef _LINUX_NFSD_FH_H
 #define _LINUX_NFSD_FH_H
 
-#include <asm/types.h>
-#ifdef __KERNEL__
 # include <linux/types.h>
+#ifdef __KERNEL__
 # include <linux/string.h>
 # include <linux/fs.h>
 #endif
diff --git a/include/linux/nfsd/syscall.h b/include/linux/nfsd/syscall.h
index 4e439765b705..7a3b565b898f 100644
--- a/include/linux/nfsd/syscall.h
+++ b/include/linux/nfsd/syscall.h
@@ -9,9 +9,8 @@
 #ifndef NFSD_SYSCALL_H
 #define NFSD_SYSCALL_H
 
-#include <asm/types.h>
-#ifdef __KERNEL__
 # include <linux/types.h>
+#ifdef __KERNEL__
 # include <linux/in.h>
 #endif 
 #include <linux/posix_types.h>
diff --git a/include/linux/nubus.h b/include/linux/nubus.h
index c4355076d1a5..7382af374731 100644
--- a/include/linux/nubus.h
+++ b/include/linux/nubus.h
@@ -12,6 +12,7 @@
 #ifndef LINUX_NUBUS_H
 #define LINUX_NUBUS_H
 
+#include <linux/types.h>
 #ifdef __KERNEL__
 #include <asm/nubus.h>
 #endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 48890cf3f96e..7bd624bfdcfd 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -684,7 +684,7 @@ int pci_enable_rom(struct pci_dev *pdev);
 void pci_disable_rom(struct pci_dev *pdev);
 void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
 void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom);
-size_t pci_get_rom_size(void __iomem *rom, size_t size);
+size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size);
 
 /* Power management related routines */
 int pci_save_state(struct pci_dev *dev);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index febc10ed3858..52a9fe08451c 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2425,6 +2425,7 @@
 #define PCI_DEVICE_ID_INTEL_ICH7_0	0x27b8
 #define PCI_DEVICE_ID_INTEL_ICH7_1	0x27b9
 #define PCI_DEVICE_ID_INTEL_ICH7_30	0x27b0
+#define PCI_DEVICE_ID_INTEL_TGP_LPC	0x27bc
 #define PCI_DEVICE_ID_INTEL_ICH7_31	0x27bd
 #define PCI_DEVICE_ID_INTEL_ICH7_17	0x27da
 #define PCI_DEVICE_ID_INTEL_ICH7_19	0x27dd
diff --git a/include/linux/phonet.h b/include/linux/phonet.h
index 4157faa857b6..ee5e3c9e2bca 100644
--- a/include/linux/phonet.h
+++ b/include/linux/phonet.h
@@ -23,6 +23,8 @@
 #ifndef LINUX_PHONET_H
 #define LINUX_PHONET_H
 
+#include <linux/types.h>
+
 /* Automatic protocol selection */
 #define PN_PROTO_TRANSPORT	0
 /* Phonet datagram socket */
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index e6aa8482ad7a..3c842edff388 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -1,6 +1,7 @@
 #ifndef __LINUX_PKT_CLS_H
 #define __LINUX_PKT_CLS_H
 
+#include <linux/types.h>
 #include <linux/pkt_sched.h>
 
 /* I think i could have done better macros ; for now this is stolen from
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index e3f133adba78..b2648e8e4987 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -1,6 +1,8 @@
 #ifndef __LINUX_PKT_SCHED_H
 #define __LINUX_PKT_SCHED_H
 
+#include <linux/types.h>
+
 /* Logical priority bands not depending on specific packet scheduler.
    Every scheduler will map them to real traffic classes, if it has
    no more precise mechanism to classify packets.
diff --git a/include/linux/ppp_defs.h b/include/linux/ppp_defs.h
index 6e8adc77522c..1c866bda2018 100644
--- a/include/linux/ppp_defs.h
+++ b/include/linux/ppp_defs.h
@@ -25,6 +25,8 @@
  * OR MODIFICATIONS.
  */
 
+#include <linux/types.h>
+
 /*
  *  ==FILEVERSION 20000114==
  *
diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h
index 9491026afe66..6ba830fa8538 100644
--- a/include/linux/raid/md_p.h
+++ b/include/linux/raid/md_p.h
@@ -15,6 +15,8 @@
 #ifndef _MD_P_H
 #define _MD_P_H
 
+#include <linux/types.h>
+
 /*
  * RAID superblock.
  *
diff --git a/include/linux/random.h b/include/linux/random.h
index 407ea3646f8f..25d02fe5c9b5 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -7,6 +7,7 @@
 #ifndef _LINUX_RANDOM_H
 #define _LINUX_RANDOM_H
 
+#include <linux/types.h>
 #include <linux/ioctl.h>
 #include <linux/irqnr.h>
 
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index e88f7058b3a1..1e5f6730ff31 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -1,6 +1,7 @@
 #ifndef __LINUX_RTNETLINK_H
 #define __LINUX_RTNETLINK_H
 
+#include <linux/types.h>
 #include <linux/netlink.h>
 #include <linux/if_link.h>
 #include <linux/if_addr.h>
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2225c207801c..28b3f505f189 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -443,6 +443,7 @@ struct pacct_struct {
  * @utime:		time spent in user mode, in &cputime_t units
  * @stime:		time spent in kernel mode, in &cputime_t units
  * @sum_exec_runtime:	total time spent on the CPU, in nanoseconds
+ * @lock:		lock for fields in this struct
  *
  * This structure groups together three kinds of CPU time that are
  * tracked for threads and thread groups.  Most things considering
diff --git a/include/linux/signalfd.h b/include/linux/signalfd.h
index bef0c46d4713..b363b916c909 100644
--- a/include/linux/signalfd.h
+++ b/include/linux/signalfd.h
@@ -8,6 +8,7 @@
 #ifndef _LINUX_SIGNALFD_H
 #define _LINUX_SIGNALFD_H
 
+#include <linux/types.h>
 /* For O_CLOEXEC and O_NONBLOCK */
 #include <linux/fcntl.h>
 
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
index 39c3a5eb8ebe..6ca6a7b66d75 100644
--- a/include/linux/slab_def.h
+++ b/include/linux/slab_def.h
@@ -43,10 +43,7 @@ static inline void *kmalloc(size_t size, gfp_t flags)
 			i++;
 #include <linux/kmalloc_sizes.h>
 #undef CACHE
-		{
-			extern void __you_cannot_kmalloc_that_much(void);
-			__you_cannot_kmalloc_that_much();
-		}
+		return NULL;
 found:
 #ifdef CONFIG_ZONE_DMA
 		if (flags & GFP_DMA)
@@ -77,10 +74,7 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
 			i++;
 #include <linux/kmalloc_sizes.h>
 #undef CACHE
-		{
-			extern void __you_cannot_kmalloc_that_much(void);
-			__you_cannot_kmalloc_that_much();
-		}
+		return NULL;
 found:
 #ifdef CONFIG_ZONE_DMA
 		if (flags & GFP_DMA)
diff --git a/include/linux/sound.h b/include/linux/sound.h
index 9e2a94feed6b..44dcf0570432 100644
--- a/include/linux/sound.h
+++ b/include/linux/sound.h
@@ -25,6 +25,7 @@
 #define SND_DEV_AMIDI		13	/* Like /dev/midi (obsolete) */
 #define SND_DEV_ADMMIDI		14	/* Like /dev/dmmidi (onsolete) */
 
+#ifdef __KERNEL__
 /*
  *	Sound core interface functions
  */
@@ -40,3 +41,4 @@ extern void unregister_sound_special(int unit);
 extern void unregister_sound_mixer(int unit);
 extern void unregister_sound_midi(int unit);
 extern void unregister_sound_dsp(int unit);
+#endif /* __KERNEL__ */
diff --git a/include/linux/spi/spidev.h b/include/linux/spi/spidev.h
index c93ef9d42a01..95251ccd5a07 100644
--- a/include/linux/spi/spidev.h
+++ b/include/linux/spi/spidev.h
@@ -22,6 +22,7 @@
 #ifndef SPIDEV_H
 #define SPIDEV_H
 
+#include <linux/types.h>
 
 /* User space versions of kernel symbols for SPI clocking modes,
  * matching <linux/spi/spi.h>
diff --git a/include/linux/synclink.h b/include/linux/synclink.h
index c844a229acc9..99b8bdb17b2b 100644
--- a/include/linux/synclink.h
+++ b/include/linux/synclink.h
@@ -13,6 +13,8 @@
 #define _SYNCLINK_H_
 #define SYNCLINK_H_VERSION 3.6
 
+#include <linux/types.h>
+
 #define BIT0	0x0001
 #define BIT1	0x0002
 #define BIT2	0x0004
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h
index 18269e956a71..341dddb55090 100644
--- a/include/linux/taskstats.h
+++ b/include/linux/taskstats.h
@@ -16,6 +16,8 @@
 #ifndef _LINUX_TASKSTATS_H
 #define _LINUX_TASKSTATS_H
 
+#include <linux/types.h>
+
 /* Format for per-task data returned to userland when
  *	- a task exits
  *	- listener requests stats for a task
diff --git a/include/linux/tc_act/tc_gact.h b/include/linux/tc_act/tc_gact.h
index 23a03eb630db..e895c0a39629 100644
--- a/include/linux/tc_act/tc_gact.h
+++ b/include/linux/tc_act/tc_gact.h
@@ -1,6 +1,7 @@
 #ifndef __LINUX_TC_GACT_H
 #define __LINUX_TC_GACT_H
 
+#include <linux/types.h>
 #include <linux/pkt_cls.h>
 
 #define TCA_ACT_GACT 5
diff --git a/include/linux/tc_act/tc_mirred.h b/include/linux/tc_act/tc_mirred.h
index 71d63409d568..0a99ab60d610 100644
--- a/include/linux/tc_act/tc_mirred.h
+++ b/include/linux/tc_act/tc_mirred.h
@@ -1,6 +1,7 @@
 #ifndef __LINUX_TC_MIR_H
 #define __LINUX_TC_MIR_H
 
+#include <linux/types.h>
 #include <linux/pkt_cls.h>
 
 #define TCA_ACT_MIRRED 8
diff --git a/include/linux/tc_act/tc_pedit.h b/include/linux/tc_act/tc_pedit.h
index 83e56e32e8e0..54ce9064115a 100644
--- a/include/linux/tc_act/tc_pedit.h
+++ b/include/linux/tc_act/tc_pedit.h
@@ -1,6 +1,7 @@
 #ifndef __LINUX_TC_PED_H
 #define __LINUX_TC_PED_H
 
+#include <linux/types.h>
 #include <linux/pkt_cls.h>
 
 #define TCA_ACT_PEDIT 7
diff --git a/include/linux/tc_ematch/tc_em_cmp.h b/include/linux/tc_ematch/tc_em_cmp.h
index c7f4d43618fd..38e7f7b25ec2 100644
--- a/include/linux/tc_ematch/tc_em_cmp.h
+++ b/include/linux/tc_ematch/tc_em_cmp.h
@@ -1,6 +1,7 @@
 #ifndef __LINUX_TC_EM_CMP_H
 #define __LINUX_TC_EM_CMP_H
 
+#include <linux/types.h>
 #include <linux/pkt_cls.h>
 
 struct tcf_em_cmp
diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h
index c50d2ba5caf0..dcfb733fa1f6 100644
--- a/include/linux/tc_ematch/tc_em_meta.h
+++ b/include/linux/tc_ematch/tc_em_meta.h
@@ -1,6 +1,7 @@
 #ifndef __LINUX_TC_EM_META_H
 #define __LINUX_TC_EM_META_H
 
+#include <linux/types.h>
 #include <linux/pkt_cls.h>
 
 enum
diff --git a/include/linux/tc_ematch/tc_em_nbyte.h b/include/linux/tc_ematch/tc_em_nbyte.h
index f19d1f58ec9d..9ed8c2e58488 100644
--- a/include/linux/tc_ematch/tc_em_nbyte.h
+++ b/include/linux/tc_ematch/tc_em_nbyte.h
@@ -1,6 +1,7 @@
 #ifndef __LINUX_TC_EM_NBYTE_H
 #define __LINUX_TC_EM_NBYTE_H
 
+#include <linux/types.h>
 #include <linux/pkt_cls.h>
 
 struct tcf_em_nbyte
diff --git a/include/linux/tc_ematch/tc_em_text.h b/include/linux/tc_ematch/tc_em_text.h
index 7cd43e99c7f5..d12a73a225fc 100644
--- a/include/linux/tc_ematch/tc_em_text.h
+++ b/include/linux/tc_ematch/tc_em_text.h
@@ -1,6 +1,7 @@
 #ifndef __LINUX_TC_EM_TEXT_H
 #define __LINUX_TC_EM_TEXT_H
 
+#include <linux/types.h>
 #include <linux/pkt_cls.h>
 
 #define TC_EM_TEXT_ALGOSIZ	16
diff --git a/include/linux/usb/cdc.h b/include/linux/usb/cdc.h
index 18a729343ffa..3c86ed25a04c 100644
--- a/include/linux/usb/cdc.h
+++ b/include/linux/usb/cdc.h
@@ -9,6 +9,8 @@
 #ifndef __LINUX_USB_CDC_H
 #define __LINUX_USB_CDC_H
 
+#include <linux/types.h>
+
 #define USB_CDC_SUBCLASS_ACM			0x02
 #define USB_CDC_SUBCLASS_ETHERNET		0x06
 #define USB_CDC_SUBCLASS_WHCM			0x08
diff --git a/include/linux/usb/gadgetfs.h b/include/linux/usb/gadgetfs.h
index ea45f265ec05..612102e4d75e 100644
--- a/include/linux/usb/gadgetfs.h
+++ b/include/linux/usb/gadgetfs.h
@@ -18,7 +18,7 @@
 #ifndef __LINUX_USB_GADGETFS_H
 #define __LINUX_USB_GADGETFS_H
 
-#include <asm/types.h>
+#include <linux/types.h>
 #include <asm/ioctl.h>
 
 #include <linux/usb/ch9.h>
diff --git a/include/linux/video_decoder.h b/include/linux/video_decoder.h
index 121e26da2c18..e26c0c86a6ea 100644
--- a/include/linux/video_decoder.h
+++ b/include/linux/video_decoder.h
@@ -1,6 +1,8 @@
 #ifndef _LINUX_VIDEO_DECODER_H
 #define _LINUX_VIDEO_DECODER_H
 
+#include <linux/types.h>
+
 #define HAVE_VIDEO_DECODER 1
 
 struct video_decoder_capability { /* this name is too long */
diff --git a/include/linux/video_encoder.h b/include/linux/video_encoder.h
index 4b0e6907a7b4..b7b6423bbb8a 100644
--- a/include/linux/video_encoder.h
+++ b/include/linux/video_encoder.h
@@ -1,6 +1,8 @@
 #ifndef _LINUX_VIDEO_ENCODER_H
 #define _LINUX_VIDEO_ENCODER_H
 
+#include <linux/types.h>
+
 struct video_encoder_capability { /* this name is too long */
 	__u32	flags;
 #define	VIDEO_ENCODER_PAL	1	/* can encode PAL signal */
diff --git a/include/linux/videodev.h b/include/linux/videodev.h
index 15a653d41132..837f392fbe97 100644
--- a/include/linux/videodev.h
+++ b/include/linux/videodev.h
@@ -12,6 +12,7 @@
 #ifndef __LINUX_VIDEODEV_H
 #define __LINUX_VIDEODEV_H
 
+#include <linux/types.h>
 #include <linux/ioctl.h>
 #include <linux/videodev2.h>
 
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h
index c1aef85243bf..94c56d29869d 100644
--- a/include/linux/virtio_blk.h
+++ b/include/linux/virtio_blk.h
@@ -2,6 +2,7 @@
 #define _LINUX_VIRTIO_BLK_H
 /* This header is BSD licensed so anyone can use the definitions to implement
  * compatible drivers/servers. */
+#include <linux/types.h>
 #include <linux/virtio_config.h>
 
 /* The ID for virtio_block */
diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h
index 7615ffcdd555..dc161115ae35 100644
--- a/include/linux/virtio_console.h
+++ b/include/linux/virtio_console.h
@@ -1,5 +1,6 @@
 #ifndef _LINUX_VIRTIO_CONSOLE_H
 #define _LINUX_VIRTIO_CONSOLE_H
+#include <linux/types.h>
 #include <linux/virtio_config.h>
 /* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
  * anyone can use the definitions to implement compatible drivers/servers. */
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index 5cdd0aa8bde9..3efa86c3ecb3 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -2,6 +2,7 @@
 #define _LINUX_VIRTIO_NET_H
 /* This header is BSD licensed so anyone can use the definitions to implement
  * compatible drivers/servers. */
+#include <linux/types.h>
 #include <linux/virtio_config.h>
 
 /* The ID for virtio_net */
diff --git a/include/linux/wait.h b/include/linux/wait.h
index ef609f842fac..a210ede73b56 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -132,6 +132,8 @@ static inline void __remove_wait_queue(wait_queue_head_t *head,
 	list_del(&old->task_list);
 }
 
+void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
+			int nr_exclusive, int sync, void *key);
 void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key);
 extern void __wake_up_locked(wait_queue_head_t *q, unsigned int mode);
 extern void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr);
@@ -333,16 +335,19 @@ do {									\
 	for (;;) {							\
 		prepare_to_wait_exclusive(&wq, &__wait,			\
 					TASK_INTERRUPTIBLE);		\
-		if (condition)						\
+		if (condition) {					\
+			finish_wait(&wq, &__wait);			\
 			break;						\
+		}							\
 		if (!signal_pending(current)) {				\
 			schedule();					\
 			continue;					\
 		}							\
 		ret = -ERESTARTSYS;					\
+		abort_exclusive_wait(&wq, &__wait, 			\
+				TASK_INTERRUPTIBLE, NULL);		\
 		break;							\
 	}								\
-	finish_wait(&wq, &__wait);					\
 } while (0)
 
 #define wait_event_interruptible_exclusive(wq, condition)		\
@@ -431,6 +436,8 @@ extern long interruptible_sleep_on_timeout(wait_queue_head_t *q,
 void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state);
 void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state);
 void finish_wait(wait_queue_head_t *q, wait_queue_t *wait);
+void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait,
+			unsigned int mode, void *key);
 int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
 int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
 
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index 9bf4ccc93dbf..55e41afd95ef 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -94,16 +94,16 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
 /* Call the specified callback for all subdevs matching grp_id (if 0, then
    match them all). Ignore any errors. Note that you cannot add or delete
    a subdev while walking the subdevs list. */
-#define v4l2_device_call_all(dev, grp_id, o, f, args...) 		\
+#define v4l2_device_call_all(dev, grpid, o, f, args...) 		\
 	__v4l2_device_call_subdevs(dev, 				\
-			!(grp_id) || sd->grp_id == (grp_id), o, f , ##args)
+			!(grpid) || sd->grp_id == (grpid), o, f , ##args)
 
 /* Call the specified callback for all subdevs matching grp_id (if 0, then
    match them all). If the callback returns an error other than 0 or
    -ENOIOCTLCMD, then return with that error code. Note that you cannot
    add or delete a subdev while walking the subdevs list. */
-#define v4l2_device_call_until_err(dev, grp_id, o, f, args...) 		\
+#define v4l2_device_call_until_err(dev, grpid, o, f, args...) 		\
 	__v4l2_device_call_subdevs_until_err(dev,			\
-		       !(grp_id) || sd->grp_id == (grp_id), o, f , ##args)
+		       !(grpid) || sd->grp_id == (grpid), o, f , ##args)
 
 #endif
diff --git a/include/mtd/inftl-user.h b/include/mtd/inftl-user.h
index e17eda302b2d..d409d489d900 100644
--- a/include/mtd/inftl-user.h
+++ b/include/mtd/inftl-user.h
@@ -6,6 +6,8 @@
 #ifndef __MTD_INFTL_USER_H__
 #define __MTD_INFTL_USER_H__
 
+#include <linux/types.h>
+
 #define	OSAK_VERSION	0x5120
 #define	PERCENTUSED	98
 
diff --git a/include/sound/hdsp.h b/include/sound/hdsp.h
index dec6b1dc37ea..d98a78dff2db 100644
--- a/include/sound/hdsp.h
+++ b/include/sound/hdsp.h
@@ -19,6 +19,8 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/types.h>
+
 #define HDSP_MATRIX_MIXER_SIZE 2048
 
 enum HDSP_IO_Type {
diff --git a/include/video/aty128.h b/include/video/aty128.h
index 7079beb005e8..51ac69f05bdc 100644
--- a/include/video/aty128.h
+++ b/include/video/aty128.h
@@ -21,9 +21,9 @@
 #define I2C_CNTL_1				0x0094
 #define PALETTE_INDEX				0x00b0
 #define PALETTE_DATA				0x00b4
-#define CONFIG_CNTL				0x00e0
+#define CNFG_CNTL				0x00e0
 #define GEN_RESET_CNTL				0x00f0
-#define CONFIG_MEMSIZE				0x00f8
+#define CNFG_MEMSIZE				0x00f8
 #define MEM_CNTL				0x0140
 #define MEM_POWER_MISC				0x015c
 #define AGP_BASE				0x0170
diff --git a/include/video/mach64.h b/include/video/mach64.h
index a8332e528ec1..89e91c0cb737 100644
--- a/include/video/mach64.h
+++ b/include/video/mach64.h
@@ -103,7 +103,7 @@
 #define CUR_HORZ_VERT_OFF	0x0070	/* Dword offset 0_1C */
 #define CUR2_HORZ_VERT_OFF	0x0070	/* Dword offset 0_1C */
 
-#define CONFIG_PANEL_LG		0x0074	/* Dword offset 0_1D (LG) */
+#define CNFG_PANEL_LG		0x0074	/* Dword offset 0_1D (LG) */
 
 /* General I/O Control */
 #define GP_IO			0x0078	/* Dword offset 0_1E */
@@ -146,8 +146,8 @@
 #define CLOCK_SEL_CNTL		0x0090	/* Dword offset 0_24 */
 
 /* Configuration */
-#define CONFIG_STAT1		0x0094	/* Dword offset 0_25 */
-#define CONFIG_STAT2		0x0098	/* Dword offset 0_26 */
+#define CNFG_STAT1		0x0094	/* Dword offset 0_25 */
+#define CNFG_STAT2		0x0098	/* Dword offset 0_26 */
 
 /* Bus Control */
 #define BUS_CNTL		0x00A0	/* Dword offset 0_28 */
@@ -190,9 +190,9 @@
 #define POWER_MANAGEMENT_LG	0x00D8	/* Dword offset 0_36 (LG) */
 
 /* Configuration */
-#define CONFIG_CNTL		0x00DC	/* Dword offset 0_37 (CT, ET, VT) */
-#define CONFIG_CHIP_ID		0x00E0	/* Dword offset 0_38 */
-#define CONFIG_STAT0		0x00E4	/* Dword offset 0_39 */
+#define CNFG_CNTL		0x00DC	/* Dword offset 0_37 (CT, ET, VT) */
+#define CNFG_CHIP_ID		0x00E0	/* Dword offset 0_38 */
+#define CNFG_STAT0		0x00E4	/* Dword offset 0_39 */
 
 /* Test and Debug */
 #define CRC_SIG			0x00E8	/* Dword offset 0_3A */
@@ -851,17 +851,17 @@
 #define PLL_YCLK_CNTL		0x29
 #define PM_DYN_CLK_CNTL		0x2A
 
-/* CONFIG_CNTL register constants */
+/* CNFG_CNTL register constants */
 #define APERTURE_4M_ENABLE	1
 #define APERTURE_8M_ENABLE	2
 #define VGA_APERTURE_ENABLE	4
 
-/* CONFIG_STAT0 register constants (GX, CX) */
+/* CNFG_STAT0 register constants (GX, CX) */
 #define CFG_BUS_TYPE		0x00000007
 #define CFG_MEM_TYPE		0x00000038
 #define CFG_INIT_DAC_TYPE	0x00000e00
 
-/* CONFIG_STAT0 register constants (CT, ET, VT) */
+/* CNFG_STAT0 register constants (CT, ET, VT) */
 #define CFG_MEM_TYPE_xT		0x00000007
 
 #define ISA			0
@@ -942,7 +942,7 @@
 #define PCI_ATI_VENDOR_ID	0x1002
 
 
-/* CONFIG_CHIP_ID register constants */
+/* CNFG_CHIP_ID register constants */
 #define CFG_CHIP_TYPE		0x0000FFFF
 #define CFG_CHIP_CLASS		0x00FF0000
 #define CFG_CHIP_REV		0xFF000000
@@ -951,7 +951,7 @@
 #define CFG_CHIP_MINOR		0xC0000000
 
 
-/* Chip IDs read from CONFIG_CHIP_ID */
+/* Chip IDs read from CNFG_CHIP_ID */
 
 /* mach64GX family */
 #define GX_CHIP_ID	0xD7	/* mach64GX (ATI888GX00) */
@@ -1254,7 +1254,7 @@
 #define CRTC2_DISPLAY_DIS	0x00000400
 
 /* LCD register indices */
-#define CONFIG_PANEL		0x00
+#define CNFG_PANEL		0x00
 #define LCD_GEN_CNTL		0x01
 #define DSTN_CONTROL		0x02
 #define HFB_PITCH_ADDR		0x03
diff --git a/include/video/radeon.h b/include/video/radeon.h
index 1cd09cc5b169..e072b16b39ab 100644
--- a/include/video/radeon.h
+++ b/include/video/radeon.h
@@ -11,13 +11,13 @@
 #define HI_STAT                                0x004C  
 #define BUS_CNTL1                              0x0034
 #define I2C_CNTL_1			       0x0094  
-#define CONFIG_CNTL                            0x00E0  
-#define CONFIG_MEMSIZE                         0x00F8  
-#define CONFIG_APER_0_BASE                     0x0100  
-#define CONFIG_APER_1_BASE                     0x0104  
-#define CONFIG_APER_SIZE                       0x0108  
-#define CONFIG_REG_1_BASE                      0x010C  
-#define CONFIG_REG_APER_SIZE                   0x0110  
+#define CNFG_CNTL                              0x00E0
+#define CNFG_MEMSIZE                           0x00F8
+#define CNFG_APER_0_BASE                       0x0100
+#define CNFG_APER_1_BASE                       0x0104
+#define CNFG_APER_SIZE                         0x0108
+#define CNFG_REG_1_BASE                        0x010C
+#define CNFG_REG_APER_SIZE                     0x0110
 #define PAD_AGPINPUT_DELAY                     0x0164  
 #define PAD_CTLR_STRENGTH                      0x0168  
 #define PAD_CTLR_UPDATE                        0x016C
@@ -509,7 +509,7 @@
 /* CLOCK_CNTL_INDEX bit constants */
 #define PLL_WR_EN                                  0x00000080
 
-/* CONFIG_CNTL bit constants */
+/* CNFG_CNTL bit constants */
 #define CFG_VGA_RAM_EN                             0x00000100
 #define CFG_ATI_REV_ID_MASK			   (0xf << 16)
 #define CFG_ATI_REV_A11				   (0 << 16)
@@ -980,7 +980,7 @@
 
 /* masks */
 
-#define CONFIG_MEMSIZE_MASK		0x1f000000
+#define CNFG_MEMSIZE_MASK		0x1f000000
 #define MEM_CFG_TYPE			0x40000000
 #define DST_OFFSET_MASK			0x003fffff
 #define DST_PITCH_MASK			0x3fc00000
diff --git a/include/video/sisfb.h b/include/video/sisfb.h
index e402eb5b3c7a..fdd74f1a6791 100644
--- a/include/video/sisfb.h
+++ b/include/video/sisfb.h
@@ -21,8 +21,8 @@
 #ifndef _LINUX_SISFB_H_
 #define _LINUX_SISFB_H_
 
+#include <linux/types.h>
 #include <asm/ioctl.h>
-#include <asm/types.h>
 
 /**********************************************/
 /*                   PUBLIC                   */
diff --git a/include/video/uvesafb.h b/include/video/uvesafb.h
index 95bcef193954..0993a220a3e6 100644
--- a/include/video/uvesafb.h
+++ b/include/video/uvesafb.h
@@ -1,6 +1,8 @@
 #ifndef _UVESAFB_H
 #define _UVESAFB_H
 
+#include <linux/types.h>
+
 struct v86_regs {
 	__u32 ebx;
 	__u32 ecx;
diff --git a/ipc/shm.c b/ipc/shm.c
index a9e09ad2263e..f8f69fad3a27 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -368,14 +368,14 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
 		file = hugetlb_file_setup(name, size);
 		shp->mlock_user = current_user();
 	} else {
-		int acctflag = VM_ACCOUNT;
+		int acctflag = 0;
 		/*
 		 * Do not allow no accounting for OVERCOMMIT_NEVER, even
 	 	 * if it's asked for.
 		 */
 		if  ((shmflg & SHM_NORESERVE) &&
 				sysctl_overcommit_memory != OVERCOMMIT_NEVER)
-			acctflag = 0;
+			acctflag = VM_NORESERVE;
 		file = shmem_file_setup(name, size, acctflag);
 	}
 	error = PTR_ERR(file);
@@ -565,11 +565,15 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
 			struct hstate *h = hstate_file(shp->shm_file);
 			*rss += pages_per_huge_page(h) * mapping->nrpages;
 		} else {
+#ifdef CONFIG_SHMEM
 			struct shmem_inode_info *info = SHMEM_I(inode);
 			spin_lock(&info->lock);
 			*rss += inode->i_mapping->nrpages;
 			*swp += info->swapped;
 			spin_unlock(&info->lock);
+#else
+			*rss += inode->i_mapping->nrpages;
+#endif
 		}
 
 		total++;
diff --git a/kernel/async.c b/kernel/async.c
index 608b32b42812..f565891f2c9b 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -54,6 +54,7 @@ asynchronous and synchronous parts of the kernel.
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/kthread.h>
+#include <linux/delay.h>
 #include <asm/atomic.h>
 
 static async_cookie_t next_cookie = 1;
@@ -132,21 +133,23 @@ static void run_one_entry(void)
 	entry = list_first_entry(&async_pending, struct async_entry, list);
 
 	/* 2) move it to the running queue */
-	list_del(&entry->list);
-	list_add_tail(&entry->list, &async_running);
+	list_move_tail(&entry->list, entry->running);
 	spin_unlock_irqrestore(&async_lock, flags);
 
 	/* 3) run it (and print duration)*/
 	if (initcall_debug && system_state == SYSTEM_BOOTING) {
-		printk("calling  %lli_%pF @ %i\n", entry->cookie, entry->func, task_pid_nr(current));
+		printk("calling  %lli_%pF @ %i\n", (long long)entry->cookie,
+			entry->func, task_pid_nr(current));
 		calltime = ktime_get();
 	}
 	entry->func(entry->data, entry->cookie);
 	if (initcall_debug && system_state == SYSTEM_BOOTING) {
 		rettime = ktime_get();
 		delta = ktime_sub(rettime, calltime);
-		printk("initcall %lli_%pF returned 0 after %lld usecs\n", entry->cookie,
-			entry->func, ktime_to_ns(delta) >> 10);
+		printk("initcall %lli_%pF returned 0 after %lld usecs\n",
+			(long long)entry->cookie,
+			entry->func,
+			(long long)ktime_to_ns(delta) >> 10);
 	}
 
 	/* 4) remove it from the running queue */
@@ -205,18 +208,44 @@ static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct l
 	return newcookie;
 }
 
+/**
+ * async_schedule - schedule a function for asynchronous execution
+ * @ptr: function to execute asynchronously
+ * @data: data pointer to pass to the function
+ *
+ * Returns an async_cookie_t that may be used for checkpointing later.
+ * Note: This function may be called from atomic or non-atomic contexts.
+ */
 async_cookie_t async_schedule(async_func_ptr *ptr, void *data)
 {
-	return __async_schedule(ptr, data, &async_pending);
+	return __async_schedule(ptr, data, &async_running);
 }
 EXPORT_SYMBOL_GPL(async_schedule);
 
-async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *running)
+/**
+ * async_schedule_domain - schedule a function for asynchronous execution within a certain domain
+ * @ptr: function to execute asynchronously
+ * @data: data pointer to pass to the function
+ * @running: running list for the domain
+ *
+ * Returns an async_cookie_t that may be used for checkpointing later.
+ * @running may be used in the async_synchronize_*_domain() functions
+ * to wait within a certain synchronization domain rather than globally.
+ * A synchronization domain is specified via the running queue @running to use.
+ * Note: This function may be called from atomic or non-atomic contexts.
+ */
+async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data,
+				     struct list_head *running)
 {
 	return __async_schedule(ptr, data, running);
 }
-EXPORT_SYMBOL_GPL(async_schedule_special);
+EXPORT_SYMBOL_GPL(async_schedule_domain);
 
+/**
+ * async_synchronize_full - synchronize all asynchronous function calls
+ *
+ * This function waits until all asynchronous function calls have been done.
+ */
 void async_synchronize_full(void)
 {
 	do {
@@ -225,13 +254,30 @@ void async_synchronize_full(void)
 }
 EXPORT_SYMBOL_GPL(async_synchronize_full);
 
-void async_synchronize_full_special(struct list_head *list)
+/**
+ * async_synchronize_full_domain - synchronize all asynchronous function within a certain domain
+ * @list: running list to synchronize on
+ *
+ * This function waits until all asynchronous function calls for the
+ * synchronization domain specified by the running list @list have been done.
+ */
+void async_synchronize_full_domain(struct list_head *list)
 {
-	async_synchronize_cookie_special(next_cookie, list);
+	async_synchronize_cookie_domain(next_cookie, list);
 }
-EXPORT_SYMBOL_GPL(async_synchronize_full_special);
+EXPORT_SYMBOL_GPL(async_synchronize_full_domain);
 
-void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *running)
+/**
+ * async_synchronize_cookie_domain - synchronize asynchronous function calls within a certain domain with cookie checkpointing
+ * @cookie: async_cookie_t to use as checkpoint
+ * @running: running list to synchronize on
+ *
+ * This function waits until all asynchronous function calls for the
+ * synchronization domain specified by the running list @list submitted
+ * prior to @cookie have been done.
+ */
+void async_synchronize_cookie_domain(async_cookie_t cookie,
+				     struct list_head *running)
 {
 	ktime_t starttime, delta, endtime;
 
@@ -247,14 +293,22 @@ void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *r
 		delta = ktime_sub(endtime, starttime);
 
 		printk("async_continuing @ %i after %lli usec\n",
-			task_pid_nr(current), ktime_to_ns(delta) >> 10);
+			task_pid_nr(current),
+			(long long)ktime_to_ns(delta) >> 10);
 	}
 }
-EXPORT_SYMBOL_GPL(async_synchronize_cookie_special);
+EXPORT_SYMBOL_GPL(async_synchronize_cookie_domain);
 
+/**
+ * async_synchronize_cookie - synchronize asynchronous function calls with cookie checkpointing
+ * @cookie: async_cookie_t to use as checkpoint
+ *
+ * This function waits until all asynchronous function calls prior to @cookie
+ * have been done.
+ */
 void async_synchronize_cookie(async_cookie_t cookie)
 {
-	async_synchronize_cookie_special(cookie, &async_running);
+	async_synchronize_cookie_domain(cookie, &async_running);
 }
 EXPORT_SYMBOL_GPL(async_synchronize_cookie);
 
@@ -315,7 +369,11 @@ static int async_manager_thread(void *unused)
 		ec = atomic_read(&entry_count);
 
 		while (tc < ec && tc < MAX_THREADS) {
-			kthread_run(async_thread, NULL, "async/%i", tc);
+			if (IS_ERR(kthread_run(async_thread, NULL, "async/%i",
+					       tc))) {
+				msleep(100);
+				continue;
+			}
 			atomic_inc(&thread_count);
 			tc++;
 		}
@@ -330,7 +388,9 @@ static int async_manager_thread(void *unused)
 static int __init async_init(void)
 {
 	if (async_enabled)
-		kthread_run(async_manager_thread, NULL, "async/mgr");
+		if (IS_ERR(kthread_run(async_manager_thread, NULL,
+				       "async/mgr")))
+			async_enabled = 0;
 	return 0;
 }
 
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index a85678865c5e..f76db9dcaa05 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -61,6 +61,14 @@
 #include <linux/cgroup.h>
 
 /*
+ * Workqueue for cpuset related tasks.
+ *
+ * Using kevent workqueue may cause deadlock when memory_migrate
+ * is set. So we create a separate workqueue thread for cpuset.
+ */
+static struct workqueue_struct *cpuset_wq;
+
+/*
  * Tracks how many cpusets are currently defined in system.
  * When there is only one cpuset (the root cpuset) we can
  * short circuit some hooks.
@@ -831,7 +839,7 @@ static DECLARE_WORK(rebuild_sched_domains_work, do_rebuild_sched_domains);
  */
 static void async_rebuild_sched_domains(void)
 {
-	schedule_work(&rebuild_sched_domains_work);
+	queue_work(cpuset_wq, &rebuild_sched_domains_work);
 }
 
 /*
@@ -2111,6 +2119,9 @@ void __init cpuset_init_smp(void)
 
 	hotcpu_notifier(cpuset_track_online_cpus, 0);
 	hotplug_memory_notifier(cpuset_track_online_nodes, 10);
+
+	cpuset_wq = create_singlethread_workqueue("cpuset");
+	BUG_ON(!cpuset_wq);
 }
 
 /**
diff --git a/kernel/fork.c b/kernel/fork.c
index 99309df985bf..c078438ba6fc 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1010,6 +1010,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 	 * triggers too late. This doesn't hurt, the check is only there
 	 * to stop root fork bombs.
 	 */
+	retval = -EAGAIN;
 	if (nr_threads >= max_threads)
 		goto bad_fork_cleanup_count;
 
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index f33afb0407bc..f394d2a42ca3 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -501,6 +501,13 @@ static void hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base)
 			continue;
 		timer = rb_entry(base->first, struct hrtimer, node);
 		expires = ktime_sub(hrtimer_get_expires(timer), base->offset);
+		/*
+		 * clock_was_set() has changed base->offset so the
+		 * result might be negative. Fix it up to prevent a
+		 * false positive in clockevents_program_event()
+		 */
+		if (expires.tv64 < 0)
+			expires.tv64 = 0;
 		if (expires.tv64 < cpu_base->expires_next.tv64)
 			cpu_base->expires_next = expires;
 	}
@@ -1158,6 +1165,29 @@ static void __run_hrtimer(struct hrtimer *timer)
 
 #ifdef CONFIG_HIGH_RES_TIMERS
 
+static int force_clock_reprogram;
+
+/*
+ * After 5 iteration's attempts, we consider that hrtimer_interrupt()
+ * is hanging, which could happen with something that slows the interrupt
+ * such as the tracing. Then we force the clock reprogramming for each future
+ * hrtimer interrupts to avoid infinite loops and use the min_delta_ns
+ * threshold that we will overwrite.
+ * The next tick event will be scheduled to 3 times we currently spend on
+ * hrtimer_interrupt(). This gives a good compromise, the cpus will spend
+ * 1/4 of their time to process the hrtimer interrupts. This is enough to
+ * let it running without serious starvation.
+ */
+
+static inline void
+hrtimer_interrupt_hanging(struct clock_event_device *dev,
+			ktime_t try_time)
+{
+	force_clock_reprogram = 1;
+	dev->min_delta_ns = (unsigned long)try_time.tv64 * 3;
+	printk(KERN_WARNING "hrtimer: interrupt too slow, "
+		"forcing clock min delta to %lu ns\n", dev->min_delta_ns);
+}
 /*
  * High resolution timer interrupt
  * Called with interrupts disabled
@@ -1167,6 +1197,7 @@ void hrtimer_interrupt(struct clock_event_device *dev)
 	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
 	struct hrtimer_clock_base *base;
 	ktime_t expires_next, now;
+	int nr_retries = 0;
 	int i;
 
 	BUG_ON(!cpu_base->hres_active);
@@ -1174,6 +1205,10 @@ void hrtimer_interrupt(struct clock_event_device *dev)
 	dev->next_event.tv64 = KTIME_MAX;
 
  retry:
+	/* 5 retries is enough to notice a hang */
+	if (!(++nr_retries % 5))
+		hrtimer_interrupt_hanging(dev, ktime_sub(ktime_get(), now));
+
 	now = ktime_get();
 
 	expires_next.tv64 = KTIME_MAX;
@@ -1226,7 +1261,7 @@ void hrtimer_interrupt(struct clock_event_device *dev)
 
 	/* Reprogramming necessary ? */
 	if (expires_next.tv64 != KTIME_MAX) {
-		if (tick_program_event(expires_next, 0))
+		if (tick_program_event(expires_next, force_clock_reprogram))
 			goto retry;
 	}
 }
@@ -1580,6 +1615,10 @@ static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self,
 		break;
 
 #ifdef CONFIG_HOTPLUG_CPU
+	case CPU_DYING:
+	case CPU_DYING_FROZEN:
+		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DYING, &scpu);
+		break;
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
 	{
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index c248eba98b43..122fef4b0bd3 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -386,6 +386,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
 out_unlock:
 	spin_unlock(&desc->lock);
 }
+EXPORT_SYMBOL_GPL(handle_level_irq);
 
 /**
  *	handle_fasteoi_irq - irq handler for transparent controllers
@@ -596,6 +597,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
 	}
 	spin_unlock_irqrestore(&desc->lock, flags);
 }
+EXPORT_SYMBOL_GPL(__set_irq_handler);
 
 void
 set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c
index 666260e4c065..7f9b80434e32 100644
--- a/kernel/irq/numa_migrate.c
+++ b/kernel/irq/numa_migrate.c
@@ -78,7 +78,7 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
 	desc = irq_desc_ptrs[irq];
 
 	if (desc && old_desc != desc)
-			goto out_unlock;
+		goto out_unlock;
 
 	node = cpu_to_node(cpu);
 	desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
@@ -97,10 +97,15 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
 	}
 
 	irq_desc_ptrs[irq] = desc;
+	spin_unlock_irqrestore(&sparse_irq_lock, flags);
 
 	/* free the old one */
 	free_one_irq_desc(old_desc, desc);
+	spin_unlock(&old_desc->lock);
 	kfree(old_desc);
+	spin_lock(&desc->lock);
+
+	return desc;
 
 out_unlock:
 	spin_unlock_irqrestore(&sparse_irq_lock, flags);
diff --git a/kernel/module.c b/kernel/module.c
index e8b51d41dd72..ba22484a987e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -573,13 +573,13 @@ static char last_unloaded_module[MODULE_NAME_LEN+1];
 /* Init the unload section of the module. */
 static void module_unload_init(struct module *mod)
 {
-	unsigned int i;
+	int cpu;
 
 	INIT_LIST_HEAD(&mod->modules_which_use_me);
-	for (i = 0; i < NR_CPUS; i++)
-		local_set(&mod->ref[i].count, 0);
+	for_each_possible_cpu(cpu)
+		local_set(__module_ref_addr(mod, cpu), 0);
 	/* Hold reference count during initialization. */
-	local_set(&mod->ref[raw_smp_processor_id()].count, 1);
+	local_set(__module_ref_addr(mod, raw_smp_processor_id()), 1);
 	/* Backwards compatibility macros put refcount during init. */
 	mod->waiter = current;
 }
@@ -717,10 +717,11 @@ static int try_stop_module(struct module *mod, int flags, int *forced)
 
 unsigned int module_refcount(struct module *mod)
 {
-	unsigned int i, total = 0;
+	unsigned int total = 0;
+	int cpu;
 
-	for (i = 0; i < NR_CPUS; i++)
-		total += local_read(&mod->ref[i].count);
+	for_each_possible_cpu(cpu)
+		total += local_read(__module_ref_addr(mod, cpu));
 	return total;
 }
 EXPORT_SYMBOL(module_refcount);
@@ -894,7 +895,7 @@ void module_put(struct module *module)
 {
 	if (module) {
 		unsigned int cpu = get_cpu();
-		local_dec(&module->ref[cpu].count);
+		local_dec(__module_ref_addr(module, cpu));
 		/* Maybe they're waiting for us to drop reference? */
 		if (unlikely(!module_is_live(module)))
 			wake_up_process(module->waiter);
@@ -1464,7 +1465,10 @@ static void free_module(struct module *mod)
 	kfree(mod->args);
 	if (mod->percpu)
 		percpu_modfree(mod->percpu);
-
+#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
+	if (mod->refptr)
+		percpu_modfree(mod->refptr);
+#endif
 	/* Free lock-classes: */
 	lockdep_free_key_range(mod->module_core, mod->core_size);
 
@@ -2011,6 +2015,14 @@ static noinline struct module *load_module(void __user *umod,
 	if (err < 0)
 		goto free_mod;
 
+#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
+	mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t),
+				      mod->name);
+	if (!mod->refptr) {
+		err = -ENOMEM;
+		goto free_mod;
+	}
+#endif
 	if (pcpuindex) {
 		/* We have a special allocation for this section. */
 		percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size,
@@ -2018,7 +2030,7 @@ static noinline struct module *load_module(void __user *umod,
 					 mod->name);
 		if (!percpu) {
 			err = -ENOMEM;
-			goto free_mod;
+			goto free_percpu;
 		}
 		sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
 		mod->percpu = percpu;
@@ -2282,6 +2294,9 @@ static noinline struct module *load_module(void __user *umod,
  free_percpu:
 	if (percpu)
 		percpu_modfree(percpu);
+#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
+	percpu_modfree(mod->refptr);
+#endif
  free_mod:
 	kfree(args);
  free_hdr:
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 239988873971..b4d219016b6c 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -57,16 +57,6 @@ int pm_notifier_call_chain(unsigned long val)
 #ifdef CONFIG_PM_DEBUG
 int pm_test_level = TEST_NONE;
 
-static int suspend_test(int level)
-{
-	if (pm_test_level == level) {
-		printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n");
-		mdelay(5000);
-		return 1;
-	}
-	return 0;
-}
-
 static const char * const pm_tests[__TEST_AFTER_LAST] = {
 	[TEST_NONE] = "none",
 	[TEST_CORE] = "core",
@@ -125,14 +115,24 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
 }
 
 power_attr(pm_test);
-#else /* !CONFIG_PM_DEBUG */
-static inline int suspend_test(int level) { return 0; }
-#endif /* !CONFIG_PM_DEBUG */
+#endif /* CONFIG_PM_DEBUG */
 
 #endif /* CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_SUSPEND
 
+static int suspend_test(int level)
+{
+#ifdef CONFIG_PM_DEBUG
+	if (pm_test_level == level) {
+		printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n");
+		mdelay(5000);
+		return 1;
+	}
+#endif /* !CONFIG_PM_DEBUG */
+	return 0;
+}
+
 #ifdef CONFIG_PM_TEST_SUSPEND
 
 /*
diff --git a/kernel/sched.c b/kernel/sched.c
index c71d7d501edb..fc17fd91ab57 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2266,6 +2266,16 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
 	if (!sched_feat(SYNC_WAKEUPS))
 		sync = 0;
 
+	if (!sync) {
+		if (current->se.avg_overlap < sysctl_sched_migration_cost &&
+			  p->se.avg_overlap < sysctl_sched_migration_cost)
+			sync = 1;
+	} else {
+		if (current->se.avg_overlap >= sysctl_sched_migration_cost ||
+			  p->se.avg_overlap >= sysctl_sched_migration_cost)
+			sync = 0;
+	}
+
 #ifdef CONFIG_SMP
 	if (sched_feat(LB_WAKEUP_UPDATE)) {
 		struct sched_domain *sd;
@@ -4687,8 +4697,8 @@ EXPORT_SYMBOL(default_wake_function);
  * started to run but is not in state TASK_RUNNING. try_to_wake_up() returns
  * zero in this (rare) case, and we handle it by continuing to scan the queue.
  */
-static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
-			     int nr_exclusive, int sync, void *key)
+void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
+			int nr_exclusive, int sync, void *key)
 {
 	wait_queue_t *curr, *next;
 
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 5cc1c162044f..a7e50ba185ac 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -719,7 +719,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
 		__enqueue_entity(cfs_rq, se);
 }
 
-static void clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se)
+static void __clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
 	if (cfs_rq->last == se)
 		cfs_rq->last = NULL;
@@ -728,6 +728,12 @@ static void clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se)
 		cfs_rq->next = NULL;
 }
 
+static void clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se)
+{
+	for_each_sched_entity(se)
+		__clear_buddies(cfs_rq_of(se), se);
+}
+
 static void
 dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
 {
@@ -768,8 +774,14 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr)
 
 	ideal_runtime = sched_slice(cfs_rq, curr);
 	delta_exec = curr->sum_exec_runtime - curr->prev_sum_exec_runtime;
-	if (delta_exec > ideal_runtime)
+	if (delta_exec > ideal_runtime) {
 		resched_task(rq_of(cfs_rq)->curr);
+		/*
+		 * The current task ran long enough, ensure it doesn't get
+		 * re-elected due to buddy favours.
+		 */
+		clear_buddies(cfs_rq, curr);
+	}
 }
 
 static void
@@ -1179,20 +1191,15 @@ wake_affine(struct sched_domain *this_sd, struct rq *this_rq,
 	    int idx, unsigned long load, unsigned long this_load,
 	    unsigned int imbalance)
 {
-	struct task_struct *curr = this_rq->curr;
-	struct task_group *tg;
 	unsigned long tl = this_load;
 	unsigned long tl_per_task;
+	struct task_group *tg;
 	unsigned long weight;
 	int balanced;
 
 	if (!(this_sd->flags & SD_WAKE_AFFINE) || !sched_feat(AFFINE_WAKEUPS))
 		return 0;
 
-	if (sync && (curr->se.avg_overlap > sysctl_sched_migration_cost ||
-			p->se.avg_overlap > sysctl_sched_migration_cost))
-		sync = 0;
-
 	/*
 	 * If sync wakeup then subtract the (maximum possible)
 	 * effect of the currently running task from the load
@@ -1419,9 +1426,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
 	if (!sched_feat(WAKEUP_PREEMPT))
 		return;
 
-	if (sched_feat(WAKEUP_OVERLAP) && (sync ||
-			(se->avg_overlap < sysctl_sched_migration_cost &&
-			 pse->avg_overlap < sysctl_sched_migration_cost))) {
+	if (sched_feat(WAKEUP_OVERLAP) && sync) {
 		resched_task(curr);
 		return;
 	}
@@ -1452,6 +1457,11 @@ static struct task_struct *pick_next_task_fair(struct rq *rq)
 
 	do {
 		se = pick_next_entity(cfs_rq);
+		/*
+		 * If se was a buddy, clear it so that it will have to earn
+		 * the favour again.
+		 */
+		__clear_buddies(cfs_rq, se);
 		set_next_entity(cfs_rq, se);
 		cfs_rq = group_cfs_rq(se);
 	} while (cfs_rq);
diff --git a/kernel/signal.c b/kernel/signal.c
index e73759783dc8..b6b36768b758 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -909,7 +909,9 @@ static void print_fatal_signal(struct pt_regs *regs, int signr)
 	}
 #endif
 	printk("\n");
+	preempt_disable();
 	show_regs(regs);
+	preempt_enable();
 }
 
 static int __init setup_print_fatal_signals(char *str)
diff --git a/kernel/smp.c b/kernel/smp.c
index 5cfa0e5e3e88..bbedbb7efe32 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -18,6 +18,7 @@ __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_function_lock);
 enum {
 	CSD_FLAG_WAIT		= 0x01,
 	CSD_FLAG_ALLOC		= 0x02,
+	CSD_FLAG_LOCK		= 0x04,
 };
 
 struct call_function_data {
@@ -186,6 +187,9 @@ void generic_smp_call_function_single_interrupt(void)
 			if (data_flags & CSD_FLAG_WAIT) {
 				smp_wmb();
 				data->flags &= ~CSD_FLAG_WAIT;
+			} else if (data_flags & CSD_FLAG_LOCK) {
+				smp_wmb();
+				data->flags &= ~CSD_FLAG_LOCK;
 			} else if (data_flags & CSD_FLAG_ALLOC)
 				kfree(data);
 		}
@@ -196,6 +200,8 @@ void generic_smp_call_function_single_interrupt(void)
 	}
 }
 
+static DEFINE_PER_CPU(struct call_single_data, csd_data);
+
 /*
  * smp_call_function_single - Run a function on a specific CPU
  * @func: The function to run. This must be fast and non-blocking.
@@ -224,14 +230,38 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
 		func(info);
 		local_irq_restore(flags);
 	} else if ((unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) {
-		struct call_single_data *data = NULL;
+		struct call_single_data *data;
 
 		if (!wait) {
+			/*
+			 * We are calling a function on a single CPU
+			 * and we are not going to wait for it to finish.
+			 * We first try to allocate the data, but if we
+			 * fail, we fall back to use a per cpu data to pass
+			 * the information to that CPU. Since all callers
+			 * of this code will use the same data, we must
+			 * synchronize the callers to prevent a new caller
+			 * from corrupting the data before the callee
+			 * can access it.
+			 *
+			 * The CSD_FLAG_LOCK is used to let us know when
+			 * the IPI handler is done with the data.
+			 * The first caller will set it, and the callee
+			 * will clear it. The next caller must wait for
+			 * it to clear before we set it again. This
+			 * will make sure the callee is done with the
+			 * data before a new caller will use it.
+			 */
 			data = kmalloc(sizeof(*data), GFP_ATOMIC);
 			if (data)
 				data->flags = CSD_FLAG_ALLOC;
-		}
-		if (!data) {
+			else {
+				data = &per_cpu(csd_data, me);
+				while (data->flags & CSD_FLAG_LOCK)
+					cpu_relax();
+				data->flags = CSD_FLAG_LOCK;
+			}
+		} else {
 			data = &d;
 			data->flags = CSD_FLAG_WAIT;
 		}
diff --git a/kernel/sys.c b/kernel/sys.c
index e7dc0e10a485..f145c415bc16 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1525,22 +1525,14 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
 		return -EINVAL;
 	if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
 		return -EFAULT;
+	if (new_rlim.rlim_cur > new_rlim.rlim_max)
+		return -EINVAL;
 	old_rlim = current->signal->rlim + resource;
 	if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
 	    !capable(CAP_SYS_RESOURCE))
 		return -EPERM;
-
-	if (resource == RLIMIT_NOFILE) {
-		if (new_rlim.rlim_max == RLIM_INFINITY)
-			new_rlim.rlim_max = sysctl_nr_open;
-		if (new_rlim.rlim_cur == RLIM_INFINITY)
-			new_rlim.rlim_cur = sysctl_nr_open;
-		if (new_rlim.rlim_max > sysctl_nr_open)
-			return -EPERM;
-	}
-
-	if (new_rlim.rlim_cur > new_rlim.rlim_max)
-		return -EINVAL;
+	if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
+		return -EPERM;
 
 	retval = security_task_setrlimit(resource, &new_rlim);
 	if (retval)
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 63e05d423a09..21a5ca849514 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -274,6 +274,21 @@ out_bc:
 }
 
 /*
+ * Transfer the do_timer job away from a dying cpu.
+ *
+ * Called with interrupts disabled.
+ */
+static void tick_handover_do_timer(int *cpup)
+{
+	if (*cpup == tick_do_timer_cpu) {
+		int cpu = cpumask_first(cpu_online_mask);
+
+		tick_do_timer_cpu = (cpu < nr_cpu_ids) ? cpu :
+			TICK_DO_TIMER_NONE;
+	}
+}
+
+/*
  * Shutdown an event device on a given cpu:
  *
  * This is called on a life CPU, when a CPU is dead. So we cannot
@@ -297,13 +312,6 @@ static void tick_shutdown(unsigned int *cpup)
 		clockevents_exchange_device(dev, NULL);
 		td->evtdev = NULL;
 	}
-	/* Transfer the do_timer job away from this cpu */
-	if (*cpup == tick_do_timer_cpu) {
-		int cpu = cpumask_first(cpu_online_mask);
-
-		tick_do_timer_cpu = (cpu < nr_cpu_ids) ? cpu :
-			TICK_DO_TIMER_NONE;
-	}
 	spin_unlock_irqrestore(&tick_device_lock, flags);
 }
 
@@ -357,6 +365,10 @@ static int tick_notify(struct notifier_block *nb, unsigned long reason,
 		tick_broadcast_oneshot_control(reason);
 		break;
 
+	case CLOCK_EVT_NOTIFY_CPU_DYING:
+		tick_handover_do_timer(dev);
+		break;
+
 	case CLOCK_EVT_NOTIFY_CPU_DEAD:
 		tick_shutdown_broadcast_oneshot(dev);
 		tick_shutdown_broadcast(dev);
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 2f32969c09df..9a236ffe2aa4 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -17,6 +17,7 @@
 #include <linux/clocksource.h>
 #include <linux/kallsyms.h>
 #include <linux/seq_file.h>
+#include <linux/suspend.h>
 #include <linux/debugfs.h>
 #include <linux/hardirq.h>
 #include <linux/kthread.h>
@@ -1736,9 +1737,12 @@ static void clear_ftrace_pid(struct pid *pid)
 {
 	struct task_struct *p;
 
+	rcu_read_lock();
 	do_each_pid_task(pid, PIDTYPE_PID, p) {
 		clear_tsk_trace_trace(p);
 	} while_each_pid_task(pid, PIDTYPE_PID, p);
+	rcu_read_unlock();
+
 	put_pid(pid);
 }
 
@@ -1746,9 +1750,11 @@ static void set_ftrace_pid(struct pid *pid)
 {
 	struct task_struct *p;
 
+	rcu_read_lock();
 	do_each_pid_task(pid, PIDTYPE_PID, p) {
 		set_tsk_trace_trace(p);
 	} while_each_pid_task(pid, PIDTYPE_PID, p);
+	rcu_read_unlock();
 }
 
 static void clear_ftrace_pid_task(struct pid **pid)
@@ -1965,6 +1971,7 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 
 static atomic_t ftrace_graph_active;
+static struct notifier_block ftrace_suspend_notifier;
 
 int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
 {
@@ -2043,6 +2050,27 @@ static int start_graph_tracing(void)
 	return ret;
 }
 
+/*
+ * Hibernation protection.
+ * The state of the current task is too much unstable during
+ * suspend/restore to disk. We want to protect against that.
+ */
+static int
+ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state,
+							void *unused)
+{
+	switch (state) {
+	case PM_HIBERNATION_PREPARE:
+		pause_graph_tracing();
+		break;
+
+	case PM_POST_HIBERNATION:
+		unpause_graph_tracing();
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
 int register_ftrace_graph(trace_func_graph_ret_t retfunc,
 			trace_func_graph_ent_t entryfunc)
 {
@@ -2050,6 +2078,9 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc,
 
 	mutex_lock(&ftrace_sysctl_lock);
 
+	ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call;
+	register_pm_notifier(&ftrace_suspend_notifier);
+
 	atomic_inc(&ftrace_graph_active);
 	ret = start_graph_tracing();
 	if (ret) {
@@ -2075,6 +2106,7 @@ void unregister_ftrace_graph(void)
 	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);
 
 	mutex_unlock(&ftrace_sysctl_lock);
 }
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 8b0daf0662ef..bd38c5cfd8ad 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -246,7 +246,7 @@ static inline int test_time_stamp(u64 delta)
 	return 0;
 }
 
-#define BUF_PAGE_SIZE (PAGE_SIZE - sizeof(struct buffer_data_page))
+#define BUF_PAGE_SIZE (PAGE_SIZE - offsetof(struct buffer_data_page, data))
 
 /*
  * head_page == tail_page && head == tail then buffer is empty.
@@ -1025,12 +1025,8 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
 		}
 
 		if (next_page == head_page) {
-			if (!(buffer->flags & RB_FL_OVERWRITE)) {
-				/* reset write */
-				if (tail <= BUF_PAGE_SIZE)
-					local_set(&tail_page->write, tail);
+			if (!(buffer->flags & RB_FL_OVERWRITE))
 				goto out_unlock;
-			}
 
 			/* tail_page has not moved yet? */
 			if (tail_page == cpu_buffer->tail_page) {
@@ -1105,6 +1101,10 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
 	return event;
 
  out_unlock:
+	/* reset write */
+	if (tail <= BUF_PAGE_SIZE)
+		local_set(&tail_page->write, tail);
+
 	__raw_spin_unlock(&cpu_buffer->lock);
 	local_irq_restore(flags);
 	return NULL;
@@ -2174,6 +2174,9 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
 
 	cpu_buffer->overrun = 0;
 	cpu_buffer->entries = 0;
+
+	cpu_buffer->write_stamp = 0;
+	cpu_buffer->read_stamp = 0;
 }
 
 /**
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index c580233add95..17bb88d86ac2 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -40,7 +40,7 @@
 
 #define TRACE_BUFFER_FLAGS	(RB_FL_OVERWRITE)
 
-unsigned long __read_mostly	tracing_max_latency = (cycle_t)ULONG_MAX;
+unsigned long __read_mostly	tracing_max_latency;
 unsigned long __read_mostly	tracing_thresh;
 
 /*
@@ -3736,7 +3736,7 @@ static struct notifier_block trace_die_notifier = {
  * it if we decide to change what log level the ftrace dump
  * should be at.
  */
-#define KERN_TRACE		KERN_INFO
+#define KERN_TRACE		KERN_EMERG
 
 static void
 trace_printk_seq(struct trace_seq *s)
@@ -3770,6 +3770,7 @@ void ftrace_dump(void)
 	dump_ran = 1;
 
 	/* No turning back! */
+	tracing_off();
 	ftrace_kill();
 
 	for_each_tracing_cpu(cpu) {
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index 7c2e326bbc8b..62a78d943534 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -380,6 +380,7 @@ static void stop_irqsoff_tracer(struct trace_array *tr)
 
 static void __irqsoff_tracer_init(struct trace_array *tr)
 {
+	tracing_max_latency = 0;
 	irqsoff_trace = tr;
 	/* make sure that the tracer is visible */
 	smp_wmb();
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c
index 43586b689e31..42ae1e77b6b3 100644
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -333,6 +333,7 @@ static void stop_wakeup_tracer(struct trace_array *tr)
 
 static int wakeup_tracer_init(struct trace_array *tr)
 {
+	tracing_max_latency = 0;
 	wakeup_trace = tr;
 	start_wakeup_tracer(tr);
 	return 0;
diff --git a/kernel/wait.c b/kernel/wait.c
index cd87131f2fc2..42a2dbc181c8 100644
--- a/kernel/wait.c
+++ b/kernel/wait.c
@@ -91,6 +91,15 @@ prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state)
 }
 EXPORT_SYMBOL(prepare_to_wait_exclusive);
 
+/*
+ * finish_wait - clean up after waiting in a queue
+ * @q: waitqueue waited on
+ * @wait: wait descriptor
+ *
+ * Sets current thread back to running state and removes
+ * the wait descriptor from the given waitqueue if still
+ * queued.
+ */
 void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
 {
 	unsigned long flags;
@@ -117,6 +126,39 @@ void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
 }
 EXPORT_SYMBOL(finish_wait);
 
+/*
+ * abort_exclusive_wait - abort exclusive waiting in a queue
+ * @q: waitqueue waited on
+ * @wait: wait descriptor
+ * @state: runstate of the waiter to be woken
+ * @key: key to identify a wait bit queue or %NULL
+ *
+ * Sets current thread back to running state and removes
+ * the wait descriptor from the given waitqueue if still
+ * queued.
+ *
+ * Wakes up the next waiter if the caller is concurrently
+ * woken up through the queue.
+ *
+ * This prevents waiter starvation where an exclusive waiter
+ * aborts and is woken up concurrently and noone wakes up
+ * the next waiter.
+ */
+void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait,
+			unsigned int mode, void *key)
+{
+	unsigned long flags;
+
+	__set_current_state(TASK_RUNNING);
+	spin_lock_irqsave(&q->lock, flags);
+	if (!list_empty(&wait->task_list))
+		list_del_init(&wait->task_list);
+	else if (waitqueue_active(q))
+		__wake_up_common(q, mode, 1, 0, key);
+	spin_unlock_irqrestore(&q->lock, flags);
+}
+EXPORT_SYMBOL(abort_exclusive_wait);
+
 int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
 {
 	int ret = default_wake_function(wait, mode, sync, key);
@@ -177,17 +219,20 @@ int __sched
 __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q,
 			int (*action)(void *), unsigned mode)
 {
-	int ret = 0;
-
 	do {
+		int ret;
+
 		prepare_to_wait_exclusive(wq, &q->wait, mode);
-		if (test_bit(q->key.bit_nr, q->key.flags)) {
-			if ((ret = (*action)(q->key.flags)))
-				break;
-		}
+		if (!test_bit(q->key.bit_nr, q->key.flags))
+			continue;
+		ret = action(q->key.flags);
+		if (!ret)
+			continue;
+		abort_exclusive_wait(wq, &q->wait, mode, &q->key);
+		return ret;
 	} while (test_and_set_bit(q->key.bit_nr, q->key.flags));
 	finish_wait(wq, &q->wait);
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL(__wait_on_bit_lock);
 
diff --git a/mm/memory.c b/mm/memory.c
index 22bfa7a47a0b..baa999e87cd2 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1999,7 +1999,7 @@ gotten:
 	 * Don't let another task, with possibly unlocked vma,
 	 * keep the mlocked page.
 	 */
-	if (vma->vm_flags & VM_LOCKED) {
+	if ((vma->vm_flags & VM_LOCKED) && old_page) {
 		lock_page(old_page);	/* for LRU manipulation */
 		clear_page_mlock(old_page);
 		unlock_page(old_page);
diff --git a/mm/mlock.c b/mm/mlock.c
index 2904a347e476..028ec482fdd4 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -294,14 +294,10 @@ static inline int __mlock_posix_error_return(long retval)
  *
  * return number of pages [> 0] to be removed from locked_vm on success
  * of "special" vmas.
- *
- * return negative error if vma spanning @start-@range disappears while
- * mmap semaphore is dropped.  Unlikely?
  */
 long mlock_vma_pages_range(struct vm_area_struct *vma,
 			unsigned long start, unsigned long end)
 {
-	struct mm_struct *mm = vma->vm_mm;
 	int nr_pages = (end - start) / PAGE_SIZE;
 	BUG_ON(!(vma->vm_flags & VM_LOCKED));
 
@@ -314,20 +310,8 @@ long mlock_vma_pages_range(struct vm_area_struct *vma,
 	if (!((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) ||
 			is_vm_hugetlb_page(vma) ||
 			vma == get_gate_vma(current))) {
-		long error;
-		downgrade_write(&mm->mmap_sem);
-
-		error = __mlock_vma_pages_range(vma, start, end, 1);
 
-		up_read(&mm->mmap_sem);
-		/* vma can change or disappear */
-		down_write(&mm->mmap_sem);
-		vma = find_vma(mm, start);
-		/* non-NULL vma must contain @start, but need to check @end */
-		if (!vma ||  end > vma->vm_end)
-			return -ENOMEM;
-
-		return 0;	/* hide other errors from mmap(), et al */
+		return __mlock_vma_pages_range(vma, start, end, 1);
 	}
 
 	/*
@@ -438,41 +422,14 @@ success:
 	vma->vm_flags = newflags;
 
 	if (lock) {
-		/*
-		 * mmap_sem is currently held for write.  Downgrade the write
-		 * lock to a read lock so that other faults, mmap scans, ...
-		 * while we fault in all pages.
-		 */
-		downgrade_write(&mm->mmap_sem);
-
 		ret = __mlock_vma_pages_range(vma, start, end, 1);
 
-		/*
-		 * Need to reacquire mmap sem in write mode, as our callers
-		 * expect this.  We have no support for atomically upgrading
-		 * a sem to write, so we need to check for ranges while sem
-		 * is unlocked.
-		 */
-		up_read(&mm->mmap_sem);
-		/* vma can change or disappear */
-		down_write(&mm->mmap_sem);
-		*prev = find_vma(mm, start);
-		/* non-NULL *prev must contain @start, but need to check @end */
-		if (!(*prev) || end > (*prev)->vm_end)
-			ret = -ENOMEM;
-		else if (ret > 0) {
+		if (ret > 0) {
 			mm->locked_vm -= ret;
 			ret = 0;
 		} else
 			ret = __mlock_posix_error_return(ret); /* translate if needed */
 	} else {
-		/*
-		 * TODO:  for unlocking, pages will already be resident, so
-		 * we don't need to wait for allocations/reclaim/pagein, ...
-		 * However, unlocking a very large region can still take a
-		 * while.  Should we downgrade the semaphore for both lock
-		 * AND unlock ?
-		 */
 		__mlock_vma_pages_range(vma, start, end, 0);
 	}
 
diff --git a/mm/mmap.c b/mm/mmap.c
index c581df14d0de..214b6a258eeb 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1090,6 +1090,15 @@ int vma_wants_writenotify(struct vm_area_struct *vma)
 		mapping_cap_account_dirty(vma->vm_file->f_mapping);
 }
 
+/*
+ * We account for memory if it's a private writeable mapping,
+ * and VM_NORESERVE wasn't set.
+ */
+static inline int accountable_mapping(unsigned int vm_flags)
+{
+	return (vm_flags & (VM_NORESERVE | VM_SHARED | VM_WRITE)) == VM_WRITE;
+}
+
 unsigned long mmap_region(struct file *file, unsigned long addr,
 			  unsigned long len, unsigned long flags,
 			  unsigned int vm_flags, unsigned long pgoff,
@@ -1117,23 +1126,24 @@ munmap_back:
 	if (!may_expand_vm(mm, len >> PAGE_SHIFT))
 		return -ENOMEM;
 
-	if (flags & MAP_NORESERVE)
+	/*
+	 * Set 'VM_NORESERVE' if we should not account for the
+	 * memory use of this mapping. We only honor MAP_NORESERVE
+	 * if we're allowed to overcommit memory.
+	 */
+	if ((flags & MAP_NORESERVE) && sysctl_overcommit_memory != OVERCOMMIT_NEVER)
+		vm_flags |= VM_NORESERVE;
+	if (!accountable)
 		vm_flags |= VM_NORESERVE;
 
-	if (accountable && (!(flags & MAP_NORESERVE) ||
-			    sysctl_overcommit_memory == OVERCOMMIT_NEVER)) {
-		if (vm_flags & VM_SHARED) {
-			/* Check memory availability in shmem_file_setup? */
-			vm_flags |= VM_ACCOUNT;
-		} else if (vm_flags & VM_WRITE) {
-			/*
-			 * Private writable mapping: check memory availability
-			 */
-			charged = len >> PAGE_SHIFT;
-			if (security_vm_enough_memory(charged))
-				return -ENOMEM;
-			vm_flags |= VM_ACCOUNT;
-		}
+	/*
+	 * Private writable mapping: check memory availability
+	 */
+	if (accountable_mapping(vm_flags)) {
+		charged = len >> PAGE_SHIFT;
+		if (security_vm_enough_memory(charged))
+			return -ENOMEM;
+		vm_flags |= VM_ACCOUNT;
 	}
 
 	/*
@@ -1184,14 +1194,6 @@ munmap_back:
 			goto free_vma;
 	}
 
-	/* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
-	 * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
-	 * that memory reservation must be checked; but that reservation
-	 * belongs to shared memory object, not to vma: so now clear it.
-	 */
-	if ((vm_flags & (VM_SHARED|VM_ACCOUNT)) == (VM_SHARED|VM_ACCOUNT))
-		vma->vm_flags &= ~VM_ACCOUNT;
-
 	/* Can addr have changed??
 	 *
 	 * Answer: Yes, several device drivers can do it in their
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index b493db7841dc..dc32dae01e5f 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -1051,13 +1051,22 @@ continue_unlock:
 				}
  			}
 
-			if (wbc->sync_mode == WB_SYNC_NONE) {
-				wbc->nr_to_write--;
-				if (wbc->nr_to_write <= 0) {
-					done = 1;
-					break;
-				}
+			if (nr_to_write > 0)
+				nr_to_write--;
+			else if (wbc->sync_mode == WB_SYNC_NONE) {
+				/*
+				 * We stop writing back only if we are not
+				 * doing integrity sync. In case of integrity
+				 * sync we have to keep going because someone
+				 * may be concurrently dirtying pages, and we
+				 * might have synced a lot of newly appeared
+				 * dirty pages, but have not synced all of the
+				 * old dirty pages.
+				 */
+				done = 1;
+				break;
 			}
+
 			if (wbc->nonblocking && bdi_write_congested(bdi)) {
 				wbc->encountered_congestion = 1;
 				done = 1;
diff --git a/mm/shmem.c b/mm/shmem.c
index 5d0de96c9789..19d566ccdeea 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2628,7 +2628,7 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
 		goto close_file;
 
 #ifdef CONFIG_SHMEM
-	SHMEM_I(inode)->flags = flags & VM_ACCOUNT;
+	SHMEM_I(inode)->flags = (flags & VM_NORESERVE) ? 0 : VM_ACCOUNT;
 #endif
 	d_instantiate(dentry, inode);
 	inode->i_size = size;
diff --git a/mm/slub.c b/mm/slub.c
index 6392ae5cc6b1..bdc9abb08a23 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1996,7 +1996,7 @@ static struct kmem_cache_cpu *alloc_kmem_cache_cpu(struct kmem_cache *s,
 static void free_kmem_cache_cpu(struct kmem_cache_cpu *c, int cpu)
 {
 	if (c < per_cpu(kmem_cache_cpu, cpu) ||
-			c > per_cpu(kmem_cache_cpu, cpu) + NR_KMEM_CACHE_CPU) {
+			c >= per_cpu(kmem_cache_cpu, cpu) + NR_KMEM_CACHE_CPU) {
 		kfree(c);
 		return;
 	}
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 557fe16cbfb0..dda42f0bd7a3 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -663,14 +663,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 	th->urg_ptr		= 0;
 
 	/* The urg_mode check is necessary during a below snd_una win probe */
-	if (unlikely(tcp_urg_mode(tp))) {
-		if (between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF)) {
-			th->urg_ptr = htons(tp->snd_up - tcb->seq);
-			th->urg = 1;
-		} else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) {
-			th->urg_ptr = 0xFFFF;
-			th->urg = 1;
-		}
+	if (unlikely(tcp_urg_mode(tp) &&
+		     between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF))) {
+		th->urg_ptr		= htons(tp->snd_up - tcb->seq);
+		th->urg			= 1;
 	}
 
 	tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index b7faffe5c029..cc3a0a06c004 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1015,9 +1015,11 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 
 	if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) {
 		/* Note that an ENOMEM error is charged twice */
-		if (rc == -ENOMEM)
+		if (rc == -ENOMEM) {
 			UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS,
 					 is_udplite);
+			atomic_inc(&sk->sk_drops);
+		}
 		goto drop;
 	}
 
@@ -1229,7 +1231,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		   int proto)
 {
 	struct sock *sk;
-	struct udphdr *uh = udp_hdr(skb);
+	struct udphdr *uh;
 	unsigned short ulen;
 	struct rtable *rt = (struct rtable*)skb->dst;
 	__be32 saddr = ip_hdr(skb)->saddr;
@@ -1242,6 +1244,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 	if (!pskb_may_pull(skb, sizeof(struct udphdr)))
 		goto drop;		/* No space for header. */
 
+	uh   = udp_hdr(skb);
 	ulen = ntohs(uh->len);
 	if (ulen > skb->len)
 		goto short_packet;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 4b15938bef4d..9fb49c3b518a 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1105,6 +1105,18 @@ static inline int ip6_ufo_append_data(struct sock *sk,
 	return err;
 }
 
+static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src,
+					       gfp_t gfp)
+{
+	return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL;
+}
+
+static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src,
+						gfp_t gfp)
+{
+	return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL;
+}
+
 int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
 	int offset, int len, int odd, struct sk_buff *skb),
 	void *from, int length, int transhdrlen,
@@ -1130,17 +1142,37 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
 		 * setup for corking
 		 */
 		if (opt) {
-			if (np->cork.opt == NULL) {
-				np->cork.opt = kmalloc(opt->tot_len,
-						       sk->sk_allocation);
-				if (unlikely(np->cork.opt == NULL))
-					return -ENOBUFS;
-			} else if (np->cork.opt->tot_len < opt->tot_len) {
-				printk(KERN_DEBUG "ip6_append_data: invalid option length\n");
+			if (WARN_ON(np->cork.opt))
 				return -EINVAL;
-			}
-			memcpy(np->cork.opt, opt, opt->tot_len);
-			inet->cork.flags |= IPCORK_OPT;
+
+			np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation);
+			if (unlikely(np->cork.opt == NULL))
+				return -ENOBUFS;
+
+			np->cork.opt->tot_len = opt->tot_len;
+			np->cork.opt->opt_flen = opt->opt_flen;
+			np->cork.opt->opt_nflen = opt->opt_nflen;
+
+			np->cork.opt->dst0opt = ip6_opt_dup(opt->dst0opt,
+							    sk->sk_allocation);
+			if (opt->dst0opt && !np->cork.opt->dst0opt)
+				return -ENOBUFS;
+
+			np->cork.opt->dst1opt = ip6_opt_dup(opt->dst1opt,
+							    sk->sk_allocation);
+			if (opt->dst1opt && !np->cork.opt->dst1opt)
+				return -ENOBUFS;
+
+			np->cork.opt->hopopt = ip6_opt_dup(opt->hopopt,
+							   sk->sk_allocation);
+			if (opt->hopopt && !np->cork.opt->hopopt)
+				return -ENOBUFS;
+
+			np->cork.opt->srcrt = ip6_rthdr_dup(opt->srcrt,
+							    sk->sk_allocation);
+			if (opt->srcrt && !np->cork.opt->srcrt)
+				return -ENOBUFS;
+
 			/* need source address above miyazawa*/
 		}
 		dst_hold(&rt->u.dst);
@@ -1167,8 +1199,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
 	} else {
 		rt = (struct rt6_info *)inet->cork.dst;
 		fl = &inet->cork.fl;
-		if (inet->cork.flags & IPCORK_OPT)
-			opt = np->cork.opt;
+		opt = np->cork.opt;
 		transhdrlen = 0;
 		exthdrlen = 0;
 		mtu = inet->cork.fragsize;
@@ -1407,9 +1438,15 @@ error:
 
 static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np)
 {
-	inet->cork.flags &= ~IPCORK_OPT;
-	kfree(np->cork.opt);
-	np->cork.opt = NULL;
+	if (np->cork.opt) {
+		kfree(np->cork.opt->dst0opt);
+		kfree(np->cork.opt->dst1opt);
+		kfree(np->cork.opt->hopopt);
+		kfree(np->cork.opt->srcrt);
+		kfree(np->cork.opt);
+		np->cork.opt = NULL;
+	}
+
 	if (inet->cork.dst) {
 		dst_release(inet->cork.dst);
 		inet->cork.dst = NULL;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index d19a84b79503..228be551e9c1 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -48,6 +48,7 @@
 #include <linux/pim.h>
 #include <net/addrconf.h>
 #include <linux/netfilter_ipv6.h>
+#include <net/ip6_checksum.h>
 
 /* Big lock, protecting vif table, mrt cache and mroute socket state.
    Note that the changes are semaphored via rtnl_lock.
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 5f94db2f3e9e..1fc4a7885c41 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -77,6 +77,7 @@
 #include <linux/poll.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/mutex.h>
 
 #ifdef CONFIG_INET
 #include <net/inet_common.h>
@@ -175,6 +176,7 @@ struct packet_sock {
 #endif
 	struct packet_type	prot_hook;
 	spinlock_t		bind_lock;
+	struct mutex		pg_vec_lock;
 	unsigned int		running:1,	/* prot_hook is attached*/
 				auxdata:1,
 				origdev:1;
@@ -220,13 +222,13 @@ static void *packet_lookup_frame(struct packet_sock *po, unsigned int position,
 	h.raw = po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size);
 	switch (po->tp_version) {
 	case TPACKET_V1:
-		if (status != h.h1->tp_status ? TP_STATUS_USER :
-						TP_STATUS_KERNEL)
+		if (status != (h.h1->tp_status ? TP_STATUS_USER :
+						TP_STATUS_KERNEL))
 			return NULL;
 		break;
 	case TPACKET_V2:
-		if (status != h.h2->tp_status ? TP_STATUS_USER :
-						TP_STATUS_KERNEL)
+		if (status != (h.h2->tp_status ? TP_STATUS_USER :
+						TP_STATUS_KERNEL))
 			return NULL;
 		break;
 	}
@@ -1069,6 +1071,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol)
 	 */
 
 	spin_lock_init(&po->bind_lock);
+	mutex_init(&po->pg_vec_lock);
 	po->prot_hook.func = packet_rcv;
 
 	if (sock->type == SOCK_PACKET)
@@ -1865,6 +1868,7 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
 	synchronize_net();
 
 	err = -EBUSY;
+	mutex_lock(&po->pg_vec_lock);
 	if (closing || atomic_read(&po->mapped) == 0) {
 		err = 0;
 #define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; })
@@ -1886,6 +1890,7 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
 		if (atomic_read(&po->mapped))
 			printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n", atomic_read(&po->mapped));
 	}
+	mutex_unlock(&po->pg_vec_lock);
 
 	spin_lock(&po->bind_lock);
 	if (was_running && !po->running) {
@@ -1918,7 +1923,7 @@ static int packet_mmap(struct file *file, struct socket *sock, struct vm_area_st
 
 	size = vma->vm_end - vma->vm_start;
 
-	lock_sock(sk);
+	mutex_lock(&po->pg_vec_lock);
 	if (po->pg_vec == NULL)
 		goto out;
 	if (size != po->pg_vec_len*po->pg_vec_pages*PAGE_SIZE)
@@ -1941,7 +1946,7 @@ static int packet_mmap(struct file *file, struct socket *sock, struct vm_area_st
 	err = 0;
 
 out:
-	release_sock(sk);
+	mutex_unlock(&po->pg_vec_lock);
 	return err;
 }
 #endif
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index dcef600d0bf5..5592883e1e4a 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -6,7 +6,7 @@ config SUNRPC_GSS
 
 config SUNRPC_XPRT_RDMA
 	tristate
-	depends on SUNRPC && INFINIBAND && EXPERIMENTAL
+	depends on SUNRPC && INFINIBAND && INFINIBAND_ADDR_TRANS && EXPERIMENTAL
 	default SUNRPC && INFINIBAND
 	help
 	  This option allows the NFS client and server to support
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index e17836680f49..0a1798eafb0b 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1767,7 +1767,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
 		       AFMT_S8 | AFMT_U16_LE |
 		       AFMT_U16_BE |
 			AFMT_S32_LE | AFMT_S32_BE |
-			AFMT_S24_LE | AFMT_S24_LE |
+			AFMT_S24_LE | AFMT_S24_BE |
 			AFMT_S24_PACKED;
 	params = kmalloc(sizeof(*params), GFP_KERNEL);
 	if (!params)
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index b7bba7dc7cf1..0b708134d12f 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -487,7 +487,6 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
 {
 	struct hda_bus *bus;
 	int err;
-	char qname[8];
 	static struct snd_device_ops dev_ops = {
 		.dev_register = snd_hda_bus_dev_register,
 		.dev_free = snd_hda_bus_dev_free,
@@ -517,10 +516,12 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
 	mutex_init(&bus->cmd_mutex);
 	INIT_LIST_HEAD(&bus->codec_list);
 
-	snprintf(qname, sizeof(qname), "hda%d", card->number);
-	bus->workq = create_workqueue(qname);
+	snprintf(bus->workq_name, sizeof(bus->workq_name),
+		 "hd-audio%d", card->number);
+	bus->workq = create_singlethread_workqueue(bus->workq_name);
 	if (!bus->workq) {
-		snd_printk(KERN_ERR "cannot create workqueue %s\n", qname);
+		snd_printk(KERN_ERR "cannot create workqueue %s\n",
+			   bus->workq_name);
 		kfree(bus);
 		return -ENOMEM;
 	}
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 5810ef588402..09a332ada0c6 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -614,6 +614,7 @@ struct hda_bus {
 
 	/* unsolicited event queue */
 	struct hda_bus_unsolicited *unsol;
+	char workq_name[16];
 	struct workqueue_struct *workq;	/* common workqueue for codecs */
 
 	/* assigned PCMs */
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 7ca66d654148..144b85276d5a 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -399,7 +399,8 @@ static void print_conn_list(struct snd_info_buffer *buffer,
 {
 	int c, curr = -1;
 
-	if (conn_len > 1 && wid_type != AC_WID_AUD_MIX)
+	if (conn_len > 1 && wid_type != AC_WID_AUD_MIX &&
+	    wid_type != AC_WID_VOL_KNB)
 		curr = snd_hda_codec_read(codec, nid, 0,
 					  AC_VERB_GET_CONNECT_SEL, 0);
 	snd_iprintf(buffer, "  Connection: %d\n", conn_len);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 7884a4e07061..ae5c8a0d1479 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1037,6 +1037,7 @@ do_sku:
 		case 0x10ec0267:
 		case 0x10ec0268:
 		case 0x10ec0269:
+		case 0x10ec0272:
 		case 0x10ec0660:
 		case 0x10ec0662:
 		case 0x10ec0663:
@@ -1065,6 +1066,7 @@ do_sku:
 		case 0x10ec0882:
 		case 0x10ec0883:
 		case 0x10ec0885:
+		case 0x10ec0887:
 		case 0x10ec0889:
 			snd_hda_codec_write(codec, 0x20, 0,
 					    AC_VERB_SET_COEF_INDEX, 7);
@@ -7012,6 +7014,7 @@ static int patch_alc882(struct hda_codec *codec)
 			break;
 		case 0x106b1000: /* iMac 24 */
 		case 0x106b2800: /* AppleTV */
+		case 0x106b3e00: /* iMac 24 Aluminium */
 			board_config = ALC885_IMAC24;
 			break;
 		case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
@@ -8514,6 +8517,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
 	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
 	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
+	SND_PCI_QUIRK(0x1734, 0x1107, "FSC AMILO Xi2550",
+		      ALC883_FUJITSU_PI2515),
 	SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
 	SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530",
 		ALC888_FUJITSU_XA3530),
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index b787b3cc096f..38428e22428f 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1804,6 +1804,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
 		      "HP dv4", STAC_HP_DV5),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc,
 		      "HP dv7", STAC_HP_M4),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3600,
+		      "HP dv5", STAC_HP_DV5),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603,
 		      "HP dv5", STAC_HP_DV5),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 19d3391e229f..e900cdc84849 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -617,7 +617,7 @@ static int snd_intel8x0_ali_codec_semaphore(struct intel8x0 *chip)
 	int time = 100;
 	if (chip->buggy_semaphore)
 		return 0; /* just ignore ... */
-	while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY))
+	while (--time && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY))
 		udelay(1);
 	if (! time && ! chip->in_ac97_init)
 		snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n");
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index c5d67900d666..ff0054b76502 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -10,7 +10,7 @@
  * Based on at91-ssc.c by
  * Frank Mandarino <fmandarino@endrelia.com>
  * Based on pxa2xx Platform drivers by
- * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+ * Liam Girdwood <lrg@slimlogic.co.uk>
  *
  * 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
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h
index a828746e8a2f..391135f9c6c1 100644
--- a/sound/soc/atmel/atmel_ssc_dai.h
+++ b/sound/soc/atmel/atmel_ssc_dai.h
@@ -10,7 +10,7 @@
  * Based on at91-ssc.c by
  * Frank Mandarino <fmandarino@endrelia.com>
  * Based on pxa2xx Platform drivers by
- * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+ * Liam Girdwood <lrg@slimlogic.co.uk>
  *
  * 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
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index e3989d406f54..35d99750c383 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
  *
- * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 5b5afc144478..1cbb7b9b51ce 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -2,8 +2,7 @@
  * wm8990.c  --  WM8990 ALSA Soc Audio driver
  *
  * Copyright 2008 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- *         lg@opensource.wolfsonmicro.com or linux@wolfsonmicro.com
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  *
  *  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
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index b0362dfd5b71..dd3bb2933762 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -175,9 +175,10 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct omap_runtime_data *prtd = runtime->private_data;
+	unsigned long flags;
 	int ret = 0;
 
-	spin_lock_irq(&prtd->lock);
+	spin_lock_irqsave(&prtd->lock, flags);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
@@ -195,7 +196,7 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 	default:
 		ret = -EINVAL;
 	}
-	spin_unlock_irq(&prtd->lock);
+	spin_unlock_irqrestore(&prtd->lock, flags);
 
 	return ret;
 }
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index c709b9563226..2ab83129d9b0 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -2966,6 +2966,7 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
 		return -EINVAL;
 	}
 	alts = &iface->altsetting[fp->altset_idx];
+	fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
 	usb_set_interface(chip->dev, fp->iface, 0);
 	init_usb_pitch(chip->dev, fp->iface, alts, fp);
 	init_usb_sample_rate(chip->dev, fp->iface, alts, fp, fp->rate_max);