Merge tag 'libnvdimm-for-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Sep 2015 21:35:59 +0000 (14:35 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Sep 2015 21:35:59 +0000 (14:35 -0700)
Pull libnvdimm updates from Dan Williams:
 "This update has successfully completed a 0day-kbuild run and has
  appeared in a linux-next release.  The changes outside of the typical
  drivers/nvdimm/ and drivers/acpi/nfit.[ch] paths are related to the
  removal of IORESOURCE_CACHEABLE, the introduction of memremap(), and
  the introduction of ZONE_DEVICE + devm_memremap_pages().

  Summary:

   - Introduce ZONE_DEVICE and devm_memremap_pages() as a generic
     mechanism for adding device-driver-discovered memory regions to the
     kernel's direct map.

     This facility is used by the pmem driver to enable pfn_to_page()
     operations on the page frames returned by DAX ('direct_access' in
     'struct block_device_operations').

     For now, the 'memmap' allocation for these "device" pages comes
     from "System RAM".  Support for allocating the memmap from device
     memory will arrive in a later kernel.

   - Introduce memremap() to replace usages of ioremap_cache() and
     ioremap_wt().  memremap() drops the __iomem annotation for these
     mappings to memory that do not have i/o side effects.  The
     replacement of ioremap_cache() with memremap() is limited to the
     pmem driver to ease merging the api change in v4.3.

     Completion of the conversion is targeted for v4.4.

   - Similar to the usage of memcpy_to_pmem() + wmb_pmem() in the pmem
     driver, update the VFS DAX implementation and PMEM api to provide
     persistence guarantees for kernel operations on a DAX mapping.

   - Convert the ACPI NFIT 'BLK' driver to map the block apertures as
     cacheable to improve performance.

   - Miscellaneous updates and fixes to libnvdimm including support for
     issuing "address range scrub" commands, clarifying the optimal
     'sector size' of pmem devices, a clarification of the usage of the
     ACPI '_STA' (status) property for DIMM devices, and other minor
     fixes"

* tag 'libnvdimm-for-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: (34 commits)
  libnvdimm, pmem: direct map legacy pmem by default
  libnvdimm, pmem: 'struct page' for pmem
  libnvdimm, pfn: 'struct page' provider infrastructure
  x86, pmem: clarify that ARCH_HAS_PMEM_API implies PMEM mapped WB
  add devm_memremap_pages
  mm: ZONE_DEVICE for "device memory"
  mm: move __phys_to_pfn and __pfn_to_phys to asm/generic/memory_model.h
  dax: drop size parameter to ->direct_access()
  nd_blk: change aperture mapping from WC to WB
  nvdimm: change to use generic kvfree()
  pmem, dax: have direct_access use __pmem annotation
  dax: update I/O path to do proper PMEM flushing
  pmem: add copy_from_iter_pmem() and clear_pmem()
  pmem, x86: clean up conditional pmem includes
  pmem: remove layer when calling arch_has_wmb_pmem()
  pmem, x86: move x86 PMEM API to new pmem.h header
  libnvdimm, e820: make CONFIG_X86_PMEM_LEGACY a tristate option
  pmem: switch to devm_ allocations
  devres: add devm_memremap
  libnvdimm, btt: write and validate parent_uuid
  ...

38 files changed:
1  2 
MAINTAINERS
arch/arm/mach-shmobile/pm-rcar.c
arch/arm64/include/asm/memory.h
arch/powerpc/kernel/pci_of_scan.c
arch/powerpc/mm/mem.c
arch/powerpc/sysdev/axonram.c
arch/s390/mm/init.c
arch/sh/include/asm/io.h
arch/sh/mm/init.c
arch/sparc/kernel/pci.c
arch/x86/Kconfig
arch/x86/include/asm/io.h
arch/x86/kernel/Makefile
arch/x86/mm/init_32.c
drivers/acpi/Kconfig
drivers/acpi/nfit.c
drivers/block/brd.c
drivers/nvdimm/btt.c
drivers/nvdimm/pmem.c
drivers/pci/probe.c
drivers/s390/block/dcssblk.c
drivers/scsi/aic94xx/aic94xx_init.c
drivers/scsi/arcmsr/arcmsr_hba.c
drivers/scsi/mvsas/mv_init.c
drivers/staging/unisys/visorbus/visorchannel.c
drivers/staging/unisys/visorbus/visorchipset.c
drivers/tty/serial/8250/8250_core.c
fs/block_dev.c
fs/dax.c
include/linux/blkdev.h
include/linux/mm.h
include/linux/mmzone.h
kernel/Makefile
lib/Kconfig
lib/pci_iomap.c
mm/Kconfig
mm/memory_hotplug.c
mm/page_alloc.c

diff --combined MAINTAINERS
@@@ -158,7 -158,6 +158,7 @@@ L: linux-wpan@vger.kernel.or
  S:    Maintained
  F:    net/6lowpan/
  F:    include/net/6lowpan.h
 +F:    Documentation/networking/6lowpan.txt
  
  6PACK NETWORK DRIVER FOR AX.25
  M:    Andreas Koensgen <ajk@comnets.uni-bremen.de>
@@@ -362,7 -361,7 +362,7 @@@ S: Supporte
  F:    drivers/input/touchscreen/ad7879.c
  
  ADDRESS SPACE LAYOUT RANDOMIZATION (ASLR)
 -M:    Jiri Kosina <jkosina@suse.com>
 +M:    Jiri Kosina <jikos@kernel.org>
  S:    Maintained
  
  ADM1025 HARDWARE MONITOR DRIVER
@@@ -557,12 -556,6 +557,12 @@@ S:       Maintaine
  F:    Documentation/i2c/busses/i2c-ali1563
  F:    drivers/i2c/busses/i2c-ali1563.c
  
 +ALLWINNER SECURITY SYSTEM
 +M:    Corentin Labbe <clabbe.montjoie@gmail.com>
 +L:    linux-crypto@vger.kernel.org
 +S:    Maintained
 +F:    drivers/crypto/sunxi-ss/
 +
  ALPHA PORT
  M:    Richard Henderson <rth@twiddle.net>
  M:    Ivan Kokshaysky <ink@jurassic.park.msu.ru>
@@@ -643,14 -636,9 +643,14 @@@ M:       Oded Gabbay <oded.gabbay@gmail.com
  L:    dri-devel@lists.freedesktop.org
  T:    git git://people.freedesktop.org/~gabbayo/linux.git
  S:    Supported
 +F:    drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
 +F:    drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
 +F:    drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
 +F:    drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
  F:    drivers/gpu/drm/amd/amdkfd/
  F:    drivers/gpu/drm/amd/include/cik_structs.h
  F:    drivers/gpu/drm/amd/include/kgd_kfd_interface.h
 +F:    drivers/gpu/drm/amd/include/vi_structs.h
  F:    drivers/gpu/drm/radeon/radeon_kfd.c
  F:    drivers/gpu/drm/radeon/radeon_kfd.h
  F:    include/uapi/linux/kfd_ioctl.h
@@@ -740,12 -728,6 +740,12 @@@ X:       drivers/iio/*/adjd
  F:    drivers/staging/iio/*/ad*
  F:    staging/iio/trigger/iio-trig-bfin-timer.c
  
 +ANALOG DEVICES INC DMA DRIVERS
 +M:    Lars-Peter Clausen <lars@metafoo.de>
 +W:    http://ez.analog.com/community/linux-device-drivers
 +S:    Supported
 +F:    drivers/dma/dma-axi-dmac.c
 +
  ANDROID DRIVERS
  M:    Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  M:    Arve HjønnevÃ¥g <arve@android.com>
@@@ -764,7 -746,7 +764,7 @@@ S: Maintaine
  F:    sound/aoa/
  
  APM DRIVER
 -M:    Jiri Kosina <jkosina@suse.com>
 +M:    Jiri Kosina <jikos@kernel.org>
  S:    Odd fixes
  F:    arch/x86/kernel/apm_32.c
  F:    include/linux/apm_bios.h
@@@ -817,13 -799,11 +817,13 @@@ F:      arch/arm/include/asm/floppy.
  ARM PMU PROFILING AND DEBUGGING
  M:    Will Deacon <will.deacon@arm.com>
  S:    Maintained
 -F:    arch/arm/kernel/perf_event*
 +F:    arch/arm/kernel/perf_*
  F:    arch/arm/oprofile/common.c
 -F:    arch/arm/include/asm/pmu.h
  F:    arch/arm/kernel/hw_breakpoint.c
  F:    arch/arm/include/asm/hw_breakpoint.h
 +F:    arch/arm/include/asm/perf_event.h
 +F:    drivers/perf/arm_pmu.c
 +F:    include/linux/perf/arm_pmu.h
  
  ARM PORT
  M:    Russell King <linux@arm.linux.org.uk>
@@@ -947,7 -927,7 +947,7 @@@ M: Sunil Goutham <sgoutham@cavium.com
  M:    Robert Richter <rric@kernel.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Supported
 -F:    drivers/net/ethernet/cavium/
 +F:    drivers/net/ethernet/cavium/thunder/
  
  ARM/CIRRUS LOGIC CLPS711X ARM ARCHITECTURE
  M:    Alexander Shiyan <shc_work@mail.ru>
@@@ -1485,7 -1465,9 +1485,7 @@@ F:      arch/arm/boot/dts/emev2
  F:    arch/arm/boot/dts/r7s*
  F:    arch/arm/boot/dts/r8a*
  F:    arch/arm/boot/dts/sh*
 -F:    arch/arm/configs/armadillo800eva_defconfig
  F:    arch/arm/configs/bockw_defconfig
 -F:    arch/arm/configs/kzm9g_defconfig
  F:    arch/arm/configs/marzen_defconfig
  F:    arch/arm/configs/shmobile_defconfig
  F:    arch/arm/include/debug/renesas-scif.S
@@@ -1522,10 -1504,8 +1522,10 @@@ S:    Maintaine
  F:    arch/arm/mach-sti/
  F:    arch/arm/boot/dts/sti*
  F:    drivers/clocksource/arm_global_timer.c
 +F:    drivers/clocksource/clksrc_st_lpc.c
  F:    drivers/i2c/busses/i2c-st.c
  F:    drivers/media/rc/st_rc.c
 +F:    drivers/media/platform/sti/c8sectpfe/
  F:    drivers/mmc/host/sdhci-st.c
  F:    drivers/phy/phy-miphy28lp.c
  F:    drivers/phy/phy-miphy365x.c
@@@ -1599,10 -1579,7 +1599,10 @@@ ARM/UNIPHIER ARCHITECTUR
  M:    Masahiro Yamada <yamada.masahiro@socionext.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
 +F:    arch/arm/boot/dts/uniphier*
  F:    arch/arm/mach-uniphier/
 +F:    drivers/pinctrl/uniphier/
 +F:    drivers/tty/serial/8250/8250_uniphier.c
  N:    uniphier
  
  ARM/Ux500 ARM ARCHITECTURE
@@@ -1697,7 -1674,7 +1697,7 @@@ M:      Michal Simek <michal.simek@xilinx.co
  R:    Sören Brinkmann <soren.brinkmann@xilinx.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  W:    http://wiki.xilinx.com
 -T:    git git://git.xilinx.com/linux-xlnx.git
 +T:    git https://github.com/Xilinx/linux-xlnx.git
  S:    Supported
  F:    arch/arm/mach-zynq/
  F:    drivers/cpuidle/cpuidle-zynq.c
@@@ -1938,14 -1915,6 +1938,14 @@@ W:    http://atmelwlandriver.sourceforge.n
  S:    Maintained
  F:    drivers/net/wireless/atmel*
  
 +ATMEL MAXTOUCH DRIVER
 +M:    Nick Dyer <nick.dyer@itdev.co.uk>
 +T:    git git://github.com/atmel-maxtouch/linux.git
 +S:    Supported
 +F:    Documentation/devicetree/bindings/input/atmel,maxtouch.txt
 +F:    drivers/input/touchscreen/atmel_mxt_ts.c
 +F:    include/linux/platform_data/atmel_mxt_ts.h
 +
  ATTO EXPRESSSAS SAS/SATA RAID SCSI DRIVER
  M:    Bradley Grove <linuxdrivers@attotech.com>
  L:    linux-scsi@vger.kernel.org
@@@ -2249,9 -2218,7 +2249,9 @@@ F:      drivers/clocksource/bcm_kona_timer.
  BROADCOM BCM2835 ARM ARCHITECTURE
  M:    Stephen Warren <swarren@wwwdotorg.org>
  M:    Lee Jones <lee@kernel.org>
 +M:    Eric Anholt <eric@anholt.net>
  L:    linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers)
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git
  S:    Maintained
  N:    bcm2835
@@@ -2575,6 -2542,7 +2575,6 @@@ M:     Raghu Vatsavayi <raghu.vatsavayi
  L:     netdev@vger.kernel.org
  W:     http://www.cavium.com
  S:     Supported
 -F:     drivers/net/ethernet/cavium/
  F:     drivers/net/ethernet/cavium/liquidio/
  
  CC2520 IEEE-802.15.4 RADIO DRIVER
@@@ -2621,15 -2589,6 +2621,15 @@@ S:    Supporte
  F:    Documentation/filesystems/ceph.txt
  F:    fs/ceph/
  
 +CERTIFICATE HANDLING:
 +M:    David Howells <dhowells@redhat.com>
 +M:    David Woodhouse <dwmw2@infradead.org>
 +L:    keyrings@linux-nfs.org
 +S:    Maintained
 +F:    Documentation/module-signing.txt
 +F:    certs/
 +F:    scripts/extract-cert.c
 +
  CERTIFIED WIRELESS USB (WUSB) SUBSYSTEM:
  L:    linux-usb@vger.kernel.org
  S:    Orphan
@@@ -3495,7 -3454,6 +3495,7 @@@ X:      Documentation/devicetree
  X:    Documentation/acpi
  X:    Documentation/power
  X:    Documentation/spi
 +X:    Documentation/DocBook/media
  T:    git git://git.lwn.net/linux-2.6.git docs-next
  
  DOUBLETALK DRIVER
@@@ -3592,15 -3550,6 +3592,15 @@@ F:    drivers/gpu/drm/exynos
  F:    include/drm/exynos*
  F:    include/uapi/drm/exynos*
  
 +DRM DRIVERS FOR FREESCALE DCU
 +M:    Jianwei Wang <jianwei.wang.chn@gmail.com>
 +M:    Alison Wang <alison.wang@freescale.com>
 +L:    dri-devel@lists.freedesktop.org
 +S:    Supported
 +F:    drivers/gpu/drm/fsl-dcu/
 +F:    Documentation/devicetree/bindings/video/fsl,dcu.txt
 +F:    Documentation/devicetree/bindings/panel/nec,nl4827hc19_05b.txt
 +
  DRM DRIVERS FOR FREESCALE IMX
  M:    Philipp Zabel <p.zabel@pengutronix.de>
  L:    dri-devel@lists.freedesktop.org
@@@ -3638,15 -3587,6 +3638,15 @@@ S:    Maintaine
  F:    drivers/gpu/drm/rockchip/
  F:    Documentation/devicetree/bindings/video/rockchip*
  
 +DRM DRIVERS FOR STI
 +M:    Benjamin Gaignard <benjamin.gaignard@linaro.org>
 +M:    Vincent Abriou <vincent.abriou@st.com>
 +L:    dri-devel@lists.freedesktop.org
 +T:    git http://git.linaro.org/people/benjamin.gaignard/kernel.git
 +S:    Maintained
 +F:    drivers/gpu/drm/sti
 +F:    Documentation/devicetree/bindings/gpu/st,stih4xx.txt
 +
  DSBR100 USB FM RADIO DRIVER
  M:    Alexey Klimov <klimov.linux@gmail.com>
  L:    linux-media@vger.kernel.org
@@@ -4119,6 -4059,15 +4119,6 @@@ F:     Documentation/filesystems/ext2.tx
  F:    fs/ext2/
  F:    include/linux/ext2*
  
 -EXT3 FILE SYSTEM
 -M:    Jan Kara <jack@suse.com>
 -M:    Andrew Morton <akpm@linux-foundation.org>
 -M:    Andreas Dilger <adilger.kernel@dilger.ca>
 -L:    linux-ext4@vger.kernel.org
 -S:    Maintained
 -F:    Documentation/filesystems/ext3.txt
 -F:    fs/ext3/
 -
  EXT4 FILE SYSTEM
  M:    "Theodore Ts'o" <tytso@mit.edu>
  M:    Andreas Dilger <adilger.kernel@dilger.ca>
@@@ -4296,7 -4245,7 +4296,7 @@@ S:      Maintaine
  F:    drivers/block/rsxx/
  
  FLOPPY DRIVER
 -M:    Jiri Kosina <jkosina@suse.com>
 +M:    Jiri Kosina <jikos@kernel.org>
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git
  S:    Odd fixes
  F:    drivers/block/floppy.c
@@@ -4457,7 -4406,6 +4457,7 @@@ F:      include/linux/fscache*.
  F2FS FILE SYSTEM
  M:    Jaegeuk Kim <jaegeuk@kernel.org>
  M:    Changman Lee <cm224.lee@samsung.com>
 +R:    Chao Yu <chao2.yu@samsung.com>
  L:    linux-f2fs-devel@lists.sourceforge.net
  W:    http://en.wikipedia.org/wiki/F2FS
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git
@@@ -4466,7 -4414,6 +4466,7 @@@ F:      Documentation/filesystems/f2fs.tx
  F:    Documentation/ABI/testing/sysfs-fs-f2fs
  F:    fs/f2fs/
  F:    include/linux/f2fs_fs.h
 +F:    include/trace/events/f2fs.h
  
  FUJITSU FR-V (FRV) PORT
  M:    David Howells <dhowells@redhat.com>
@@@ -4869,7 -4816,7 +4869,7 @@@ F:      include/linux/pm.
  F:    arch/*/include/asm/suspend*.h
  
  HID CORE LAYER
 -M:    Jiri Kosina <jkosina@suse.com>
 +M:    Jiri Kosina <jikos@kernel.org>
  L:    linux-input@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git
  S:    Maintained
@@@ -4878,7 -4825,7 +4878,7 @@@ F:      include/linux/hid
  F:    include/uapi/linux/hid*
  
  HID SENSOR HUB DRIVERS
 -M:    Jiri Kosina <jkosina@suse.com>
 +M:    Jiri Kosina <jikos@kernel.org>
  M:    Jonathan Cameron <jic23@kernel.org>
  M:    Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
  L:    linux-input@vger.kernel.org
@@@ -5010,7 -4957,6 +5010,7 @@@ F:      drivers/scsi/storvsc_drv.
  F:    drivers/video/fbdev/hyperv_fb.c
  F:    include/linux/hyperv.h
  F:    tools/hv/
 +F:    Documentation/ABI/stable/sysfs-bus-vmbus
  
  I2C OVER PARALLEL PORT
  M:    Jean Delvare <jdelvare@suse.com>
@@@ -5121,21 -5067,9 +5121,21 @@@ T:    git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    arch/ia64/
  
 +IBM Power VMX Cryptographic instructions
 +M:    Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com>
 +M:    Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com>
 +L:    linux-crypto@vger.kernel.org
 +S:    Supported
 +F:    drivers/crypto/vmx/Makefile
 +F:    drivers/crypto/vmx/Kconfig
 +F:    drivers/crypto/vmx/vmx.c
 +F:    drivers/crypto/vmx/aes*
 +F:    drivers/crypto/vmx/ghash*
 +F:    drivers/crypto/vmx/ppc-xlate.pl
 +
  IBM Power in-Nest Crypto Acceleration
 -M:    Marcelo Henrique Cerri <mhcerri@linux.vnet.ibm.com>
 -M:    Fionnuala Gunter <fin@linux.vnet.ibm.com>
 +M:    Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com>
 +M:    Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com>
  L:    linux-crypto@vger.kernel.org
  S:    Supported
  F:    drivers/crypto/nx/Makefile
@@@ -5147,7 -5081,7 +5147,7 @@@ F:      drivers/crypto/nx/nx_csbcpb.
  F:    drivers/crypto/nx/nx_debugfs.h
  
  IBM Power 842 compression accelerator
 -M:    Dan Streetman <ddstreet@us.ibm.com>
 +M:    Dan Streetman <ddstreet@ieee.org>
  S:    Supported
  F:    drivers/crypto/nx/Makefile
  F:    drivers/crypto/nx/Kconfig
@@@ -5631,7 -5565,7 +5631,7 @@@ F:      include/uapi/linux/ip_vs.
  F:    net/netfilter/ipvs/
  
  IPWIRELESS DRIVER
 -M:    Jiri Kosina <jkosina@suse.com>
 +M:    Jiri Kosina <jikos@kernel.org>
  M:    David Sterba <dsterba@suse.com>
  S:    Odd Fixes
  F:    drivers/tty/ipwireless/
@@@ -5666,7 -5600,6 +5666,7 @@@ F:      kernel/irq
  IRQCHIP DRIVERS
  M:    Thomas Gleixner <tglx@linutronix.de>
  M:    Jason Cooper <jason@lakedaemon.net>
 +M:    Marc Zyngier <marc.zyngier@arm.com>
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
@@@ -5675,14 -5608,11 +5675,14 @@@ F:   Documentation/devicetree/bindings/in
  F:    drivers/irqchip/
  
  IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
 -M:    Benjamin Herrenschmidt <benh@kernel.crashing.org>
 +M:    Jiang Liu <jiang.liu@linux.intel.com>
 +M:    Marc Zyngier <marc.zyngier@arm.com>
  S:    Maintained
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
  F:    Documentation/IRQ-domain.txt
  F:    include/linux/irqdomain.h
  F:    kernel/irq/irqdomain.c
 +F:    kernel/irq/msi.c
  
  ISAPNP
  M:    Jaroslav Kysela <perex@perex.cz>
@@@ -5821,20 -5751,21 +5821,20 @@@ S:   Maintaine
  F:    fs/jffs2/
  F:    include/uapi/linux/jffs2.h
  
 -JOURNALLING LAYER FOR BLOCK DEVICES (JBD)
 -M:    Andrew Morton <akpm@linux-foundation.org>
 -M:    Jan Kara <jack@suse.com>
 -L:    linux-ext4@vger.kernel.org
 -S:    Maintained
 -F:    fs/jbd/
 -F:    include/linux/jbd.h
 -
  JOURNALLING LAYER FOR BLOCK DEVICES (JBD2)
  M:    "Theodore Ts'o" <tytso@mit.edu>
 +M:    Jan Kara <jack@suse.com>
  L:    linux-ext4@vger.kernel.org
  S:    Maintained
  F:    fs/jbd2/
  F:    include/linux/jbd2.h
  
 +JPU V4L2 MEM2MEM DRIVER FOR RENESAS
 +M:    Mikhail Ulyanov <mikhail.ulyanov@cogentembedded.com>
 +L:    linux-media@vger.kernel.org
 +S:    Maintained
 +F:    drivers/media/platform/rcar_jpu.c
 +
  JSM Neo PCI based serial card
  M:    Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
  L:    linux-serial@vger.kernel.org
@@@ -5905,7 -5836,6 +5905,7 @@@ S:      Odd Fixe
  
  KERNEL NFSD, SUNRPC, AND LOCKD SERVERS
  M:    "J. Bruce Fields" <bfields@fieldses.org>
 +M:    Jeff Layton <jlayton@poochiereds.net>
  L:    linux-nfs@vger.kernel.org
  W:    http://nfs.sourceforge.net/
  S:    Supported
@@@ -5962,6 -5892,7 +5962,6 @@@ F:      arch/powerpc/kvm
  KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
  M:    Christian Borntraeger <borntraeger@de.ibm.com>
  M:    Cornelia Huck <cornelia.huck@de.ibm.com>
 -M:    linux390@de.ibm.com
  L:    linux-s390@vger.kernel.org
  W:    http://www.ibm.com/developerworks/linux/linux390/
  S:    Supported
@@@ -6003,7 -5934,7 +6003,7 @@@ F:      kernel/kexec.
  
  KEYS/KEYRINGS:
  M:    David Howells <dhowells@redhat.com>
 -L:    keyrings@linux-nfs.org
 +L:    keyrings@vger.kernel.org
  S:    Maintained
  F:    Documentation/security/keys.txt
  F:    include/linux/key.h
@@@ -6015,7 -5946,7 +6015,7 @@@ KEYS-TRUSTE
  M:    David Safford <safford@us.ibm.com>
  M:    Mimi Zohar <zohar@linux.vnet.ibm.com>
  L:    linux-security-module@vger.kernel.org
 -L:    keyrings@linux-nfs.org
 +L:    keyrings@vger.kernel.org
  S:    Supported
  F:    Documentation/security/keys-trusted-encrypted.txt
  F:    include/keys/trusted-type.h
@@@ -6026,7 -5957,7 +6026,7 @@@ KEYS-ENCRYPTE
  M:    Mimi Zohar <zohar@linux.vnet.ibm.com>
  M:    David Safford <safford@us.ibm.com>
  L:    linux-security-module@vger.kernel.org
 -L:    keyrings@linux-nfs.org
 +L:    keyrings@vger.kernel.org
  S:    Supported
  F:    Documentation/security/keys-trusted-encrypted.txt
  F:    include/keys/encrypted-type.h
@@@ -6096,10 -6027,11 +6096,10 @@@ F:   Documentation/scsi/53c700.tx
  F:    drivers/scsi/53c700*
  
  LED SUBSYSTEM
 -M:    Bryan Wu <cooloney@gmail.com>
  M:    Richard Purdie <rpurdie@rpsys.net>
  M:    Jacek Anaszewski <j.anaszewski@samsung.com>
  L:    linux-leds@vger.kernel.org
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds.git
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds.git
  S:    Maintained
  F:    drivers/leds/
  F:    include/linux/leds.h
@@@ -6229,6 -6161,7 +6229,7 @@@ Q:      https://patchwork.kernel.org/project
  S:    Supported
  F:    drivers/nvdimm/pmem.c
  F:    include/linux/pmem.h
+ F:    arch/*/include/asm/pmem.h
  
  LINUX FOR IBM pSERIES (RS/6000)
  M:    Paul Mackerras <paulus@au.ibm.com>
@@@ -6319,7 -6252,7 +6320,7 @@@ F:      drivers/platform/x86/hp_accel.
  LIVE PATCHING
  M:    Josh Poimboeuf <jpoimboe@redhat.com>
  M:    Seth Jennings <sjenning@redhat.com>
 -M:    Jiri Kosina <jkosina@suse.com>
 +M:    Jiri Kosina <jikos@kernel.org>
  M:    Vojtech Pavlik <vojtech@suse.com>
  S:    Maintained
  F:    kernel/livepatch/
@@@ -6574,7 -6507,7 +6575,7 @@@ F:      drivers/net/ethernet/marvell/mvneta.
  
  MARVELL MWIFIEX WIRELESS DRIVER
  M:    Amitkumar Karwar <akarwar@marvell.com>
 -M:    Avinash Patil <patila@marvell.com>
 +M:    Nishant Sarmukadam <nishants@marvell.com>
  L:    linux-wireless@vger.kernel.org
  S:    Maintained
  F:    drivers/net/wireless/mwifiex/
@@@ -6603,13 -6536,6 +6604,13 @@@ S:    Maintaine
  F:    Documentation/hwmon/max16065
  F:    drivers/hwmon/max16065.c
  
 +MAX20751 HARDWARE MONITOR DRIVER
 +M:    Guenter Roeck <linux@roeck-us.net>
 +L:    lm-sensors@lm-sensors.org
 +S:    Maintained
 +F:    Documentation/hwmon/max20751
 +F:    drivers/hwmon/max20751.c
 +
  MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
  M:    "Hans J. Koch" <hjk@hansjkoch.de>
  L:    lm-sensors@lm-sensors.org
@@@ -6633,14 -6559,6 +6634,14 @@@ S:    Supporte
  F:    drivers/power/max14577_charger.c
  F:    drivers/power/max77693_charger.c
  
 +MAXIM MAX77802 MULTIFUNCTION PMIC DEVICE DRIVERS
 +M:    Javier Martinez Canillas <javier@osg.samsung.com>
 +L:    linux-kernel@vger.kernel.org
 +S:    Supported
 +F:    drivers/*/*max77802.c
 +F:    Documentation/devicetree/bindings/*/*max77802.txt
 +F:    include/dt-bindings/*/*max77802.h
 +
  MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS
  M:    Chanwoo Choi <cw00.choi@samsung.com>
  M:    Krzysztof Kozlowski <k.kozlowski@samsung.com>
@@@ -6654,7 -6572,7 +6655,7 @@@ F:      drivers/extcon/extcon-max77693.
  F:    drivers/rtc/rtc-max77686.c
  F:    drivers/clk/clk-max77686.c
  F:    Documentation/devicetree/bindings/mfd/max14577.txt
 -F:    Documentation/devicetree/bindings/mfd/max77686.txt
 +F:    Documentation/devicetree/bindings/*/max77686.txt
  F:    Documentation/devicetree/bindings/mfd/max77693.txt
  F:    Documentation/devicetree/bindings/clock/maxim,max77686.txt
  F:    include/linux/mfd/max14577*.h
@@@ -6678,51 -6596,6 +6679,51 @@@ S:    Supporte
  F:    Documentation/devicetree/bindings/media/renesas,vsp1.txt
  F:    drivers/media/platform/vsp1/
  
 +MEDIA DRIVERS FOR ASCOT2E
 +M:    Sergey Kozlov <serjk@netup.ru>
 +L:    linux-media@vger.kernel.org
 +W:    http://linuxtv.org
 +W:    http://netup.tv/
 +T:    git git://linuxtv.org/media_tree.git
 +S:    Supported
 +F:    drivers/media/dvb-frontends/ascot2e*
 +
 +MEDIA DRIVERS FOR CXD2841ER
 +M:    Sergey Kozlov <serjk@netup.ru>
 +L:    linux-media@vger.kernel.org
 +W:    http://linuxtv.org/
 +W:    http://netup.tv/
 +T:    git git://linuxtv.org/media_tree.git
 +S:    Supported
 +F:    drivers/media/dvb-frontends/cxd2841er*
 +
 +MEDIA DRIVERS FOR HORUS3A
 +M:    Sergey Kozlov <serjk@netup.ru>
 +L:    linux-media@vger.kernel.org
 +W:    http://linuxtv.org/
 +W:    http://netup.tv/
 +T:    git git://linuxtv.org/media_tree.git
 +S:    Supported
 +F:    drivers/media/dvb-frontends/horus3a*
 +
 +MEDIA DRIVERS FOR LNBH25
 +M:    Sergey Kozlov <serjk@netup.ru>
 +L:    linux-media@vger.kernel.org
 +W:    http://linuxtv.org/
 +W:    http://netup.tv/
 +T:    git git://linuxtv.org/media_tree.git
 +S:    Supported
 +F:    drivers/media/dvb-frontends/lnbh25*
 +
 +MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices
 +M:    Sergey Kozlov <serjk@netup.ru>
 +L:    linux-media@vger.kernel.org
 +W:    http://linuxtv.org/
 +W:    http://netup.tv/
 +T:    git git://linuxtv.org/media_tree.git
 +S:    Supported
 +F:    drivers/media/pci/netup_unidvb/*
 +
  MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
  M:    Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  P:    LinuxTV.org Project
@@@ -6772,15 -6645,6 +6773,15 @@@ W:    http://www.mellanox.co
  Q:    http://patchwork.ozlabs.org/project/netdev/list/
  F:    drivers/net/ethernet/mellanox/mlx4/en_*
  
 +MELLANOX ETHERNET SWITCH DRIVERS
 +M:    Jiri Pirko <jiri@mellanox.com>
 +M:    Ido Schimmel <idosch@mellanox.com>
 +L:    netdev@vger.kernel.org
 +S:    Supported
 +W:    http://www.mellanox.com
 +Q:    http://patchwork.ozlabs.org/project/netdev/list/
 +F:    drivers/net/ethernet/mellanox/mlxsw/
 +
  MEMORY MANAGEMENT
  L:    linux-mm@kvack.org
  W:    http://www.linux-mm.org
@@@ -6816,7 -6680,6 +6817,7 @@@ M:      Johannes Thumshirn <morbidrsa@gmail.
  S:    Maintained
  F:    drivers/mcb/
  F:    include/linux/mcb.h
 +F:    Documentation/men-chameleon-bus.txt
  
  MEN F21BMC (Board Management Controller)
  M:    Andreas Werner <andreas.werner@men.de>
@@@ -7422,15 -7285,6 +7423,15 @@@ S:    Supporte
  F:    drivers/block/nvme*
  F:    include/linux/nvme.h
  
 +NVMEM FRAMEWORK
 +M:    Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 +M:    Maxime Ripard <maxime.ripard@free-electrons.com>
 +S:    Maintained
 +F:    drivers/nvmem/
 +F:    Documentation/devicetree/bindings/nvmem/
 +F:    include/linux/nvmem-consumer.h
 +F:    include/linux/nvmem-provider.h
 +
  NXP-NCI NFC DRIVER
  M:    Clément Perrochaud <clement.perrochaud@effinnov.com>
  R:    Charles Gorand <charles.gorand@effinnov.com>
@@@ -7668,9 -7522,8 +7669,9 @@@ F:      Documentation/i2c/busses/i2c-ocore
  F:    drivers/i2c/busses/i2c-ocores.c
  
  OPEN FIRMWARE AND FLATTENED DEVICE TREE
 -M:    Grant Likely <grant.likely@linaro.org>
  M:    Rob Herring <robh+dt@kernel.org>
 +M:    Frank Rowand <frowand.list@gmail.com>
 +M:    Grant Likely <grant.likely@linaro.org>
  L:    devicetree@vger.kernel.org
  W:    http://www.devicetree.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/glikely/linux.git
@@@ -8143,6 -7996,7 +8144,6 @@@ F:      drivers/pinctrl/sh-pfc
  
  PIN CONTROLLER - SAMSUNG
  M:    Tomasz Figa <tomasz.figa@gmail.com>
 -M:    Thomas Abraham <thomas.abraham@linaro.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  L:    linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
  S:    Maintained
@@@ -8157,7 -8011,7 +8158,7 @@@ S:      Maintaine
  F:    drivers/pinctrl/spear/
  
  PKTCDVD DRIVER
 -M:    Jiri Kosina <jkosina@suse.com>
 +M:    Jiri Kosina <jikos@kernel.org>
  S:    Maintained
  F:    drivers/block/pktcdvd.c
  F:    include/linux/pktcdvd.h
@@@ -8192,7 -8046,7 +8193,7 @@@ S:      Supporte
  F:    drivers/scsi/pmcraid.*
  
  PMC SIERRA PM8001 DRIVER
 -M:    xjtuwjp@gmail.com
 +M:    Jack Wang <jinpu.wang@profitbricks.com>
  M:    lindar_liu@usish.com
  L:    pmchba@pmcs.com
  L:    linux-scsi@vger.kernel.org
@@@ -8217,16 -8071,6 +8218,16 @@@ T:    git git://git.infradead.org/battery-
  S:    Maintained
  F:    include/linux/power_supply.h
  F:    drivers/power/
 +X:    drivers/power/avs/
 +
 +POWER STATE COORDINATION INTERFACE (PSCI)
 +M:    Mark Rutland <mark.rutland@arm.com>
 +M:    Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
 +L:    linux-arm-kernel@lists.infradead.org
 +S:    Maintained
 +F:    drivers/firmware/psci.c
 +F:    include/linux/psci.h
 +F:    include/uapi/linux/psci.h
  
  PNP SUPPORT
  M:    "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
@@@ -8625,7 -8469,7 +8626,7 @@@ M:      "Paul E. McKenney" <paulmck@linux.vn
  M:    Josh Triplett <josh@joshtriplett.org>
  R:    Steven Rostedt <rostedt@goodmis.org>
  R:    Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
 -R:    Lai Jiangshan <laijs@cn.fujitsu.com>
 +R:    Lai Jiangshan <jiangshanlai@gmail.com>
  L:    linux-kernel@vger.kernel.org
  S:    Supported
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
@@@ -8652,7 -8496,7 +8653,7 @@@ M:      "Paul E. McKenney" <paulmck@linux.vn
  M:    Josh Triplett <josh@joshtriplett.org>
  R:    Steven Rostedt <rostedt@goodmis.org>
  R:    Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
 -R:    Lai Jiangshan <laijs@cn.fujitsu.com>
 +R:    Lai Jiangshan <jiangshanlai@gmail.com>
  L:    linux-kernel@vger.kernel.org
  W:    http://www.rdrop.com/users/paulmck/RCU/
  S:    Supported
@@@ -8717,7 -8561,6 +8718,7 @@@ M:      Philipp Zabel <p.zabel@pengutronix.d
  S:    Maintained
  F:    drivers/reset/
  F:    Documentation/devicetree/bindings/reset/
 +F:    include/dt-bindings/reset/
  F:    include/linux/reset.h
  F:    include/linux/reset-controller.h
  
@@@ -8852,6 -8695,7 +8853,6 @@@ F:      drivers/video/fbdev/savage
  S390
  M:    Martin Schwidefsky <schwidefsky@de.ibm.com>
  M:    Heiko Carstens <heiko.carstens@de.ibm.com>
 -M:    linux390@de.ibm.com
  L:    linux-s390@vger.kernel.org
  W:    http://www.ibm.com/developerworks/linux/linux390/
  S:    Supported
@@@ -8879,6 -8723,7 +8880,6 @@@ F:      block/partitions/ibm.
  
  S390 NETWORK DRIVERS
  M:    Ursula Braun <ursula.braun@de.ibm.com>
 -M:    linux390@de.ibm.com
  L:    linux-s390@vger.kernel.org
  W:    http://www.ibm.com/developerworks/linux/linux390/
  S:    Supported
@@@ -8895,6 -8740,7 +8896,6 @@@ F:      drivers/pci/hotplug/s390_pci_hpc.
  
  S390 ZCRYPT DRIVER
  M:    Ingo Tuchscherer <ingo.tuchscherer@de.ibm.com>
 -M:    linux390@de.ibm.com
  L:    linux-s390@vger.kernel.org
  W:    http://www.ibm.com/developerworks/linux/linux390/
  S:    Supported
@@@ -8902,6 -8748,7 +8903,6 @@@ F:      drivers/s390/crypto
  
  S390 ZFCP DRIVER
  M:    Steffen Maier <maier@linux.vnet.ibm.com>
 -M:    linux390@de.ibm.com
  L:    linux-s390@vger.kernel.org
  W:    http://www.ibm.com/developerworks/linux/linux390/
  S:    Supported
@@@ -8909,6 -8756,7 +8910,6 @@@ F:      drivers/s390/scsi/zfcp_
  
  S390 IUCV NETWORK LAYER
  M:    Ursula Braun <ursula.braun@de.ibm.com>
 -M:    linux390@de.ibm.com
  L:    linux-s390@vger.kernel.org
  W:    http://www.ibm.com/developerworks/linux/linux390/
  S:    Supported
@@@ -9011,12 -8859,6 +9012,12 @@@ L:    linux-media@vger.kernel.or
  S:    Supported
  F:    drivers/media/i2c/s5k5baf.c
  
 +SAMSUNG S3FWRN5 NFC DRIVER
 +M:    Robert Baldyga <r.baldyga@samsung.com>
 +L:    linux-nfc@lists.01.org (moderated for non-subscribers)
 +S:    Supported
 +F:    drivers/nfc/s3fwrn5
 +
  SAMSUNG SOC CLOCK DRIVERS
  M:    Sylwester Nawrocki <s.nawrocki@samsung.com>
  M:    Tomasz Figa <tomasz.figa@gmail.com>
@@@ -9067,13 -8909,6 +9068,13 @@@ F:    include/linux/dma/dw.
  F:    include/linux/platform_data/dma-dw.h
  F:    drivers/dma/dw/
  
 +SYNOPSYS DESIGNWARE ETHERNET QOS 4.10a driver
 +M: Lars Persson <lars.persson@axis.com>
 +L: netdev@vger.kernel.org
 +S: Supported
 +F: Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt
 +F: drivers/net/ethernet/synopsys/dwc_eth_qos.c
 +
  SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER
  M:    Seungwon Jeon <tgih.jun@samsung.com>
  M:    Jaehoon Chung <jh80.chung@samsung.com>
@@@ -9273,12 -9108,6 +9274,12 @@@ T:    git git://git.kernel.org/pub/scm/lin
  S:    Supported
  F:    security/apparmor/
  
 +YAMA SECURITY MODULE
 +M:    Kees Cook <keescook@chromium.org>
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git yama/tip
 +S:    Supported
 +F:    security/yama/
 +
  SENSABLE PHANTOM
  M:    Jiri Slaby <jirislaby@gmail.com>
  S:    Maintained
@@@ -9496,15 -9325,6 +9497,15 @@@ S:    Maintaine
  F:    drivers/media/i2c/ov2659.c
  F:    include/media/ov2659.h
  
 +SILICON MOTION SM712 FRAME BUFFER DRIVER
 +M:    Sudip Mukherjee <sudipm.mukherjee@gmail.com>
 +M:    Teddy Wang <teddy.wang@siliconmotion.com>
 +M:    Sudip Mukherjee <sudip@vectorindia.org>
 +L:    linux-fbdev@vger.kernel.org
 +S:    Maintained
 +F:    drivers/video/fbdev/sm712*
 +F:    Documentation/fb/sm712fb.txt
 +
  SIS 190 ETHERNET DRIVER
  M:    Francois Romieu <romieu@fr.zoreil.com>
  L:    netdev@vger.kernel.org
@@@ -9544,7 -9364,7 +9545,7 @@@ F:      include/linux/sl?b*.
  F:    mm/sl?b*
  
  SLEEPABLE READ-COPY UPDATE (SRCU)
 -M:    Lai Jiangshan <laijs@cn.fujitsu.com>
 +M:    Lai Jiangshan <jiangshanlai@gmail.com>
  M:    "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
  M:    Josh Triplett <josh@joshtriplett.org>
  R:    Steven Rostedt <rostedt@goodmis.org>
@@@ -9902,6 -9722,11 +9903,6 @@@ W:     http://wiki.laptop.org/go/DCO
  S:    Maintained
  F:    drivers/staging/olpc_dcon/
  
 -STAGING - OZMO DEVICES USB OVER WIFI DRIVER
 -M:    Shigekatsu Tateno <shigekatsu.tateno@atmel.com>
 -S:    Maintained
 -F:    drivers/staging/ozwpan/
 -
  STAGING - PARALLEL LCD/KEYPAD PANEL DRIVER
  M:    Willy Tarreau <willy@meta-x.org>
  S:    Odd Fixes
@@@ -9920,6 -9745,14 +9921,6 @@@ L:     linux-wireless@vger.kernel.or
  S:    Maintained
  F:    drivers/staging/rtl8723au/
  
 -STAGING - SILICON MOTION SM7XX FRAME BUFFER DRIVER
 -M:    Sudip Mukherjee <sudipm.mukherjee@gmail.com>
 -M:    Teddy Wang <teddy.wang@siliconmotion.com>
 -M:    Sudip Mukherjee <sudip@vectorindia.org>
 -L:    linux-fbdev@vger.kernel.org
 -S:    Maintained
 -F:    drivers/staging/sm7xxfb/
 -
  STAGING - SILICON MOTION SM750 FRAME BUFFER DRIVER
  M:    Sudip Mukherjee <sudipm.mukherjee@gmail.com>
  M:    Teddy Wang <teddy.wang@siliconmotion.com>
@@@ -10038,9 -9871,8 +10039,9 @@@ SYNOPSYS ARC ARCHITECTUR
  M:    Vineet Gupta <vgupta@synopsys.com>
  S:    Supported
  F:    arch/arc/
 -F:    Documentation/devicetree/bindings/arc/
 +F:    Documentation/devicetree/bindings/arc/*
  F:    drivers/tty/serial/arc_uart.c
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git
  
  SYNOPSYS ARC SDP platform support
  M:    Alexey Brodkin <abrodkin@synopsys.com>
@@@ -10495,13 -10327,6 +10496,13 @@@ F: drivers/char/toshiba.
  F:    include/linux/toshiba.h
  F:    include/uapi/linux/toshiba.h
  
 +TOSHIBA TC358743 DRIVER
 +M:    Mats Randgaard <matrandg@cisco.com>
 +L:    linux-media@vger.kernel.org
 +S:    Maintained
 +F:    drivers/media/i2c/tc358743*
 +F:    include/media/tc358743.h
 +
  TMIO MMC DRIVER
  M:    Ian Molton <ian@mnementh.co.uk>
  L:    linux-mmc@vger.kernel.org
@@@ -10798,7 -10623,7 +10799,7 @@@ F:   drivers/usb/gadget
  F:    include/linux/usb/gadget*
  
  USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...)
 -M:    Jiri Kosina <jkosina@suse.com>
 +M:    Jiri Kosina <jikos@kernel.org>
  L:    linux-usb@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git
  S:    Maintained
@@@ -11193,7 -11018,7 +11194,7 @@@ F:   drivers/input/mouse/vmmouse.
  F:    drivers/input/mouse/vmmouse.h
  
  VMWARE VMXNET3 ETHERNET DRIVER
 -M:    Shreyas Bhatewara <sbhatewara@vmware.com>
 +M:    Shrikrishna Khare <skhare@vmware.com>
  M:    "VMware, Inc." <pv-drivers@vmware.com>
  L:    netdev@vger.kernel.org
  S:    Maintained
@@@ -11218,14 -11043,6 +11219,14 @@@ S: Supporte
  F:    drivers/regulator/
  F:    include/linux/regulator/
  
 +VRF
 +M:    David Ahern <dsa@cumulusnetworks.com>
 +M:    Shrijeet Mukherjee <shm@cumulusnetworks.com>
 +L:    netdev@vger.kernel.org
 +S:    Maintained
 +F:    drivers/net/vrf.c
 +F:    include/net/vrf.h
 +
  VT1211 HARDWARE MONITOR DRIVER
  M:    Juerg Haefliger <juergh@gmail.com>
  L:    lm-sensors@lm-sensors.org
@@@ -11381,7 -11198,6 +11382,7 @@@ F:   sound/soc/codecs/wm
  
  WORKQUEUE
  M:    Tejun Heo <tj@kernel.org>
 +R:    Lai Jiangshan <jiangshanlai@gmail.com>
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git
  S:    Maintained
  F:    include/linux/workqueue.h
  #include <linux/err.h>
  #include <linux/mm.h>
  #include <linux/spinlock.h>
- #include <asm/io.h>
+ #include <linux/io.h>
  #include "pm-rcar.h"
  
 -/* SYSC */
 -#define SYSCSR 0x00
 -#define SYSCISR 0x04
 -#define SYSCISCR 0x08
 +/* SYSC Common */
 +#define SYSCSR                        0x00    /* SYSC Status Register */
 +#define SYSCISR                       0x04    /* Interrupt Status Register */
 +#define SYSCISCR              0x08    /* Interrupt Status Clear Register */
 +#define SYSCIER                       0x0c    /* Interrupt Enable Register */
 +#define SYSCIMR                       0x10    /* Interrupt Mask Register */
  
 -#define PWRSR_OFFS 0x00
 -#define PWROFFCR_OFFS 0x04
 -#define PWRONCR_OFFS 0x0c
 -#define PWRER_OFFS 0x14
 +/* SYSC Status Register */
 +#define SYSCSR_PONENB         1       /* Ready for power resume requests */
 +#define SYSCSR_POFFENB                0       /* Ready for power shutoff requests */
  
 -#define SYSCSR_RETRIES 100
 -#define SYSCSR_DELAY_US 1
 +/*
 + * Power Control Register Offsets inside the register block for each domain
 + * Note: The "CR" registers for ARM cores exist on H1 only
 + *       Use WFI to power off, CPG/APMU to resume ARM cores on R-Car Gen2
 + */
 +#define PWRSR_OFFS            0x00    /* Power Status Register */
 +#define PWROFFCR_OFFS         0x04    /* Power Shutoff Control Register */
 +#define PWROFFSR_OFFS         0x08    /* Power Shutoff Status Register */
 +#define PWRONCR_OFFS          0x0c    /* Power Resume Control Register */
 +#define PWRONSR_OFFS          0x10    /* Power Resume Status Register */
 +#define PWRER_OFFS            0x14    /* Power Shutoff/Resume Error */
 +
 +
 +#define SYSCSR_RETRIES                100
 +#define SYSCSR_DELAY_US               1
 +
 +#define PWRER_RETRIES         100
 +#define PWRER_DELAY_US                1
  
 -#define SYSCISR_RETRIES 1000
 -#define SYSCISR_DELAY_US 1
 +#define SYSCISR_RETRIES               1000
 +#define SYSCISR_DELAY_US      1
  
  static void __iomem *rcar_sysc_base;
  static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */
  
 -static int rcar_sysc_pwr_on_off(struct rcar_sysc_ch *sysc_ch,
 -                              int sr_bit, int reg_offs)
 +static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on)
  {
 +      unsigned int sr_bit, reg_offs;
        int k;
  
 +      if (on) {
 +              sr_bit = SYSCSR_PONENB;
 +              reg_offs = PWRONCR_OFFS;
 +      } else {
 +              sr_bit = SYSCSR_POFFENB;
 +              reg_offs = PWROFFCR_OFFS;
 +      }
 +
 +      /* Wait until SYSC is ready to accept a power request */
        for (k = 0; k < SYSCSR_RETRIES; k++) {
 -              if (ioread32(rcar_sysc_base + SYSCSR) & (1 << sr_bit))
 +              if (ioread32(rcar_sysc_base + SYSCSR) & BIT(sr_bit))
                        break;
                udelay(SYSCSR_DELAY_US);
        }
        if (k == SYSCSR_RETRIES)
                return -EAGAIN;
  
 -      iowrite32(1 << sysc_ch->chan_bit,
 +      /* Submit power shutoff or power resume request */
 +      iowrite32(BIT(sysc_ch->chan_bit),
                  rcar_sysc_base + sysc_ch->chan_offs + reg_offs);
  
        return 0;
  }
  
 -static int rcar_sysc_pwr_off(struct rcar_sysc_ch *sysc_ch)
 -{
 -      return rcar_sysc_pwr_on_off(sysc_ch, 0, PWROFFCR_OFFS);
 -}
 -
 -static int rcar_sysc_pwr_on(struct rcar_sysc_ch *sysc_ch)
 +static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
  {
 -      return rcar_sysc_pwr_on_off(sysc_ch, 1, PWRONCR_OFFS);
 -}
 -
 -static int rcar_sysc_update(struct rcar_sysc_ch *sysc_ch,
 -                          int (*on_off_fn)(struct rcar_sysc_ch *))
 -{
 -      unsigned int isr_mask = 1 << sysc_ch->isr_bit;
 -      unsigned int chan_mask = 1 << sysc_ch->chan_bit;
 +      unsigned int isr_mask = BIT(sysc_ch->isr_bit);
 +      unsigned int chan_mask = BIT(sysc_ch->chan_bit);
        unsigned int status;
        unsigned long flags;
        int ret = 0;
  
        iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
  
 -      do {
 -              ret = on_off_fn(sysc_ch);
 +      /* Submit power shutoff or resume request until it was accepted */
 +      for (k = 0; k < PWRER_RETRIES; k++) {
 +              ret = rcar_sysc_pwr_on_off(sysc_ch, on);
                if (ret)
                        goto out;
  
                status = ioread32(rcar_sysc_base +
                                  sysc_ch->chan_offs + PWRER_OFFS);
 -      } while (status & chan_mask);
 +              if (!(status & chan_mask))
 +                      break;
 +
 +              udelay(PWRER_DELAY_US);
 +      }
 +
 +      if (k == PWRER_RETRIES) {
 +              ret = -EIO;
 +              goto out;
 +      }
  
 +      /* Wait until the power shutoff or resume request has completed * */
        for (k = 0; k < SYSCISR_RETRIES; k++) {
                if (ioread32(rcar_sysc_base + SYSCISR) & isr_mask)
                        break;
        return ret;
  }
  
 -int rcar_sysc_power_down(struct rcar_sysc_ch *sysc_ch)
 +int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch)
  {
 -      return rcar_sysc_update(sysc_ch, rcar_sysc_pwr_off);
 +      return rcar_sysc_power(sysc_ch, false);
  }
  
 -int rcar_sysc_power_up(struct rcar_sysc_ch *sysc_ch)
 +int rcar_sysc_power_up(const struct rcar_sysc_ch *sysc_ch)
  {
 -      return rcar_sysc_update(sysc_ch, rcar_sysc_pwr_on);
 +      return rcar_sysc_power(sysc_ch, true);
  }
  
 -bool rcar_sysc_power_is_off(struct rcar_sysc_ch *sysc_ch)
 +bool rcar_sysc_power_is_off(const struct rcar_sysc_ch *sysc_ch)
  {
        unsigned int st;
  
        st = ioread32(rcar_sysc_base + sysc_ch->chan_offs + PWRSR_OFFS);
 -      if (st & (1 << sysc_ch->chan_bit))
 +      if (st & BIT(sysc_ch->chan_bit))
                return true;
  
        return false;
  #define __virt_to_phys(x)     (((phys_addr_t)(x) - PAGE_OFFSET + PHYS_OFFSET))
  #define __phys_to_virt(x)     ((unsigned long)((x) - PHYS_OFFSET + PAGE_OFFSET))
  
- /*
-  * Convert a physical address to a Page Frame Number and back
-  */
- #define       __phys_to_pfn(paddr)    ((unsigned long)((paddr) >> PAGE_SHIFT))
- #define       __pfn_to_phys(pfn)      ((phys_addr_t)(pfn) << PAGE_SHIFT)
  /*
   * Convert a page to/from a physical address
   */
@@@ -113,14 -107,6 +107,14 @@@ extern phys_addr_t               memstart_addr
  /* PHYS_OFFSET - the physical address of the start of memory. */
  #define PHYS_OFFSET           ({ memstart_addr; })
  
 +/*
 + * The maximum physical address that the linear direct mapping
 + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
 + * a 2's complement signed quantity and negated to derive the
 + * maximum size of the linear mapping.)
 + */
 +#define MAX_MEMBLOCK_ADDR     ({ memstart_addr - PAGE_OFFSET - 1; })
 +
  /*
   * PFNs are used to describe any physical page; this means
   * PFN 0 == physical address 0.
@@@ -102,7 -102,7 +102,7 @@@ static void of_pci_parse_addrs(struct d
                        res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
                } else if (i == dev->rom_base_reg) {
                        res = &dev->resource[PCI_ROM_RESOURCE];
-                       flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
+                       flags |= IORESOURCE_READONLY;
                } else {
                        printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
                        continue;
@@@ -126,6 -126,7 +126,6 @@@ struct pci_dev *of_create_pci_dev(struc
  {
        struct pci_dev *dev;
        const char *type;
 -      struct pci_slot *slot;
  
        dev = pci_alloc_dev(bus);
        if (!dev)
        dev->needs_freset = 0;          /* pcie fundamental reset required */
        set_pcie_port_type(dev);
  
 -      list_for_each_entry(slot, &dev->bus->slots, list)
 -              if (PCI_SLOT(dev->devfn) == slot->number)
 -                      dev->slot = slot;
 -
 +      pci_dev_assign_slot(dev);
        dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
        dev->device = get_int_prop(node, "device-id", 0xffff);
        dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
  
        pci_device_add(dev, bus);
  
 +      /* Setup MSI caps & disable MSI/MSI-X interrupts */
 +      pci_msi_setup_pci_dev(dev);
 +
        return dev;
  }
  EXPORT_SYMBOL(of_create_pci_dev);
diff --combined arch/powerpc/mm/mem.c
@@@ -113,7 -113,7 +113,7 @@@ int memory_add_physaddr_to_nid(u64 star
  }
  #endif
  
- int arch_add_memory(int nid, u64 start, u64 size)
+ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
  {
        struct pglist_data *pgdata;
        struct zone *zone;
  
        /* this should work for most non-highmem platforms */
        zone = pgdata->node_zones +
-               zone_for_memory(nid, start, size, 0);
+               zone_for_memory(nid, start, size, 0, for_device);
  
        return __add_pages(nid, zone, start_pfn, nr_pages);
  }
@@@ -414,17 -414,17 +414,17 @@@ void flush_dcache_icache_page(struct pa
                return;
        }
  #endif
 -#ifdef CONFIG_BOOKE
 -      {
 +#if defined(CONFIG_8xx) || defined(CONFIG_PPC64)
 +      /* On 8xx there is no need to kmap since highmem is not supported */
 +      __flush_dcache_icache(page_address(page));
 +#else
 +      if (IS_ENABLED(CONFIG_BOOKE) || sizeof(phys_addr_t) > sizeof(void *)) {
                void *start = kmap_atomic(page);
                __flush_dcache_icache(start);
                kunmap_atomic(start);
 +      } else {
 +              __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);
        }
 -#elif defined(CONFIG_8xx) || defined(CONFIG_PPC64)
 -      /* On 8xx there is no need to kmap since highmem is not supported */
 -      __flush_dcache_icache(page_address(page)); 
 -#else
 -      __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);
  #endif
  }
  EXPORT_SYMBOL(flush_dcache_icache_page);
@@@ -132,7 -132,7 +132,7 @@@ axon_ram_make_request(struct request_qu
                phys_mem += vec.bv_len;
                transfered += vec.bv_len;
        }
 -      bio_endio(bio, 0);
 +      bio_endio(bio);
  }
  
  /**
   */
  static long
  axon_ram_direct_access(struct block_device *device, sector_t sector,
-                      void **kaddr, unsigned long *pfn, long size)
+                      void __pmem **kaddr, unsigned long *pfn)
  {
        struct axon_ram_bank *bank = device->bd_disk->private_data;
        loff_t offset = (loff_t)sector << AXON_RAM_SECTOR_SHIFT;
+       void *addr = (void *)(bank->ph_addr + offset);
  
-       *kaddr = (void *)(bank->ph_addr + offset);
-       *pfn = virt_to_phys(*kaddr) >> PAGE_SHIFT;
+       *kaddr = (void __pmem *)addr;
+       *pfn = virt_to_phys(addr) >> PAGE_SHIFT;
  
        return bank->size - offset;
  }
diff --combined arch/s390/mm/init.c
@@@ -27,7 -27,6 +27,7 @@@
  #include <linux/initrd.h>
  #include <linux/export.h>
  #include <linux/gfp.h>
 +#include <linux/memblock.h>
  #include <asm/processor.h>
  #include <asm/uaccess.h>
  #include <asm/pgtable.h>
@@@ -139,7 -138,7 +139,7 @@@ void __init mem_init(void
        cpumask_set_cpu(0, mm_cpumask(&init_mm));
        atomic_set(&init_mm.context.attach_count, 1);
  
 -        max_mapnr = max_low_pfn;
 +      set_max_mapnr(max_low_pfn);
          high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
  
        /* Setup guest page hinting */
@@@ -169,38 -168,39 +169,38 @@@ void __init free_initrd_mem(unsigned lo
  #endif
  
  #ifdef CONFIG_MEMORY_HOTPLUG
- int arch_add_memory(int nid, u64 start, u64 size)
+ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
  {
 -      unsigned long zone_start_pfn, zone_end_pfn, nr_pages;
 +      unsigned long normal_end_pfn = PFN_DOWN(memblock_end_of_DRAM());
 +      unsigned long dma_end_pfn = PFN_DOWN(MAX_DMA_ADDRESS);
        unsigned long start_pfn = PFN_DOWN(start);
        unsigned long size_pages = PFN_DOWN(size);
 -      struct zone *zone;
 -      int rc;
 +      unsigned long nr_pages;
 +      int rc, zone_enum;
  
        rc = vmem_add_mapping(start, size);
        if (rc)
                return rc;
 -      for_each_zone(zone) {
 -              if (zone_idx(zone) != ZONE_MOVABLE) {
 -                      /* Add range within existing zone limits */
 -                      zone_start_pfn = zone->zone_start_pfn;
 -                      zone_end_pfn = zone->zone_start_pfn +
 -                                     zone->spanned_pages;
 +
 +      while (size_pages > 0) {
 +              if (start_pfn < dma_end_pfn) {
 +                      nr_pages = (start_pfn + size_pages > dma_end_pfn) ?
 +                                 dma_end_pfn - start_pfn : size_pages;
 +                      zone_enum = ZONE_DMA;
 +              } else if (start_pfn < normal_end_pfn) {
 +                      nr_pages = (start_pfn + size_pages > normal_end_pfn) ?
 +                                 normal_end_pfn - start_pfn : size_pages;
 +                      zone_enum = ZONE_NORMAL;
                } else {
 -                      /* Add remaining range to ZONE_MOVABLE */
 -                      zone_start_pfn = start_pfn;
 -                      zone_end_pfn = start_pfn + size_pages;
 +                      nr_pages = size_pages;
 +                      zone_enum = ZONE_MOVABLE;
                }
 -              if (start_pfn < zone_start_pfn || start_pfn >= zone_end_pfn)
 -                      continue;
 -              nr_pages = (start_pfn + size_pages > zone_end_pfn) ?
 -                         zone_end_pfn - start_pfn : size_pages;
 -              rc = __add_pages(nid, zone, start_pfn, nr_pages);
 +              rc = __add_pages(nid, NODE_DATA(nid)->node_zones + zone_enum,
 +                               start_pfn, size_pages);
                if (rc)
                        break;
                start_pfn += nr_pages;
                size_pages -= nr_pages;
 -              if (!size_pages)
 -                      break;
        }
        if (rc)
                vmem_remove_mapping(start, size);
diff --combined arch/sh/include/asm/io.h
@@@ -342,6 -342,7 +342,7 @@@ ioremap_cache(phys_addr_t offset, unsig
  {
        return __ioremap_mode(offset, size, PAGE_KERNEL);
  }
+ #define ioremap_cache ioremap_cache
  
  #ifdef CONFIG_HAVE_IOREMAP_PROT
  static inline void __iomem *
@@@ -368,7 -369,6 +369,7 @@@ static inline int iounmap_fixed(void __
  #endif
  
  #define ioremap_nocache       ioremap
 +#define ioremap_uc    ioremap
  #define iounmap               __iounmap
  
  /*
diff --combined arch/sh/mm/init.c
@@@ -485,10 -485,10 +485,10 @@@ void free_initrd_mem(unsigned long star
  #endif
  
  #ifdef CONFIG_MEMORY_HOTPLUG
- int arch_add_memory(int nid, u64 start, u64 size)
+ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
  {
        pg_data_t *pgdat;
 -      unsigned long start_pfn = start >> PAGE_SHIFT;
 +      unsigned long start_pfn = PFN_DOWN(start);
        unsigned long nr_pages = size >> PAGE_SHIFT;
        int ret;
  
  
        /* We only have ZONE_NORMAL, so this is easy.. */
        ret = __add_pages(nid, pgdat->node_zones +
-                       zone_for_memory(nid, start, size, ZONE_NORMAL),
+                       zone_for_memory(nid, start, size, ZONE_NORMAL,
+                       for_device),
                        start_pfn, nr_pages);
        if (unlikely(ret))
                printk("%s: Failed, __add_pages() == %d\n", __func__, ret);
@@@ -517,7 -518,7 +518,7 @@@ EXPORT_SYMBOL_GPL(memory_add_physaddr_t
  #ifdef CONFIG_MEMORY_HOTREMOVE
  int arch_remove_memory(u64 start, u64 size)
  {
 -      unsigned long start_pfn = start >> PAGE_SHIFT;
 +      unsigned long start_pfn = PFN_DOWN(start);
        unsigned long nr_pages = size >> PAGE_SHIFT;
        struct zone *zone;
        int ret;
diff --combined arch/sparc/kernel/pci.c
@@@ -231,8 -231,7 +231,7 @@@ static void pci_parse_of_addrs(struct p
                        res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
                } else if (i == dev->rom_base_reg) {
                        res = &dev->resource[PCI_ROM_RESOURCE];
-                       flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE
-                             | IORESOURCE_SIZEALIGN;
+                       flags |= IORESOURCE_READONLY | IORESOURCE_SIZEALIGN;
                } else {
                        printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
                        continue;
@@@ -249,6 -248,7 +248,6 @@@ static struct pci_dev *of_create_pci_de
                                         struct pci_bus *bus, int devfn)
  {
        struct dev_archdata *sd;
 -      struct pci_slot *slot;
        struct platform_device *op;
        struct pci_dev *dev;
        const char *type;
        dev->multifunction = 0;         /* maybe a lie? */
        set_pcie_port_type(dev);
  
 -      list_for_each_entry(slot, &dev->bus->slots, list)
 -              if (PCI_SLOT(dev->devfn) == slot->number)
 -                      dev->slot = slot;
 -
 +      pci_dev_assign_slot(dev);
        dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff);
        dev->device = of_getintprop_default(node, "device-id", 0xffff);
        dev->subsystem_vendor =
@@@ -914,7 -917,7 +913,7 @@@ int arch_setup_msi_irq(struct pci_dev *
  void arch_teardown_msi_irq(unsigned int irq)
  {
        struct msi_desc *entry = irq_get_msi_desc(irq);
 -      struct pci_dev *pdev = entry->dev;
 +      struct pci_dev *pdev = msi_desc_to_pci_dev(entry);
        struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
  
        if (pbm->teardown_msi_irq)
diff --combined arch/x86/Kconfig
@@@ -27,7 -27,8 +27,8 @@@ config X8
        select ARCH_HAS_ELF_RANDOMIZE
        select ARCH_HAS_FAST_MULTIPLIER
        select ARCH_HAS_GCOV_PROFILE_ALL
-       select ARCH_HAS_PMEM_API
+       select ARCH_HAS_PMEM_API                if X86_64
+       select ARCH_HAS_MMIO_FLUSH
        select ARCH_HAS_SG_CHAIN
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select ARCH_MIGHT_HAVE_ACPI_PDC         if ACPI
@@@ -41,7 -42,6 +42,7 @@@
        select ARCH_USE_CMPXCHG_LOCKREF         if X86_64
        select ARCH_USE_QUEUED_RWLOCKS
        select ARCH_USE_QUEUED_SPINLOCKS
 +      select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH if SMP
        select ARCH_WANTS_DYNAMIC_TASK_STRUCT
        select ARCH_WANT_FRAME_POINTERS
        select ARCH_WANT_IPC_PARSE_VERSION      if X86_32
        select HAVE_PERF_USER_STACK_DUMP
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_SYSCALL_TRACEPOINTS
 -      select HAVE_UID16                       if X86_32
 +      select HAVE_UID16                       if X86_32 || IA32_EMULATION
        select HAVE_UNSTABLE_SCHED_CLOCK
        select HAVE_USER_RETURN_NOTIFIER
        select IRQ_FORCED_THREADING
@@@ -956,7 -956,6 +957,7 @@@ config X86_REROUTE_FOR_BROKEN_BOOT_IRQ
  
  config X86_MCE
        bool "Machine Check / overheating reporting"
 +      select GENERIC_ALLOCATOR
        default y
        ---help---
          Machine Check support allows the processor to notify the
@@@ -1004,41 -1003,19 +1005,41 @@@ config X86_THERMAL_VECTO
        def_bool y
        depends on X86_MCE_INTEL
  
 -config VM86
 -      bool "Enable VM86 support" if EXPERT
 -      default y
 +config X86_LEGACY_VM86
 +      bool "Legacy VM86 support (obsolete)"
 +      default n
        depends on X86_32
        ---help---
 -        This option is required by programs like DOSEMU to run
 -        16-bit real mode legacy code on x86 processors. It also may
 -        be needed by software like XFree86 to initialize some video
 -        cards via BIOS. Disabling this option saves about 6K.
 +        This option allows user programs to put the CPU into V8086
 +        mode, which is an 80286-era approximation of 16-bit real mode.
 +
 +        Some very old versions of X and/or vbetool require this option
 +        for user mode setting.  Similarly, DOSEMU will use it if
 +        available to accelerate real mode DOS programs.  However, any
 +        recent version of DOSEMU, X, or vbetool should be fully
 +        functional even without kernel VM86 support, as they will all
 +        fall back to (pretty well performing) software emulation.
 +
 +        Anything that works on a 64-bit kernel is unlikely to need
 +        this option, as 64-bit kernels don't, and can't, support V8086
 +        mode.  This option is also unrelated to 16-bit protected mode
 +        and is not needed to run most 16-bit programs under Wine.
 +
 +        Enabling this option adds considerable attack surface to the
 +        kernel and slows down system calls and exception handling.
 +
 +        Unless you use very old userspace or need the last drop of
 +        performance in your real mode DOS games and can't use KVM,
 +        say N here.
 +
 +config VM86
 +       bool
 +       default X86_LEGACY_VM86
  
  config X86_16BIT
        bool "Enable support for 16-bit segments" if EXPERT
        default y
 +      depends on MODIFY_LDT_SYSCALL
        ---help---
          This option is required by programs like Wine to run 16-bit
          protected mode legacy code on x86 processors.  Disabling
@@@ -1450,10 -1427,14 +1451,14 @@@ config ILLEGAL_POINTER_VALU
  
  source "mm/Kconfig"
  
+ config X86_PMEM_LEGACY_DEVICE
+       bool
  config X86_PMEM_LEGACY
-       bool "Support non-standard NVDIMMs and ADR protected memory"
+       tristate "Support non-standard NVDIMMs and ADR protected memory"
        depends on PHYS_ADDR_T_64BIT
        depends on BLK_DEV
+       select X86_PMEM_LEGACY_DEVICE
        select LIBNVDIMM
        help
          Treat memory marked using the non-standard e820 type of 12 as used
@@@ -1533,7 -1514,6 +1538,7 @@@ config X86_RESERVE_LO
  
  config MATH_EMULATION
        bool
 +      depends on MODIFY_LDT_SYSCALL
        prompt "Math emulation" if X86_32
        ---help---
          Linux can emulate a math coprocessor (used for floating point
@@@ -2078,22 -2058,6 +2083,22 @@@ config CMDLINE_OVERRID
          This is used to work around broken boot loaders.  This should
          be set to 'N' under normal conditions.
  
 +config MODIFY_LDT_SYSCALL
 +      bool "Enable the LDT (local descriptor table)" if EXPERT
 +      default y
 +      ---help---
 +        Linux can allow user programs to install a per-process x86
 +        Local Descriptor Table (LDT) using the modify_ldt(2) system
 +        call.  This is required to run 16-bit or segmented code such as
 +        DOSEMU or some Wine programs.  It is also used by some very old
 +        threading libraries.
 +
 +        Enabling this feature adds a small amount of overhead to
 +        context switches and increases the low-level kernel attack
 +        surface.  Disabling it removes the modify_ldt(2) system call.
 +
 +        Saying 'N' here may make sense for embedded or server kernels.
 +
  source "kernel/livepatch/Kconfig"
  
  endmenu
@@@ -2563,7 -2527,7 +2568,7 @@@ config IA32_EMULATIO
        depends on X86_64
        select BINFMT_ELF
        select COMPAT_BINFMT_ELF
 -      select HAVE_UID16
 +      select ARCH_WANT_OLD_COMPAT_IPC
        ---help---
          Include code to run legacy 32-bit programs under a
          64-bit kernel. You should likely turn this on, unless you're
@@@ -2577,7 -2541,7 +2582,7 @@@ config IA32_AOU
  
  config X86_X32
        bool "x32 ABI for 64-bit mode"
 -      depends on X86_64 && IA32_EMULATION
 +      depends on X86_64
        ---help---
          Include code to run binaries for the x32 native 32-bit ABI
          for 64-bit processors.  An x32 process gets access to the
  config COMPAT
        def_bool y
        depends on IA32_EMULATION || X86_X32
 -      select ARCH_WANT_OLD_COMPAT_IPC
  
  if COMPAT
  config COMPAT_FOR_U64_ALIGNMENT
@@@ -180,8 -180,6 +180,8 @@@ static inline unsigned int isa_virt_to_
   */
  extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
  extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size);
 +#define ioremap_uc ioremap_uc
 +
  extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
  extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
                                unsigned long prot_val);
@@@ -250,12 -248,6 +250,6 @@@ static inline void flush_write_buffers(
  #endif
  }
  
- static inline void __pmem *arch_memremap_pmem(resource_size_t offset,
-       unsigned long size)
- {
-       return (void __force __pmem *) ioremap_cache(offset, size);
- }
  #endif /* __KERNEL__ */
  
  extern void native_io_delay(void);
diff --combined arch/x86/kernel/Makefile
@@@ -23,10 -23,8 +23,10 @@@ KASAN_SANITIZE_dumpstack_$(BITS).o := 
  CFLAGS_irq.o := -I$(src)/../include/asm/trace
  
  obj-y                 := process_$(BITS).o signal.o
 +obj-$(CONFIG_COMPAT)  += signal_compat.o
  obj-y                 += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
 -obj-y                 += time.o ioport.o ldt.o dumpstack.o nmi.o
 +obj-y                 += time.o ioport.o dumpstack.o nmi.o
 +obj-$(CONFIG_MODIFY_LDT_SYSCALL)      += ldt.o
  obj-y                 += setup.o x86_init.o i8259.o irqinit.o jump_label.o
  obj-$(CONFIG_IRQ_WORK)  += irq_work.o
  obj-y                 += probe_roms.o
@@@ -94,7 -92,7 +94,7 @@@ obj-$(CONFIG_KVM_GUEST)               += kvm.o kvmcl
  obj-$(CONFIG_PARAVIRT)                += paravirt.o paravirt_patch_$(BITS).o
  obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o
  obj-$(CONFIG_PARAVIRT_CLOCK)  += pvclock.o
- obj-$(CONFIG_X86_PMEM_LEGACY) += pmem.o
+ obj-$(CONFIG_X86_PMEM_LEGACY_DEVICE) += pmem.o
  
  obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o
  
@@@ -109,6 -107,8 +109,6 @@@ obj-$(CONFIG_EFI)                  += sysfb_efi.
  
  obj-$(CONFIG_PERF_EVENTS)             += perf_regs.o
  obj-$(CONFIG_TRACING)                 += tracepoint.o
 -obj-$(CONFIG_IOSF_MBI)                        += iosf_mbi.o
 -obj-$(CONFIG_PMC_ATOM)                        += pmc_atom.o
  
  ###
  # 64 bit specific files
diff --combined arch/x86/mm/init_32.c
@@@ -137,7 -137,6 +137,7 @@@ page_table_range_init_count(unsigned lo
  
        vaddr = start;
        pgd_idx = pgd_index(vaddr);
 +      pmd_idx = pmd_index(vaddr);
  
        for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd_idx++) {
                for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
@@@ -823,11 -822,11 +823,11 @@@ void __init mem_init(void
  }
  
  #ifdef CONFIG_MEMORY_HOTPLUG
- int arch_add_memory(int nid, u64 start, u64 size)
+ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
  {
        struct pglist_data *pgdata = NODE_DATA(nid);
        struct zone *zone = pgdata->node_zones +
-               zone_for_memory(nid, start, size, ZONE_HIGHMEM);
+               zone_for_memory(nid, start, size, ZONE_HIGHMEM, for_device);
        unsigned long start_pfn = start >> PAGE_SHIFT;
        unsigned long nr_pages = size >> PAGE_SHIFT;
  
diff --combined drivers/acpi/Kconfig
@@@ -189,24 -189,17 +189,24 @@@ config ACPI_DOC
          This driver supports ACPI-controlled docking stations and removable
          drive bays such as the IBM Ultrabay and the Dell Module Bay.
  
 -config ACPI_PROCESSOR
 -      tristate "Processor"
 +config ACPI_CPU_FREQ_PSS
 +      bool
        select THERMAL
 +
 +config ACPI_PROCESSOR_IDLE
 +      bool
        select CPU_IDLE
 +
 +config ACPI_PROCESSOR
 +      tristate "Processor"
        depends on X86 || IA64
 +      select ACPI_PROCESSOR_IDLE
 +      select ACPI_CPU_FREQ_PSS
        default y
        help
 -        This driver installs ACPI as the idle handler for Linux and uses
 -        ACPI C2 and C3 processor states to save power on systems that
 -        support it.  It is required by several flavors of cpufreq
 -        performance-state drivers.
 +        This driver adds support for the ACPI Processor package. It is required
 +        by several flavors of cpufreq performance-state, thermal, throttling and
 +        idle drivers.
  
          To compile this driver as a module, choose M here:
          the module will be called processor.
@@@ -417,6 -410,7 +417,7 @@@ config ACPI_NFI
        tristate "ACPI NVDIMM Firmware Interface Table (NFIT)"
        depends on PHYS_ADDR_T_64BIT
        depends on BLK_DEV
+       depends on ARCH_HAS_MMIO_FLUSH
        select LIBNVDIMM
        help
          Infrastructure to probe ACPI 6 compliant platforms for
diff --combined drivers/acpi/nfit.c
@@@ -20,6 -20,7 +20,7 @@@
  #include <linux/sort.h>
  #include <linux/pmem.h>
  #include <linux/io.h>
+ #include <asm/cacheflush.h>
  #include "nfit.h"
  
  /*
@@@ -702,11 -703,11 +703,11 @@@ static ssize_t flags_show(struct devic
        u16 flags = to_nfit_memdev(dev)->flags;
  
        return sprintf(buf, "%s%s%s%s%s\n",
 -                      flags & ACPI_NFIT_MEM_SAVE_FAILED ? "save " : "",
 -                      flags & ACPI_NFIT_MEM_RESTORE_FAILED ? "restore " : "",
 -                      flags & ACPI_NFIT_MEM_FLUSH_FAILED ? "flush " : "",
 -                      flags & ACPI_NFIT_MEM_ARMED ? "arm " : "",
 -                      flags & ACPI_NFIT_MEM_HEALTH_OBSERVED ? "smart " : "");
 +              flags & ACPI_NFIT_MEM_SAVE_FAILED ? "save_fail " : "",
 +              flags & ACPI_NFIT_MEM_RESTORE_FAILED ? "restore_fail " : "",
 +              flags & ACPI_NFIT_MEM_FLUSH_FAILED ? "flush_fail " : "",
 +              flags & ACPI_NFIT_MEM_ARMED ? "not_armed " : "",
 +              flags & ACPI_NFIT_MEM_HEALTH_OBSERVED ? "smart_event " : "");
  }
  static DEVICE_ATTR_RO(flags);
  
@@@ -764,9 -765,7 +765,7 @@@ static int acpi_nfit_add_dimm(struct ac
        struct acpi_device *adev, *adev_dimm;
        struct device *dev = acpi_desc->dev;
        const u8 *uuid = to_nfit_uuid(NFIT_DEV_DIMM);
-       unsigned long long sta;
-       int i, rc = -ENODEV;
-       acpi_status status;
+       int i;
  
        nfit_mem->dsm_mask = acpi_desc->dimm_dsm_force_en;
        adev = to_acpi_dev(acpi_desc);
                return force_enable_dimms ? 0 : -ENODEV;
        }
  
-       status = acpi_evaluate_integer(adev_dimm->handle, "_STA", NULL, &sta);
-       if (status == AE_NOT_FOUND) {
-               dev_dbg(dev, "%s missing _STA, assuming enabled...\n",
-                               dev_name(&adev_dimm->dev));
-               rc = 0;
-       } else if (ACPI_FAILURE(status))
-               dev_err(dev, "%s failed to retrieve_STA, disabling...\n",
-                               dev_name(&adev_dimm->dev));
-       else if ((sta & ACPI_STA_DEVICE_ENABLED) == 0)
-               dev_info(dev, "%s disabled by firmware\n",
-                               dev_name(&adev_dimm->dev));
-       else
-               rc = 0;
        for (i = ND_CMD_SMART; i <= ND_CMD_VENDOR; i++)
                if (acpi_check_dsm(adev_dimm->handle, uuid, 1, 1ULL << i))
                        set_bit(i, &nfit_mem->dsm_mask);
  
-       return force_enable_dimms ? 0 : rc;
+       return 0;
  }
  
  static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
                if ((mem_flags & ACPI_NFIT_MEM_FAILED_MASK) == 0)
                        continue;
  
 -              dev_info(acpi_desc->dev, "%s: failed: %s%s%s%s\n",
 +              dev_info(acpi_desc->dev, "%s flags:%s%s%s%s\n",
                                nvdimm_name(nvdimm),
 -                      mem_flags & ACPI_NFIT_MEM_SAVE_FAILED ? "save " : "",
 -                      mem_flags & ACPI_NFIT_MEM_RESTORE_FAILED ? "restore " : "",
 -                      mem_flags & ACPI_NFIT_MEM_FLUSH_FAILED ? "flush " : "",
 -                      mem_flags & ACPI_NFIT_MEM_ARMED ? "arm " : "");
 +                mem_flags & ACPI_NFIT_MEM_SAVE_FAILED ? " save_fail" : "",
 +                mem_flags & ACPI_NFIT_MEM_RESTORE_FAILED ? " restore_fail":"",
 +                mem_flags & ACPI_NFIT_MEM_FLUSH_FAILED ? " flush_fail" : "",
 +                mem_flags & ACPI_NFIT_MEM_ARMED ? " not_armed" : "");
  
        }
  
@@@ -868,6 -853,7 +853,7 @@@ static void acpi_nfit_init_dsms(struct 
        struct acpi_device *adev;
        int i;
  
+       nd_desc->dsm_mask = acpi_desc->bus_dsm_force_en;
        adev = to_acpi_dev(acpi_desc);
        if (!adev)
                return;
@@@ -1024,7 -1010,7 +1010,7 @@@ static void wmb_blk(struct nfit_blk *nf
                wmb_pmem();
  }
  
 -static u64 read_blk_stat(struct nfit_blk *nfit_blk, unsigned int bw)
 +static u32 read_blk_stat(struct nfit_blk *nfit_blk, unsigned int bw)
  {
        struct nfit_blk_mmio *mmio = &nfit_blk->mmio[DCR];
        u64 offset = nfit_blk->stat_offset + mmio->size * bw;
        if (mmio->num_lines)
                offset = to_interleave_offset(offset, mmio);
  
-       return readl(mmio->base + offset);
 -      return readq(mmio->addr.base + offset);
++      return readl(mmio->addr.base + offset);
  }
  
  static void write_blk_ctl(struct nfit_blk *nfit_blk, unsigned int bw,
        if (mmio->num_lines)
                offset = to_interleave_offset(offset, mmio);
  
-       writeq(cmd, mmio->base + offset);
+       writeq(cmd, mmio->addr.base + offset);
        wmb_blk(nfit_blk);
  
        if (nfit_blk->dimm_flags & ND_BLK_DCR_LATCH)
-               readq(mmio->base + offset);
+               readq(mmio->addr.base + offset);
  }
  
  static int acpi_nfit_blk_single_io(struct nfit_blk *nfit_blk,
                }
  
                if (rw)
-                       memcpy_to_pmem(mmio->aperture + offset,
+                       memcpy_to_pmem(mmio->addr.aperture + offset,
                                        iobuf + copied, c);
-               else
+               else {
+                       if (nfit_blk->dimm_flags & ND_BLK_READ_FLUSH)
+                               mmio_flush_range((void __force *)
+                                       mmio->addr.aperture + offset, c);
                        memcpy_from_pmem(iobuf + copied,
-                                       mmio->aperture + offset, c);
+                                       mmio->addr.aperture + offset, c);
+               }
  
                copied += c;
                len -= c;
@@@ -1144,7 -1135,10 +1135,10 @@@ static void nfit_spa_mapping_release(st
  
        WARN_ON(!mutex_is_locked(&acpi_desc->spa_map_mutex));
        dev_dbg(acpi_desc->dev, "%s: SPA%d\n", __func__, spa->range_index);
-       iounmap(spa_map->iomem);
+       if (spa_map->type == SPA_MAP_APERTURE)
+               memunmap((void __force *)spa_map->addr.aperture);
+       else
+               iounmap(spa_map->addr.base);
        release_mem_region(spa->address, spa->length);
        list_del(&spa_map->list);
        kfree(spa_map);
@@@ -1190,7 -1184,7 +1184,7 @@@ static void __iomem *__nfit_spa_map(str
        spa_map = find_spa_mapping(acpi_desc, spa);
        if (spa_map) {
                kref_get(&spa_map->kref);
-               return spa_map->iomem;
+               return spa_map->addr.base;
        }
  
        spa_map = kzalloc(sizeof(*spa_map), GFP_KERNEL);
        if (!res)
                goto err_mem;
  
-       if (type == SPA_MAP_APERTURE) {
-               /*
-                * TODO: memremap_pmem() support, but that requires cache
-                * flushing when the aperture is moved.
-                */
-               spa_map->iomem = ioremap_wc(start, n);
-       } else
-               spa_map->iomem = ioremap_nocache(start, n);
+       spa_map->type = type;
+       if (type == SPA_MAP_APERTURE)
+               spa_map->addr.aperture = (void __pmem *)memremap(start, n,
+                                                       ARCH_MEMREMAP_PMEM);
+       else
+               spa_map->addr.base = ioremap_nocache(start, n);
  
-       if (!spa_map->iomem)
+       if (!spa_map->addr.base)
                goto err_map;
  
        list_add_tail(&spa_map->list, &acpi_desc->spa_maps);
-       return spa_map->iomem;
+       return spa_map->addr.base;
  
   err_map:
        release_mem_region(start, n);
@@@ -1282,7 -1275,7 +1275,7 @@@ static int acpi_nfit_blk_get_flags(stru
                nfit_blk->dimm_flags = flags.flags;
        else if (rc == -ENOTTY) {
                /* fall back to a conservative default */
-               nfit_blk->dimm_flags = ND_BLK_DCR_LATCH;
+               nfit_blk->dimm_flags = ND_BLK_DCR_LATCH | ND_BLK_READ_FLUSH;
                rc = 0;
        } else
                rc = -ENXIO;
@@@ -1322,9 -1315,9 +1315,9 @@@ static int acpi_nfit_blk_region_enable(
        /* map block aperture memory */
        nfit_blk->bdw_offset = nfit_mem->bdw->offset;
        mmio = &nfit_blk->mmio[BDW];
-       mmio->base = nfit_spa_map(acpi_desc, nfit_mem->spa_bdw,
+       mmio->addr.base = nfit_spa_map(acpi_desc, nfit_mem->spa_bdw,
                        SPA_MAP_APERTURE);
-       if (!mmio->base) {
+       if (!mmio->addr.base) {
                dev_dbg(dev, "%s: %s failed to map bdw\n", __func__,
                                nvdimm_name(nvdimm));
                return -ENOMEM;
        nfit_blk->cmd_offset = nfit_mem->dcr->command_offset;
        nfit_blk->stat_offset = nfit_mem->dcr->status_offset;
        mmio = &nfit_blk->mmio[DCR];
-       mmio->base = nfit_spa_map(acpi_desc, nfit_mem->spa_dcr,
+       mmio->addr.base = nfit_spa_map(acpi_desc, nfit_mem->spa_dcr,
                        SPA_MAP_CONTROL);
-       if (!mmio->base) {
+       if (!mmio->addr.base) {
                dev_dbg(dev, "%s: %s failed to map dcr\n", __func__,
                                nvdimm_name(nvdimm));
                return -ENOMEM;
                        return -ENOMEM;
        }
  
-       if (!arch_has_pmem_api() && !nfit_blk->nvdimm_flush)
+       if (!arch_has_wmb_pmem() && !nfit_blk->nvdimm_flush)
                dev_warn(dev, "unable to guarantee persistence of writes\n");
  
        if (mmio->line_size == 0)
@@@ -1414,7 -1407,7 +1407,7 @@@ static void acpi_nfit_blk_region_disabl
        for (i = 0; i < 2; i++) {
                struct nfit_blk_mmio *mmio = &nfit_blk->mmio[i];
  
-               if (mmio->base)
+               if (mmio->addr.base)
                        nfit_spa_unmap(acpi_desc, mmio->spa);
        }
        nd_blk_region_set_provider_data(ndbr, NULL);
diff --combined drivers/block/brd.c
@@@ -331,12 -331,14 +331,12 @@@ static void brd_make_request(struct req
        struct bio_vec bvec;
        sector_t sector;
        struct bvec_iter iter;
 -      int err = -EIO;
  
        sector = bio->bi_iter.bi_sector;
        if (bio_end_sector(bio) > get_capacity(bdev->bd_disk))
 -              goto out;
 +              goto io_error;
  
        if (unlikely(bio->bi_rw & REQ_DISCARD)) {
 -              err = 0;
                discard_from_brd(brd, sector, bio->bi_iter.bi_size);
                goto out;
        }
  
        bio_for_each_segment(bvec, bio, iter) {
                unsigned int len = bvec.bv_len;
 +              int err;
 +
                err = brd_do_bvec(brd, bvec.bv_page, len,
                                        bvec.bv_offset, rw, sector);
                if (err)
 -                      break;
 +                      goto io_error;
                sector += len >> SECTOR_SHIFT;
        }
  
  out:
 -      bio_endio(bio, err);
 +      bio_endio(bio);
 +      return;
 +io_error:
 +      bio_io_error(bio);
  }
  
  static int brd_rw_page(struct block_device *bdev, sector_t sector,
  
  #ifdef CONFIG_BLK_DEV_RAM_DAX
  static long brd_direct_access(struct block_device *bdev, sector_t sector,
-                       void **kaddr, unsigned long *pfn, long size)
+                       void __pmem **kaddr, unsigned long *pfn)
  {
        struct brd_device *brd = bdev->bd_disk->private_data;
        struct page *page;
        page = brd_insert_page(brd, sector);
        if (!page)
                return -ENOSPC;
-       *kaddr = page_address(page);
+       *kaddr = (void __pmem *)page_address(page);
        *pfn = page_to_pfn(page);
  
-       /*
-        * TODO: If size > PAGE_SIZE, we could look to see if the next page in
-        * the file happens to be mapped to the next page of physical RAM.
-        */
        return PAGE_SIZE;
  }
  #else
@@@ -503,7 -496,7 +499,7 @@@ static struct brd_device *brd_alloc(in
        blk_queue_physical_block_size(brd->brd_queue, PAGE_SIZE);
  
        brd->brd_queue->limits.discard_granularity = PAGE_SIZE;
 -      brd->brd_queue->limits.max_discard_sectors = UINT_MAX;
 +      blk_queue_max_discard_sectors(brd->brd_queue, UINT_MAX);
        brd->brd_queue->limits.discard_zeroes_data = 1;
        queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, brd->brd_queue);
  
diff --combined drivers/nvdimm/btt.c
@@@ -582,33 -582,6 +582,6 @@@ static void free_arenas(struct btt *btt
        }
  }
  
- /*
-  * This function checks if the metadata layout is valid and error free
-  */
- static int arena_is_valid(struct arena_info *arena, struct btt_sb *super,
-                               u8 *uuid, u32 lbasize)
- {
-       u64 checksum;
-       if (memcmp(super->uuid, uuid, 16))
-               return 0;
-       checksum = le64_to_cpu(super->checksum);
-       super->checksum = 0;
-       if (checksum != nd_btt_sb_checksum(super))
-               return 0;
-       super->checksum = cpu_to_le64(checksum);
-       if (lbasize != le32_to_cpu(super->external_lbasize))
-               return 0;
-       /* TODO: figure out action for this */
-       if ((le32_to_cpu(super->flags) & IB_FLAG_ERROR_MASK) != 0)
-               dev_info(to_dev(arena), "Found arena with an error flag\n");
-       return 1;
- }
  /*
   * This function reads an existing valid btt superblock and
   * populates the corresponding arena_info struct
@@@ -632,8 -605,9 +605,9 @@@ static void parse_arena_meta(struct are
        arena->logoff = arena_off + le64_to_cpu(super->logoff);
        arena->info2off = arena_off + le64_to_cpu(super->info2off);
  
-       arena->size = (super->nextoff > 0) ? (le64_to_cpu(super->nextoff)) :
-                       (arena->info2off - arena->infooff + BTT_PG_SIZE);
+       arena->size = (le64_to_cpu(super->nextoff) > 0)
+               ? (le64_to_cpu(super->nextoff))
+               : (arena->info2off - arena->infooff + BTT_PG_SIZE);
  
        arena->flags = le32_to_cpu(super->flags);
  }
@@@ -665,8 -639,7 +639,7 @@@ static int discover_arenas(struct btt *
                if (ret)
                        goto out;
  
-               if (!arena_is_valid(arena, super, btt->nd_btt->uuid,
-                               btt->lbasize)) {
+               if (!nd_btt_arena_is_valid(btt->nd_btt, super)) {
                        if (remaining == btt->rawsize) {
                                btt->init_state = INIT_NOTFOUND;
                                dev_info(to_dev(arena), "No existing arenas\n");
@@@ -755,10 -728,13 +728,13 @@@ static int create_arenas(struct btt *bt
   * It is only called for an uninitialized arena when a write
   * to that arena occurs for the first time.
   */
- static int btt_arena_write_layout(struct arena_info *arena, u8 *uuid)
+ static int btt_arena_write_layout(struct arena_info *arena)
  {
        int ret;
+       u64 sum;
        struct btt_sb *super;
+       struct nd_btt *nd_btt = arena->nd_btt;
+       const u8 *parent_uuid = nd_dev_to_uuid(&nd_btt->ndns->dev);
  
        ret = btt_map_init(arena);
        if (ret)
                return -ENOMEM;
  
        strncpy(super->signature, BTT_SIG, BTT_SIG_LEN);
-       memcpy(super->uuid, uuid, 16);
+       memcpy(super->uuid, nd_btt->uuid, 16);
+       memcpy(super->parent_uuid, parent_uuid, 16);
        super->flags = cpu_to_le32(arena->flags);
        super->version_major = cpu_to_le16(arena->version_major);
        super->version_minor = cpu_to_le16(arena->version_minor);
        super->info2off = cpu_to_le64(arena->info2off - arena->infooff);
  
        super->flags = 0;
-       super->checksum = cpu_to_le64(nd_btt_sb_checksum(super));
+       sum = nd_sb_checksum((struct nd_gen_sb *) super);
+       super->checksum = cpu_to_le64(sum);
  
        ret = btt_info_write(arena, super);
  
@@@ -813,7 -791,7 +791,7 @@@ static int btt_meta_init(struct btt *bt
  
        mutex_lock(&btt->init_lock);
        list_for_each_entry(arena, &btt->arena_list, list) {
-               ret = btt_arena_write_layout(arena, btt->nd_btt->uuid);
+               ret = btt_arena_write_layout(arena);
                if (ret)
                        goto unlock;
  
@@@ -1189,7 -1167,7 +1167,7 @@@ static void btt_make_request(struct req
         * another kernel subsystem, and we just pass it through.
         */
        if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
 -              err = -EIO;
 +              bio->bi_error = -EIO;
                goto out;
        }
  
                                        "io error in %s sector %lld, len %d,\n",
                                        (rw == READ) ? "READ" : "WRITE",
                                        (unsigned long long) iter.bi_sector, len);
 +                      bio->bi_error = err;
                        break;
                }
        }
                nd_iostat_end(bio, start);
  
  out:
 -      bio_endio(bio, err);
 +      bio_endio(bio);
  }
  
  static int btt_rw_page(struct block_device *bdev, sector_t sector,
@@@ -1447,8 -1424,6 +1425,6 @@@ static int __init nd_btt_init(void
  {
        int rc;
  
-       BUILD_BUG_ON(sizeof(struct btt_sb) != SZ_4K);
        btt_major = register_blkdev(0, "btt");
        if (btt_major < 0)
                return btt_major;
diff --combined drivers/nvdimm/pmem.c
  #include <linux/init.h>
  #include <linux/platform_device.h>
  #include <linux/module.h>
+ #include <linux/memory_hotplug.h>
  #include <linux/moduleparam.h>
+ #include <linux/vmalloc.h>
  #include <linux/slab.h>
  #include <linux/pmem.h>
  #include <linux/nd.h>
+ #include "pfn.h"
  #include "nd.h"
  
  struct pmem_device {
        struct request_queue    *pmem_queue;
        struct gendisk          *pmem_disk;
+       struct nd_namespace_common *ndns;
  
        /* One contiguous memory region per device */
        phys_addr_t             phys_addr;
+       /* when non-zero this device is hosting a 'pfn' instance */
+       phys_addr_t             data_offset;
        void __pmem             *virt_addr;
        size_t                  size;
  };
@@@ -44,7 -50,7 +50,7 @@@ static void pmem_do_bvec(struct pmem_de
                        sector_t sector)
  {
        void *mem = kmap_atomic(page);
-       size_t pmem_off = sector << 9;
+       phys_addr_t pmem_off = sector * 512 + pmem->data_offset;
        void __pmem *pmem_addr = pmem->virt_addr + pmem_off;
  
        if (rw == READ) {
@@@ -77,7 -83,7 +83,7 @@@ static void pmem_make_request(struct re
        if (bio_data_dir(bio))
                wmb_pmem();
  
 -      bio_endio(bio, 0);
 +      bio_endio(bio);
  }
  
  static int pmem_rw_page(struct block_device *bdev, sector_t sector,
  }
  
  static long pmem_direct_access(struct block_device *bdev, sector_t sector,
-                             void **kaddr, unsigned long *pfn, long size)
+                     void __pmem **kaddr, unsigned long *pfn)
  {
        struct pmem_device *pmem = bdev->bd_disk->private_data;
-       size_t offset = sector << 9;
-       if (!pmem)
-               return -ENODEV;
+       resource_size_t offset = sector * 512 + pmem->data_offset;
+       resource_size_t size;
+       if (pmem->data_offset) {
+               /*
+                * Limit the direct_access() size to what is covered by
+                * the memmap
+                */
+               size = (pmem->size - offset) & ~ND_PFN_MASK;
+       } else
+               size = pmem->size - offset;
  
        /* FIXME convert DAX to comprehend that this mapping has a lifetime */
-       *kaddr = (void __force *) pmem->virt_addr + offset;
+       *kaddr = pmem->virt_addr + offset;
        *pfn = (pmem->phys_addr + offset) >> PAGE_SHIFT;
  
-       return pmem->size - offset;
+       return size;
  }
  
  static const struct block_device_operations pmem_fops = {
@@@ -119,27 -132,33 +132,33 @@@ static struct pmem_device *pmem_alloc(s
  {
        struct pmem_device *pmem;
  
-       pmem = kzalloc(sizeof(*pmem), GFP_KERNEL);
+       pmem = devm_kzalloc(dev, sizeof(*pmem), GFP_KERNEL);
        if (!pmem)
                return ERR_PTR(-ENOMEM);
  
        pmem->phys_addr = res->start;
        pmem->size = resource_size(res);
-       if (!arch_has_pmem_api())
+       if (!arch_has_wmb_pmem())
                dev_warn(dev, "unable to guarantee persistence of writes\n");
  
-       if (!request_mem_region(pmem->phys_addr, pmem->size, dev_name(dev))) {
+       if (!devm_request_mem_region(dev, pmem->phys_addr, pmem->size,
+                       dev_name(dev))) {
                dev_warn(dev, "could not reserve region [0x%pa:0x%zx]\n",
                                &pmem->phys_addr, pmem->size);
-               kfree(pmem);
                return ERR_PTR(-EBUSY);
        }
  
-       pmem->virt_addr = memremap_pmem(pmem->phys_addr, pmem->size);
-       if (!pmem->virt_addr) {
-               release_mem_region(pmem->phys_addr, pmem->size);
-               kfree(pmem);
-               return ERR_PTR(-ENXIO);
+       if (pmem_should_map_pages(dev)) {
+               void *addr = devm_memremap_pages(dev, res);
+               if (IS_ERR(addr))
+                       return addr;
+               pmem->virt_addr = (void __pmem *) addr;
+       } else {
+               pmem->virt_addr = memremap_pmem(dev, pmem->phys_addr,
+                               pmem->size);
+               if (!pmem->virt_addr)
+                       return ERR_PTR(-ENXIO);
        }
  
        return pmem;
  
  static void pmem_detach_disk(struct pmem_device *pmem)
  {
+       if (!pmem->pmem_disk)
+               return;
        del_gendisk(pmem->pmem_disk);
        put_disk(pmem->pmem_disk);
        blk_cleanup_queue(pmem->pmem_queue);
  }
  
- static int pmem_attach_disk(struct nd_namespace_common *ndns,
-               struct pmem_device *pmem)
+ static int pmem_attach_disk(struct device *dev,
+               struct nd_namespace_common *ndns, struct pmem_device *pmem)
  {
        struct gendisk *disk;
  
                return -ENOMEM;
  
        blk_queue_make_request(pmem->pmem_queue, pmem_make_request);
+       blk_queue_physical_block_size(pmem->pmem_queue, PAGE_SIZE);
        blk_queue_max_hw_sectors(pmem->pmem_queue, UINT_MAX);
        blk_queue_bounce_limit(pmem->pmem_queue, BLK_BOUNCE_ANY);
        queue_flag_set_unlocked(QUEUE_FLAG_NONROT, pmem->pmem_queue);
        disk->queue             = pmem->pmem_queue;
        disk->flags             = GENHD_FL_EXT_DEVT;
        nvdimm_namespace_disk_name(ndns, disk->disk_name);
-       disk->driverfs_dev = &ndns->dev;
-       set_capacity(disk, pmem->size >> 9);
+       disk->driverfs_dev = dev;
+       set_capacity(disk, (pmem->size - pmem->data_offset) / 512);
        pmem->pmem_disk = disk;
  
        add_disk(disk);
@@@ -209,11 -232,152 +232,152 @@@ static int pmem_rw_bytes(struct nd_name
        return 0;
  }
  
- static void pmem_free(struct pmem_device *pmem)
+ static int nd_pfn_init(struct nd_pfn *nd_pfn)
+ {
+       struct nd_pfn_sb *pfn_sb = kzalloc(sizeof(*pfn_sb), GFP_KERNEL);
+       struct pmem_device *pmem = dev_get_drvdata(&nd_pfn->dev);
+       struct nd_namespace_common *ndns = nd_pfn->ndns;
+       struct nd_region *nd_region;
+       unsigned long npfns;
+       phys_addr_t offset;
+       u64 checksum;
+       int rc;
+       if (!pfn_sb)
+               return -ENOMEM;
+       nd_pfn->pfn_sb = pfn_sb;
+       rc = nd_pfn_validate(nd_pfn);
+       if (rc == 0 || rc == -EBUSY)
+               return rc;
+       /* section alignment for simple hotplug */
+       if (nvdimm_namespace_capacity(ndns) < ND_PFN_ALIGN
+                       || pmem->phys_addr & ND_PFN_MASK)
+               return -ENODEV;
+       nd_region = to_nd_region(nd_pfn->dev.parent);
+       if (nd_region->ro) {
+               dev_info(&nd_pfn->dev,
+                               "%s is read-only, unable to init metadata\n",
+                               dev_name(&nd_region->dev));
+               goto err;
+       }
+       memset(pfn_sb, 0, sizeof(*pfn_sb));
+       npfns = (pmem->size - SZ_8K) / SZ_4K;
+       /*
+        * Note, we use 64 here for the standard size of struct page,
+        * debugging options may cause it to be larger in which case the
+        * implementation will limit the pfns advertised through
+        * ->direct_access() to those that are included in the memmap.
+        */
+       if (nd_pfn->mode == PFN_MODE_PMEM)
+               offset = ALIGN(SZ_8K + 64 * npfns, PMD_SIZE);
+       else if (nd_pfn->mode == PFN_MODE_RAM)
+               offset = SZ_8K;
+       else
+               goto err;
+       npfns = (pmem->size - offset) / SZ_4K;
+       pfn_sb->mode = cpu_to_le32(nd_pfn->mode);
+       pfn_sb->dataoff = cpu_to_le64(offset);
+       pfn_sb->npfns = cpu_to_le64(npfns);
+       memcpy(pfn_sb->signature, PFN_SIG, PFN_SIG_LEN);
+       memcpy(pfn_sb->uuid, nd_pfn->uuid, 16);
+       pfn_sb->version_major = cpu_to_le16(1);
+       checksum = nd_sb_checksum((struct nd_gen_sb *) pfn_sb);
+       pfn_sb->checksum = cpu_to_le64(checksum);
+       rc = nvdimm_write_bytes(ndns, SZ_4K, pfn_sb, sizeof(*pfn_sb));
+       if (rc)
+               goto err;
+       return 0;
+  err:
+       nd_pfn->pfn_sb = NULL;
+       kfree(pfn_sb);
+       return -ENXIO;
+ }
+ static int nvdimm_namespace_detach_pfn(struct nd_namespace_common *ndns)
+ {
+       struct nd_pfn *nd_pfn = to_nd_pfn(ndns->claim);
+       struct pmem_device *pmem;
+       /* free pmem disk */
+       pmem = dev_get_drvdata(&nd_pfn->dev);
+       pmem_detach_disk(pmem);
+       /* release nd_pfn resources */
+       kfree(nd_pfn->pfn_sb);
+       nd_pfn->pfn_sb = NULL;
+       return 0;
+ }
+ static int nvdimm_namespace_attach_pfn(struct nd_namespace_common *ndns)
  {
-       memunmap_pmem(pmem->virt_addr);
-       release_mem_region(pmem->phys_addr, pmem->size);
-       kfree(pmem);
+       struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
+       struct nd_pfn *nd_pfn = to_nd_pfn(ndns->claim);
+       struct device *dev = &nd_pfn->dev;
+       struct vmem_altmap *altmap;
+       struct nd_region *nd_region;
+       struct nd_pfn_sb *pfn_sb;
+       struct pmem_device *pmem;
+       phys_addr_t offset;
+       int rc;
+       if (!nd_pfn->uuid || !nd_pfn->ndns)
+               return -ENODEV;
+       nd_region = to_nd_region(dev->parent);
+       rc = nd_pfn_init(nd_pfn);
+       if (rc)
+               return rc;
+       if (PAGE_SIZE != SZ_4K) {
+               dev_err(dev, "only supported on systems with 4K PAGE_SIZE\n");
+               return -ENXIO;
+       }
+       if (nsio->res.start & ND_PFN_MASK) {
+               dev_err(dev, "%s not memory hotplug section aligned\n",
+                               dev_name(&ndns->dev));
+               return -ENXIO;
+       }
+       pfn_sb = nd_pfn->pfn_sb;
+       offset = le64_to_cpu(pfn_sb->dataoff);
+       nd_pfn->mode = le32_to_cpu(nd_pfn->pfn_sb->mode);
+       if (nd_pfn->mode == PFN_MODE_RAM) {
+               if (offset != SZ_8K)
+                       return -EINVAL;
+               nd_pfn->npfns = le64_to_cpu(pfn_sb->npfns);
+               altmap = NULL;
+       } else {
+               rc = -ENXIO;
+               goto err;
+       }
+       /* establish pfn range for lookup, and switch to direct map */
+       pmem = dev_get_drvdata(dev);
+       memunmap_pmem(dev, pmem->virt_addr);
+       pmem->virt_addr = (void __pmem *)devm_memremap_pages(dev, &nsio->res);
+       if (IS_ERR(pmem->virt_addr)) {
+               rc = PTR_ERR(pmem->virt_addr);
+               goto err;
+       }
+       /* attach pmem disk in "pfn-mode" */
+       pmem->data_offset = offset;
+       rc = pmem_attach_disk(dev, ndns, pmem);
+       if (rc)
+               goto err;
+       return rc;
+  err:
+       nvdimm_namespace_detach_pfn(ndns);
+       return rc;
  }
  
  static int nd_pmem_probe(struct device *dev)
        struct nd_namespace_common *ndns;
        struct nd_namespace_io *nsio;
        struct pmem_device *pmem;
-       int rc;
  
        ndns = nvdimm_namespace_common_probe(dev);
        if (IS_ERR(ndns))
        if (IS_ERR(pmem))
                return PTR_ERR(pmem);
  
+       pmem->ndns = ndns;
        dev_set_drvdata(dev, pmem);
        ndns->rw_bytes = pmem_rw_bytes;
        if (is_nd_btt(dev))
-               rc = nvdimm_namespace_attach_btt(ndns);
-       else if (nd_btt_probe(ndns, pmem) == 0) {
+               return nvdimm_namespace_attach_btt(ndns);
+       if (is_nd_pfn(dev))
+               return nvdimm_namespace_attach_pfn(ndns);
+       if (nd_btt_probe(ndns, pmem) == 0) {
                /* we'll come back as btt-pmem */
-               rc = -ENXIO;
-       } else
-               rc = pmem_attach_disk(ndns, pmem);
-       if (rc)
-               pmem_free(pmem);
-       return rc;
+               return -ENXIO;
+       }
+       if (nd_pfn_probe(ndns, pmem) == 0) {
+               /* we'll come back as pfn-pmem */
+               return -ENXIO;
+       }
+       return pmem_attach_disk(dev, ndns, pmem);
  }
  
  static int nd_pmem_remove(struct device *dev)
        struct pmem_device *pmem = dev_get_drvdata(dev);
  
        if (is_nd_btt(dev))
-               nvdimm_namespace_detach_btt(to_nd_btt(dev)->ndns);
+               nvdimm_namespace_detach_btt(pmem->ndns);
+       else if (is_nd_pfn(dev))
+               nvdimm_namespace_detach_pfn(pmem->ndns);
        else
                pmem_detach_disk(pmem);
-       pmem_free(pmem);
  
        return 0;
  }
diff --combined drivers/pci/probe.c
@@@ -326,8 -326,7 +326,7 @@@ static void pci_read_bases(struct pci_d
                struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
                dev->rom_base_reg = rom;
                res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH |
-                               IORESOURCE_READONLY | IORESOURCE_CACHEABLE |
-                               IORESOURCE_SIZEALIGN;
+                               IORESOURCE_READONLY | IORESOURCE_SIZEALIGN;
                __pci_read_base(dev, pci_bar_mem32, res, rom);
        }
  }
@@@ -661,35 -660,6 +660,35 @@@ static void pci_set_bus_speed(struct pc
        }
  }
  
 +static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
 +{
 +      struct irq_domain *d;
 +
 +      /*
 +       * Any firmware interface that can resolve the msi_domain
 +       * should be called from here.
 +       */
 +      d = pci_host_bridge_of_msi_domain(bus);
 +
 +      return d;
 +}
 +
 +static void pci_set_bus_msi_domain(struct pci_bus *bus)
 +{
 +      struct irq_domain *d;
 +
 +      /*
 +       * Either bus is the root, and we must obtain it from the
 +       * firmware, or we inherit it from the bridge device.
 +       */
 +      if (pci_is_root_bus(bus))
 +              d = pci_host_bridge_msi_domain(bus);
 +      else
 +              d = dev_get_msi_domain(&bus->self->dev);
 +
 +      dev_set_msi_domain(&bus->dev, d);
 +}
 +
  static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
                                           struct pci_dev *bridge, int busnr)
  {
        bridge->subordinate = child;
  
  add_dev:
 +      pci_set_bus_msi_domain(child);
        ret = device_register(&child->dev);
        WARN_ON(ret < 0);
  
@@@ -856,9 -825,6 +855,9 @@@ int pci_scan_bridge(struct pci_bus *bus
                        child->bridge_ctl = bctl;
                }
  
 +              /* Read and initialize bridge resources */
 +              pci_read_bridge_bases(child);
 +
                cmax = pci_scan_child_bus(child);
                if (cmax > subordinate)
                        dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n",
  
                if (!is_cardbus) {
                        child->bridge_ctl = bctl;
 +
 +                      /* Read and initialize bridge resources */
 +                      pci_read_bridge_bases(child);
                        max = pci_scan_child_bus(child);
                } else {
                        /*
@@@ -1033,12 -996,7 +1032,12 @@@ void set_pcie_port_type(struct pci_dev 
        else if (type == PCI_EXP_TYPE_UPSTREAM ||
                 type == PCI_EXP_TYPE_DOWNSTREAM) {
                parent = pci_upstream_bridge(pdev);
 -              if (!parent->has_secondary_link)
 +
 +              /*
 +               * Usually there's an upstream device (Root Port or Switch
 +               * Downstream Port), but we can't assume one exists.
 +               */
 +              if (parent && !parent->has_secondary_link)
                        pdev->has_secondary_link = 1;
        }
  }
@@@ -1144,7 -1102,7 +1143,7 @@@ int pci_cfg_space_size(struct pci_dev *
  
  #define LEGACY_IO_RESOURCE    (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
  
 -static void pci_msi_setup_pci_dev(struct pci_dev *dev)
 +void pci_msi_setup_pci_dev(struct pci_dev *dev)
  {
        /*
         * Disable the MSI hardware to avoid screaming interrupts
@@@ -1174,6 -1132,7 +1173,6 @@@ int pci_setup_device(struct pci_dev *de
  {
        u32 class;
        u8 hdr_type;
 -      struct pci_slot *slot;
        int pos = 0;
        struct pci_bus_region region;
        struct resource *res;
        dev->error_state = pci_channel_io_normal;
        set_pcie_port_type(dev);
  
 -      list_for_each_entry(slot, &dev->bus->slots, list)
 -              if (PCI_SLOT(dev->devfn) == slot->number)
 -                      dev->slot = slot;
 -
 +      pci_dev_assign_slot(dev);
        /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
           set this higher, assuming the system even supports it.  */
        dev->dma_mask = 0xffffffff;
        bad:
                dev_err(&dev->dev, "ignoring class %#08x (doesn't match header type %02x)\n",
                        dev->class, dev->hdr_type);
 -              dev->class = PCI_CLASS_NOT_DEFINED;
 +              dev->class = PCI_CLASS_NOT_DEFINED << 8;
        }
  
        /* We found a fine healthy device, go go go... */
        return 0;
  }
  
 +static void pci_configure_mps(struct pci_dev *dev)
 +{
 +      struct pci_dev *bridge = pci_upstream_bridge(dev);
 +      int mps, p_mps, rc;
 +
 +      if (!pci_is_pcie(dev) || !bridge || !pci_is_pcie(bridge))
 +              return;
 +
 +      mps = pcie_get_mps(dev);
 +      p_mps = pcie_get_mps(bridge);
 +
 +      if (mps == p_mps)
 +              return;
 +
 +      if (pcie_bus_config == PCIE_BUS_TUNE_OFF) {
 +              dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
 +                       mps, pci_name(bridge), p_mps);
 +              return;
 +      }
 +
 +      /*
 +       * Fancier MPS configuration is done later by
 +       * pcie_bus_configure_settings()
 +       */
 +      if (pcie_bus_config != PCIE_BUS_DEFAULT)
 +              return;
 +
 +      rc = pcie_set_mps(dev, p_mps);
 +      if (rc) {
 +              dev_warn(&dev->dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
 +                       p_mps);
 +              return;
 +      }
 +
 +      dev_info(&dev->dev, "Max Payload Size set to %d (was %d, max %d)\n",
 +               p_mps, mps, 128 << dev->pcie_mpss);
 +}
 +
  static struct hpp_type0 pci_default_type0 = {
        .revision = 1,
        .cache_line_size = 8,
@@@ -1471,8 -1395,6 +1470,8 @@@ static void pci_configure_device(struc
        struct hotplug_params hpp;
        int ret;
  
 +      pci_configure_mps(dev);
 +
        memset(&hpp, 0, sizeof(hpp));
        ret = pci_get_hp_params(dev, &hpp);
        if (ret)
@@@ -1617,24 -1539,10 +1616,24 @@@ static void pci_init_capabilities(struc
        /* Single Root I/O Virtualization */
        pci_iov_init(dev);
  
 +      /* Address Translation Services */
 +      pci_ats_init(dev);
 +
        /* Enable ACS P2P upstream forwarding */
        pci_enable_acs(dev);
  }
  
 +static void pci_set_msi_domain(struct pci_dev *dev)
 +{
 +      /*
 +       * If no domain has been set through the pcibios_add_device
 +       * callback, inherit the default from the bus device.
 +       */
 +      if (!dev_get_msi_domain(&dev->dev))
 +              dev_set_msi_domain(&dev->dev,
 +                                 dev_get_msi_domain(&dev->bus->dev));
 +}
 +
  void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
  {
        int ret;
        ret = pcibios_add_device(dev);
        WARN_ON(ret < 0);
  
 +      /* Setup MSI irq domain */
 +      pci_set_msi_domain(dev);
 +
        /* Notifier could use PCI capabilities */
        dev->match_driver = false;
        ret = device_add(&dev->dev);
@@@ -1885,6 -1790,22 +1884,6 @@@ static void pcie_write_mrrs(struct pci_
                dev_err(&dev->dev, "MRRS was unable to be configured with a safe value.  If problems are experienced, try running with pci=pcie_bus_safe\n");
  }
  
 -static void pcie_bus_detect_mps(struct pci_dev *dev)
 -{
 -      struct pci_dev *bridge = dev->bus->self;
 -      int mps, p_mps;
 -
 -      if (!bridge)
 -              return;
 -
 -      mps = pcie_get_mps(dev);
 -      p_mps = pcie_get_mps(bridge);
 -
 -      if (mps != p_mps)
 -              dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
 -                       mps, pci_name(bridge), p_mps);
 -}
 -
  static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
  {
        int mps, orig_mps;
        if (!pci_is_pcie(dev))
                return 0;
  
 -      if (pcie_bus_config == PCIE_BUS_TUNE_OFF) {
 -              pcie_bus_detect_mps(dev);
 +      if (pcie_bus_config == PCIE_BUS_TUNE_OFF ||
 +          pcie_bus_config == PCIE_BUS_DEFAULT)
                return 0;
 -      }
  
        mps = 128 << *(u8 *)data;
        orig_mps = pcie_get_mps(dev);
@@@ -2052,7 -1974,6 +2051,7 @@@ struct pci_bus *pci_create_root_bus(str
        b->bridge = get_device(&bridge->dev);
        device_enable_async_suspend(b->bridge);
        pci_set_bus_of_node(b);
 +      pci_set_bus_msi_domain(b);
  
        if (!parent)
                set_dev_node(b->bridge, pcibus_to_node(b));
@@@ -2174,9 -2095,8 +2173,9 @@@ void pci_bus_release_busn_res(struct pc
                        res, ret ? "can not be" : "is");
  }
  
 -struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
 -              struct pci_ops *ops, void *sysdata, struct list_head *resources)
 +struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
 +              struct pci_ops *ops, void *sysdata,
 +              struct list_head *resources, struct msi_controller *msi)
  {
        struct resource_entry *window;
        bool found = false;
        if (!b)
                return NULL;
  
 +      b->msi = msi;
 +
        if (!found) {
                dev_info(&b->dev,
                 "No busn resource found for root bus, will use [bus %02x-ff]\n",
  
        return b;
  }
 +
 +struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
 +              struct pci_ops *ops, void *sysdata, struct list_head *resources)
 +{
 +      return pci_scan_root_bus_msi(parent, bus, ops, sysdata, resources,
 +                                   NULL);
 +}
  EXPORT_SYMBOL(pci_scan_root_bus);
  
  struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
@@@ -29,7 -29,7 +29,7 @@@ static int dcssblk_open(struct block_de
  static void dcssblk_release(struct gendisk *disk, fmode_t mode);
  static void dcssblk_make_request(struct request_queue *q, struct bio *bio);
  static long dcssblk_direct_access(struct block_device *bdev, sector_t secnum,
-                                void **kaddr, unsigned long *pfn, long size);
+                        void __pmem **kaddr, unsigned long *pfn);
  
  static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
  
@@@ -548,10 -548,10 +548,10 @@@ dcssblk_add_store(struct device *dev, s
         */
        num_of_segments = 0;
        for (i = 0; (i < count && (buf[i] != '\0') && (buf[i] != '\n')); i++) {
 -              for (j = i; (buf[j] != ':') &&
 +              for (j = i; j < count &&
 +                      (buf[j] != ':') &&
                        (buf[j] != '\0') &&
 -                      (buf[j] != '\n') &&
 -                      j < count; j++) {
 +                      (buf[j] != '\n'); j++) {
                        local_buf[j-i] = toupper(buf[j]);
                }
                local_buf[j-i] = '\0';
@@@ -723,7 -723,7 +723,7 @@@ dcssblk_remove_store(struct device *dev
        /*
         * parse input
         */
 -      for (i = 0; ((*(buf+i)!='\0') && (*(buf+i)!='\n') && i < count); i++) {
 +      for (i = 0; (i < count && (*(buf+i)!='\0') && (*(buf+i)!='\n')); i++) {
                local_buf[i] = toupper(buf[i]);
        }
        local_buf[i] = '\0';
@@@ -826,8 -826,6 +826,8 @@@ dcssblk_make_request(struct request_que
        unsigned long source_addr;
        unsigned long bytes_done;
  
 +      blk_queue_split(q, &bio, q->bio_split);
 +
        bytes_done = 0;
        dev_info = bio->bi_bdev->bd_disk->private_data;
        if (dev_info == NULL)
                }
                bytes_done += bvec.bv_len;
        }
 -      bio_endio(bio, 0);
 +      bio_endio(bio);
        return;
  fail:
        bio_io_error(bio);
  
  static long
  dcssblk_direct_access (struct block_device *bdev, sector_t secnum,
-                       void **kaddr, unsigned long *pfn, long size)
+                       void __pmem **kaddr, unsigned long *pfn)
  {
        struct dcssblk_dev_info *dev_info;
        unsigned long offset, dev_sz;
+       void *addr;
  
        dev_info = bdev->bd_disk->private_data;
        if (!dev_info)
                return -ENODEV;
        dev_sz = dev_info->end - dev_info->start;
        offset = secnum * 512;
-       *kaddr = (void *) (dev_info->start + offset);
-       *pfn = virt_to_phys(*kaddr) >> PAGE_SHIFT;
+       addr = (void *) (dev_info->start + offset);
+       *pfn = virt_to_phys(addr) >> PAGE_SHIFT;
+       *kaddr = (void __pmem *) addr;
  
        return dev_sz - offset;
  }
@@@ -906,10 -906,10 +908,10 @@@ dcssblk_check_params(void
  
        for (i = 0; (i < DCSSBLK_PARM_LEN) && (dcssblk_segments[i] != '\0');
             i++) {
 -              for (j = i; (dcssblk_segments[j] != ',')  &&
 +              for (j = i; (j < DCSSBLK_PARM_LEN) &&
 +                          (dcssblk_segments[j] != ',')  &&
                            (dcssblk_segments[j] != '\0') &&
 -                          (dcssblk_segments[j] != '(')  &&
 -                          (j < DCSSBLK_PARM_LEN); j++)
 +                          (dcssblk_segments[j] != '('); j++)
                {
                        buf[j-i] = dcssblk_segments[j];
                }
@@@ -100,16 -100,10 +100,11 @@@ static int asd_map_memio(struct asd_ha_
                                   pci_name(asd_ha->pcidev));
                        goto Err;
                }
-               if (io_handle->flags & IORESOURCE_CACHEABLE)
-                       io_handle->addr = ioremap(io_handle->start,
-                                                 io_handle->len);
-               else
-                       io_handle->addr = ioremap_nocache(io_handle->start,
-                                                         io_handle->len);
+               io_handle->addr = ioremap(io_handle->start, io_handle->len);
                if (!io_handle->addr) {
                        asd_printk("couldn't map MBAR%d of %s\n", i==0?0:1,
                                   pci_name(asd_ha->pcidev));
 +                      err = -ENOMEM;
                        goto Err_unreq;
                }
        }
@@@ -259,10 -259,7 +259,7 @@@ static bool arcmsr_remap_pciregion(stru
                addr = (unsigned long)pci_resource_start(pdev, 0);
                range = pci_resource_len(pdev, 0);
                flags = pci_resource_flags(pdev, 0);
-               if (flags & IORESOURCE_CACHEABLE)
-                       mem_base0 = ioremap(addr, range);
-               else
-                       mem_base0 = ioremap_nocache(addr, range);
+               mem_base0 = ioremap(addr, range);
                if (!mem_base0) {
                        pr_notice("arcmsr%d: memory mapping region fail\n",
                                acb->host->host_no);
@@@ -3264,7 -3261,7 +3261,7 @@@ static int arcmsr_iop_confirm(struct Ad
                reg->doneq_index = 0;
                writel(ARCMSR_MESSAGE_SET_POST_WINDOW, reg->drv2iop_doorbell);
                if (!arcmsr_hbaB_wait_msgint_ready(acb)) {
 -                      printk(KERN_NOTICE "arcmsr%d:can not set diver mode\n", \
 +                      printk(KERN_NOTICE "arcmsr%d: cannot set driver mode\n", \
                                acb->host->host_no);
                        return 1;
                }
@@@ -324,13 -324,9 +324,9 @@@ int mvs_ioremap(struct mvs_info *mvi, i
                        goto err_out;
  
                res_flag_ex = pci_resource_flags(pdev, bar_ex);
-               if (res_flag_ex & IORESOURCE_MEM) {
-                       if (res_flag_ex & IORESOURCE_CACHEABLE)
-                               mvi->regs_ex = ioremap(res_start, res_len);
-                       else
-                               mvi->regs_ex = ioremap_nocache(res_start,
-                                               res_len);
-               } else
+               if (res_flag_ex & IORESOURCE_MEM)
+                       mvi->regs_ex = ioremap(res_start, res_len);
+               else
                        mvi->regs_ex = (void *)res_start;
                if (!mvi->regs_ex)
                        goto err_out;
  
        res_start = pci_resource_start(pdev, bar);
        res_len = pci_resource_len(pdev, bar);
 -      if (!res_start || !res_len)
 +      if (!res_start || !res_len) {
 +              iounmap(mvi->regs_ex);
 +              mvi->regs_ex = NULL;
                goto err_out;
 +      }
  
        res_flag = pci_resource_flags(pdev, bar);
-       if (res_flag & IORESOURCE_CACHEABLE)
-               mvi->regs = ioremap(res_start, res_len);
-       else
-               mvi->regs = ioremap_nocache(res_start, res_len);
+       mvi->regs = ioremap(res_start, res_len);
  
        if (!mvi->regs) {
                if (mvi->regs_ex && (res_flag_ex & IORESOURCE_MEM))
@@@ -1,11 -1,12 +1,11 @@@
  /* visorchannel_funcs.c
   *
 - * Copyright (C) 2010 - 2013 UNISYS CORPORATION
 + * Copyright (C) 2010 - 2015 UNISYS CORPORATION
   * All rights reserved.
   *
 - * This program is free software; you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License as published by
 - * the Free Software Foundation; either version 2 of the License, or (at
 - * your option) any later version.
 + * This program is free software; you can redistribute it and/or modify it
 + * under the terms and conditions of the GNU General Public License,
 + * version 2, as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
@@@ -20,6 -21,7 +20,7 @@@
   */
  
  #include <linux/uuid.h>
+ #include <linux/io.h>
  
  #include "version.h"
  #include "visorbus.h"
@@@ -35,7 -37,7 +36,7 @@@ static const uuid_le spar_video_guid = 
  struct visorchannel {
        u64 physaddr;
        ulong nbytes;
-       void __iomem *mapped;
+       void *mapped;
        bool requested;
        struct channel_header chan_hdr;
        uuid_le guid;
@@@ -92,7 -94,7 +93,7 @@@ visorchannel_create_guts(u64 physaddr, 
                }
        }
  
-       channel->mapped = ioremap_cache(physaddr, size);
+       channel->mapped = memremap(physaddr, size, MEMREMAP_WB);
        if (!channel->mapped) {
                release_mem_region(physaddr, size);
                goto cleanup;
        if (uuid_le_cmp(guid, NULL_UUID_LE) == 0)
                guid = channel->chan_hdr.chtype;
  
-       iounmap(channel->mapped);
+       memunmap(channel->mapped);
        if (channel->requested)
                release_mem_region(channel->physaddr, channel->nbytes);
        channel->mapped = NULL;
                }
        }
  
-       channel->mapped = ioremap_cache(channel->physaddr, channel_bytes);
+       channel->mapped = memremap(channel->physaddr, channel_bytes,
+                       MEMREMAP_WB);
        if (!channel->mapped) {
                release_mem_region(channel->physaddr, channel_bytes);
                goto cleanup;
@@@ -166,7 -169,7 +168,7 @@@ visorchannel_destroy(struct visorchanne
        if (!channel)
                return;
        if (channel->mapped) {
-               iounmap(channel->mapped);
+               memunmap(channel->mapped);
                if (channel->requested)
                        release_mem_region(channel->physaddr, channel->nbytes);
        }
@@@ -240,7 -243,7 +242,7 @@@ visorchannel_read(struct visorchannel *
        if (offset + nbytes > channel->nbytes)
                return -EIO;
  
-       memcpy_fromio(local, channel->mapped + offset, nbytes);
+       memcpy(local, channel->mapped + offset, nbytes);
  
        return 0;
  }
@@@ -258,11 -261,10 +260,11 @@@ visorchannel_write(struct visorchannel 
  
        if (offset < chdr_size) {
                copy_size = min(chdr_size - offset, nbytes);
 -              memcpy(&channel->chan_hdr + offset, local, copy_size);
 +              memcpy(((char *)(&channel->chan_hdr)) + offset,
 +                     local, copy_size);
        }
  
-       memcpy_toio(channel->mapped + offset, local, nbytes);
+       memcpy(channel->mapped + offset, local, nbytes);
  
        return 0;
  }
@@@ -416,12 -418,11 +418,12 @@@ boo
  visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
  {
        bool rc;
 +      unsigned long flags;
  
        if (channel->needs_lock) {
 -              spin_lock(&channel->remove_lock);
 +              spin_lock_irqsave(&channel->remove_lock, flags);
                rc = signalremove_inner(channel, queue, msg);
 -              spin_unlock(&channel->remove_lock);
 +              spin_unlock_irqrestore(&channel->remove_lock, flags);
        } else {
                rc = signalremove_inner(channel, queue, msg);
        }
  }
  EXPORT_SYMBOL_GPL(visorchannel_signalremove);
  
 +bool
 +visorchannel_signalempty(struct visorchannel *channel, u32 queue)
 +{
 +      unsigned long flags = 0;
 +      struct signal_queue_header sig_hdr;
 +      bool rc = false;
 +
 +      if (channel->needs_lock)
 +              spin_lock_irqsave(&channel->remove_lock, flags);
 +
 +      if (!sig_read_header(channel, queue, &sig_hdr))
 +              rc = true;
 +      if (sig_hdr.head == sig_hdr.tail)
 +              rc = true;
 +      if (channel->needs_lock)
 +              spin_unlock_irqrestore(&channel->remove_lock, flags);
 +
 +      return rc;
 +}
 +EXPORT_SYMBOL_GPL(visorchannel_signalempty);
 +
  static bool
  signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
  {
@@@ -492,12 -472,11 +494,12 @@@ boo
  visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg)
  {
        bool rc;
 +      unsigned long flags;
  
        if (channel->needs_lock) {
 -              spin_lock(&channel->insert_lock);
 +              spin_lock_irqsave(&channel->insert_lock, flags);
                rc = signalinsert_inner(channel, queue, msg);
 -              spin_unlock(&channel->insert_lock);
 +              spin_unlock_irqrestore(&channel->insert_lock, flags);
        } else {
                rc = signalinsert_inner(channel, queue, msg);
        }
@@@ -1,11 -1,12 +1,11 @@@
  /* visorchipset_main.c
   *
 - * Copyright (C) 2010 - 2013 UNISYS CORPORATION
 + * Copyright (C) 2010 - 2015 UNISYS CORPORATION
   * All rights reserved.
   *
 - * This program is free software; you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License as published by
 - * the Free Software Foundation; either version 2 of the License, or (at
 - * your option) any later version.
 + * This program is free software; you can redistribute it and/or modify it
 + * under the terms and conditions of the GNU General Public License,
 + * version 2, as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
@@@ -118,7 -119,7 +118,7 @@@ static struct visorchannel *controlvm_c
  
  /* Manages the request payload in the controlvm channel */
  struct visor_controlvm_payload_info {
-       u8 __iomem *ptr;        /* pointer to base address of payload pool */
+       u8 *ptr;                /* pointer to base address of payload pool */
        u64 offset;             /* offset from beginning of controlvm
                                 * channel to beginning of payload * pool */
        u32 bytes;              /* number of bytes in payload pool */
@@@ -400,21 -401,22 +400,22 @@@ parser_init_byte_stream(u64 addr, u32 b
                p = __va((unsigned long) (addr));
                memcpy(ctx->data, p, bytes);
        } else {
-               void __iomem *mapping;
+               void *mapping;
  
                if (!request_mem_region(addr, bytes, "visorchipset")) {
                        rc = NULL;
                        goto cleanup;
                }
  
-               mapping = ioremap_cache(addr, bytes);
+               mapping = memremap(addr, bytes, MEMREMAP_WB);
                if (!mapping) {
                        release_mem_region(addr, bytes);
                        rc = NULL;
                        goto cleanup;
                }
-               memcpy_fromio(ctx->data, mapping, bytes);
+               memcpy(ctx->data, mapping, bytes);
                release_mem_region(addr, bytes);
+               memunmap(mapping);
        }
  
        ctx->byte_stream = true;
@@@ -1246,11 -1248,10 +1247,11 @@@ my_device_create(struct controlvm_messa
        POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no,
                         POSTCODE_SEVERITY_INFO);
  
 -      visorchannel = visorchannel_create(cmd->create_device.channel_addr,
 -                                         cmd->create_device.channel_bytes,
 -                                         GFP_KERNEL,
 -                                         cmd->create_device.data_type_uuid);
 +      visorchannel =
 +             visorchannel_create_with_lock(cmd->create_device.channel_addr,
 +                                           cmd->create_device.channel_bytes,
 +                                           GFP_KERNEL,
 +                                           cmd->create_device.data_type_uuid);
  
        if (!visorchannel) {
                POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
@@@ -1327,7 -1328,7 +1328,7 @@@ static in
  initialize_controlvm_payload_info(u64 phys_addr, u64 offset, u32 bytes,
                                  struct visor_controlvm_payload_info *info)
  {
-       u8 __iomem *payload = NULL;
+       u8 *payload = NULL;
        int rc = CONTROLVM_RESP_SUCCESS;
  
        if (!info) {
                rc = -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID;
                goto cleanup;
        }
-       payload = ioremap_cache(phys_addr + offset, bytes);
+       payload = memremap(phys_addr + offset, bytes, MEMREMAP_WB);
        if (!payload) {
                rc = -CONTROLVM_RESP_ERROR_IOREMAP_FAILED;
                goto cleanup;
  cleanup:
        if (rc < 0) {
                if (payload) {
-                       iounmap(payload);
+                       memunmap(payload);
                        payload = NULL;
                }
        }
@@@ -1363,7 -1364,7 +1364,7 @@@ static voi
  destroy_controlvm_payload_info(struct visor_controlvm_payload_info *info)
  {
        if (info->ptr) {
-               iounmap(info->ptr);
+               memunmap(info->ptr);
                info->ptr = NULL;
        }
        memset(info, 0, sizeof(struct visor_controlvm_payload_info));
@@@ -2047,7 -2048,6 +2048,7 @@@ device_create_response(struct visor_dev
                         response);
  
        kfree(dev_info->pending_msg_hdr);
 +      dev_info->pending_msg_hdr = NULL;
  }
  
  static void
@@@ -2382,9 -2382,6 +2383,9 @@@ static struct acpi_driver unisys_acpi_d
                .remove = visorchipset_exit,
                },
  };
 +
 +MODULE_DEVICE_TABLE(acpi, unisys_device_ids);
 +
  static __init uint32_t visorutil_spar_detect(void)
  {
        unsigned int eax, ebx, ecx, edx;
@@@ -1,23 -1,25 +1,23 @@@
  /*
 - *  Driver for 8250/16550-type serial ports
 + *  Universal/legacy driver for 8250/16550-type serial ports
   *
   *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
   *
   *  Copyright (C) 2001 Russell King.
   *
 + *  Supports: ISA-compatible 8250/16550 ports
 + *          PNP 8250/16550 ports
 + *          early_serial_setup() ports
 + *          userspace-configurable "phantom" ports
 + *          "serial8250" platform devices
 + *          serial8250_register_8250_port() ports
 + *
   * 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.
 - *
 - * A note about mapbase / membase
 - *
 - *  mapbase is the physical address of the IO port.
 - *  membase is an 'ioremapped' cookie.
   */
  
 -#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 -#define SUPPORT_SYSRQ
 -#endif
 -
  #include <linux/module.h>
  #include <linux/moduleparam.h>
  #include <linux/ioport.h>
  #include <linux/slab.h>
  #include <linux/uaccess.h>
  #include <linux/pm_runtime.h>
+ #include <linux/io.h>
  #ifdef CONFIG_SPARC
  #include <linux/sunserialcore.h>
  #endif
  
- #include <asm/io.h>
  #include <asm/irq.h>
  
  #include "8250.h"
@@@ -56,10 -58,33 +56,10 @@@ static unsigned int nr_uarts = CONFIG_S
  
  static struct uart_driver serial8250_reg;
  
 -static int serial_index(struct uart_port *port)
 -{
 -      return port->minor - 64;
 -}
 -
  static unsigned int skip_txen_test; /* force skip of txen test at init time */
  
 -/*
 - * Debugging.
 - */
 -#if 0
 -#define DEBUG_AUTOCONF(fmt...)        printk(fmt)
 -#else
 -#define DEBUG_AUTOCONF(fmt...)        do { } while (0)
 -#endif
 -
 -#if 0
 -#define DEBUG_INTR(fmt...)    printk(fmt)
 -#else
 -#define DEBUG_INTR(fmt...)    do { } while (0)
 -#endif
 -
  #define PASS_LIMIT    512
  
 -#define BOTH_EMPTY    (UART_LSR_TEMT | UART_LSR_THRE)
 -
 -
  #include <asm/serial.h>
  /*
   * SERIAL_PORT_DFNS tells us about built-in ports that have no
@@@ -95,268 -120,2695 +95,268 @@@ static struct hlist_head irq_lists[NR_I
  static DEFINE_MUTEX(hash_mutex);      /* Used to walk the hash */
  
  /*
 - * Here we define the default xmit fifo size used for each type of UART.
 + * This is the serial driver's interrupt routine.
 + *
 + * Arjan thinks the old way was overly complex, so it got simplified.
 + * Alan disagrees, saying that need the complexity to handle the weird
 + * nature of ISA shared interrupts.  (This is a special exception.)
 + *
 + * In order to handle ISA shared interrupts properly, we need to check
 + * that all ports have been serviced, and therefore the ISA interrupt
 + * line has been de-asserted.
 + *
 + * This means we need to loop through all ports. checking that they
 + * don't have an interrupt pending.
   */
 -static const struct serial8250_config uart_config[] = {
 -      [PORT_UNKNOWN] = {
 -              .name           = "unknown",
 -              .fifo_size      = 1,
 -              .tx_loadsz      = 1,
 -      },
 -      [PORT_8250] = {
 -              .name           = "8250",
 -              .fifo_size      = 1,
 -              .tx_loadsz      = 1,
 -      },
 -      [PORT_16450] = {
 -              .name           = "16450",
 -              .fifo_size      = 1,
 -              .tx_loadsz      = 1,
 -      },
 -      [PORT_16550] = {
 -              .name           = "16550",
 -              .fifo_size      = 1,
 -              .tx_loadsz      = 1,
 -      },
 -      [PORT_16550A] = {
 -              .name           = "16550A",
 -              .fifo_size      = 16,
 -              .tx_loadsz      = 16,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
 -              .rxtrig_bytes   = {1, 4, 8, 14},
 -              .flags          = UART_CAP_FIFO,
 -      },
 -      [PORT_CIRRUS] = {
 -              .name           = "Cirrus",
 -              .fifo_size      = 1,
 -              .tx_loadsz      = 1,
 -      },
 -      [PORT_16650] = {
 -              .name           = "ST16650",
 -              .fifo_size      = 1,
 -              .tx_loadsz      = 1,
 -              .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
 -      },
 -      [PORT_16650V2] = {
 -              .name           = "ST16650V2",
 -              .fifo_size      = 32,
 -              .tx_loadsz      = 16,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
 -                                UART_FCR_T_TRIG_00,
 -              .rxtrig_bytes   = {8, 16, 24, 28},
 -              .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
 -      },
 -      [PORT_16750] = {
 -              .name           = "TI16750",
 -              .fifo_size      = 64,
 -              .tx_loadsz      = 64,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
 -                                UART_FCR7_64BYTE,
 -              .rxtrig_bytes   = {1, 16, 32, 56},
 -              .flags          = UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE,
 -      },
 -      [PORT_STARTECH] = {
 -              .name           = "Startech",
 -              .fifo_size      = 1,
 -              .tx_loadsz      = 1,
 -      },
 -      [PORT_16C950] = {
 -              .name           = "16C950/954",
 -              .fifo_size      = 128,
 -              .tx_loadsz      = 128,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
 -              /* UART_CAP_EFR breaks billionon CF bluetooth card. */
 -              .flags          = UART_CAP_FIFO | UART_CAP_SLEEP,
 -      },
 -      [PORT_16654] = {
 -              .name           = "ST16654",
 -              .fifo_size      = 64,
 -              .tx_loadsz      = 32,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
 -                                UART_FCR_T_TRIG_10,
 -              .rxtrig_bytes   = {8, 16, 56, 60},
 -              .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
 -      },
 -      [PORT_16850] = {
 -              .name           = "XR16850",
 -              .fifo_size      = 128,
 -              .tx_loadsz      = 128,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
 -              .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
 -      },
 -      [PORT_RSA] = {
 -              .name           = "RSA",
 -              .fifo_size      = 2048,
 -              .tx_loadsz      = 2048,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11,
 -              .flags          = UART_CAP_FIFO,
 -      },
 -      [PORT_NS16550A] = {
 -              .name           = "NS16550A",
 -              .fifo_size      = 16,
 -              .tx_loadsz      = 16,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
 -              .flags          = UART_CAP_FIFO | UART_NATSEMI,
 -      },
 -      [PORT_XSCALE] = {
 -              .name           = "XScale",
 -              .fifo_size      = 32,
 -              .tx_loadsz      = 32,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
 -              .flags          = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE,
 -      },
 -      [PORT_OCTEON] = {
 -              .name           = "OCTEON",
 -              .fifo_size      = 64,
 -              .tx_loadsz      = 64,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
 -              .flags          = UART_CAP_FIFO,
 -      },
 -      [PORT_AR7] = {
 -              .name           = "AR7",
 -              .fifo_size      = 16,
 -              .tx_loadsz      = 16,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
 -              .flags          = UART_CAP_FIFO | UART_CAP_AFE,
 -      },
 -      [PORT_U6_16550A] = {
 -              .name           = "U6_16550A",
 -              .fifo_size      = 64,
 -              .tx_loadsz      = 64,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
 -              .flags          = UART_CAP_FIFO | UART_CAP_AFE,
 -      },
 -      [PORT_TEGRA] = {
 -              .name           = "Tegra",
 -              .fifo_size      = 32,
 -              .tx_loadsz      = 8,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
 -                                UART_FCR_T_TRIG_01,
 -              .rxtrig_bytes   = {1, 4, 8, 14},
 -              .flags          = UART_CAP_FIFO | UART_CAP_RTOIE,
 -      },
 -      [PORT_XR17D15X] = {
 -              .name           = "XR17D15X",
 -              .fifo_size      = 64,
 -              .tx_loadsz      = 64,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
 -              .flags          = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR |
 -                                UART_CAP_SLEEP,
 -      },
 -      [PORT_XR17V35X] = {
 -              .name           = "XR17V35X",
 -              .fifo_size      = 256,
 -              .tx_loadsz      = 256,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11 |
 -                                UART_FCR_T_TRIG_11,
 -              .flags          = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR |
 -                                UART_CAP_SLEEP,
 -      },
 -      [PORT_LPC3220] = {
 -              .name           = "LPC3220",
 -              .fifo_size      = 64,
 -              .tx_loadsz      = 32,
 -              .fcr            = UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO |
 -                                UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00,
 -              .flags          = UART_CAP_FIFO,
 -      },
 -      [PORT_BRCM_TRUMANAGE] = {
 -              .name           = "TruManage",
 -              .fifo_size      = 1,
 -              .tx_loadsz      = 1024,
 -              .flags          = UART_CAP_HFIFO,
 -      },
 -      [PORT_8250_CIR] = {
 -              .name           = "CIR port"
 -      },
 -      [PORT_ALTR_16550_F32] = {
 -              .name           = "Altera 16550 FIFO32",
 -              .fifo_size      = 32,
 -              .tx_loadsz      = 32,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
 -              .flags          = UART_CAP_FIFO | UART_CAP_AFE,
 -      },
 -      [PORT_ALTR_16550_F64] = {
 -              .name           = "Altera 16550 FIFO64",
 -              .fifo_size      = 64,
 -              .tx_loadsz      = 64,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
 -              .flags          = UART_CAP_FIFO | UART_CAP_AFE,
 -      },
 -      [PORT_ALTR_16550_F128] = {
 -              .name           = "Altera 16550 FIFO128",
 -              .fifo_size      = 128,
 -              .tx_loadsz      = 128,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
 -              .flags          = UART_CAP_FIFO | UART_CAP_AFE,
 -      },
 -/* tx_loadsz is set to 63-bytes instead of 64-bytes to implement
 -workaround of errata A-008006 which states that tx_loadsz should  be
 -configured less than Maximum supported fifo bytes */
 -      [PORT_16550A_FSL64] = {
 -              .name           = "16550A_FSL64",
 -              .fifo_size      = 64,
 -              .tx_loadsz      = 63,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
 -                                UART_FCR7_64BYTE,
 -              .flags          = UART_CAP_FIFO,
 -      },
 -};
 -
 -/* Uart divisor latch read */
 -static int default_serial_dl_read(struct uart_8250_port *up)
 -{
 -      return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8;
 -}
 -
 -/* Uart divisor latch write */
 -static void default_serial_dl_write(struct uart_8250_port *up, int value)
 -{
 -      serial_out(up, UART_DLL, value & 0xff);
 -      serial_out(up, UART_DLM, value >> 8 & 0xff);
 -}
 -
 -#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X)
 -
 -/* Au1x00/RT288x UART hardware has a weird register layout */
 -static const s8 au_io_in_map[8] = {
 -       0,     /* UART_RX  */
 -       2,     /* UART_IER */
 -       3,     /* UART_IIR */
 -       5,     /* UART_LCR */
 -       6,     /* UART_MCR */
 -       7,     /* UART_LSR */
 -       8,     /* UART_MSR */
 -      -1,     /* UART_SCR (unmapped) */
 -};
 -
 -static const s8 au_io_out_map[8] = {
 -       1,     /* UART_TX  */
 -       2,     /* UART_IER */
 -       4,     /* UART_FCR */
 -       5,     /* UART_LCR */
 -       6,     /* UART_MCR */
 -      -1,     /* UART_LSR (unmapped) */
 -      -1,     /* UART_MSR (unmapped) */
 -      -1,     /* UART_SCR (unmapped) */
 -};
 -
 -static unsigned int au_serial_in(struct uart_port *p, int offset)
 -{
 -      if (offset >= ARRAY_SIZE(au_io_in_map))
 -              return UINT_MAX;
 -      offset = au_io_in_map[offset];
 -      if (offset < 0)
 -              return UINT_MAX;
 -      return __raw_readl(p->membase + (offset << p->regshift));
 -}
 -
 -static void au_serial_out(struct uart_port *p, int offset, int value)
 -{
 -      if (offset >= ARRAY_SIZE(au_io_out_map))
 -              return;
 -      offset = au_io_out_map[offset];
 -      if (offset < 0)
 -              return;
 -      __raw_writel(value, p->membase + (offset << p->regshift));
 -}
 -
 -/* Au1x00 haven't got a standard divisor latch */
 -static int au_serial_dl_read(struct uart_8250_port *up)
 -{
 -      return __raw_readl(up->port.membase + 0x28);
 -}
 -
 -static void au_serial_dl_write(struct uart_8250_port *up, int value)
 -{
 -      __raw_writel(value, up->port.membase + 0x28);
 -}
 -
 -#endif
 -
 -static unsigned int hub6_serial_in(struct uart_port *p, int offset)
 -{
 -      offset = offset << p->regshift;
 -      outb(p->hub6 - 1 + offset, p->iobase);
 -      return inb(p->iobase + 1);
 -}
 -
 -static void hub6_serial_out(struct uart_port *p, int offset, int value)
 -{
 -      offset = offset << p->regshift;
 -      outb(p->hub6 - 1 + offset, p->iobase);
 -      outb(value, p->iobase + 1);
 -}
 -
 -static unsigned int mem_serial_in(struct uart_port *p, int offset)
 -{
 -      offset = offset << p->regshift;
 -      return readb(p->membase + offset);
 -}
 -
 -static void mem_serial_out(struct uart_port *p, int offset, int value)
 -{
 -      offset = offset << p->regshift;
 -      writeb(value, p->membase + offset);
 -}
 -
 -static void mem32_serial_out(struct uart_port *p, int offset, int value)
 -{
 -      offset = offset << p->regshift;
 -      writel(value, p->membase + offset);
 -}
 -
 -static unsigned int mem32_serial_in(struct uart_port *p, int offset)
 -{
 -      offset = offset << p->regshift;
 -      return readl(p->membase + offset);
 -}
 -
 -static void mem32be_serial_out(struct uart_port *p, int offset, int value)
 -{
 -      offset = offset << p->regshift;
 -      iowrite32be(value, p->membase + offset);
 -}
 -
 -static unsigned int mem32be_serial_in(struct uart_port *p, int offset)
 -{
 -      offset = offset << p->regshift;
 -      return ioread32be(p->membase + offset);
 -}
 -
 -static unsigned int io_serial_in(struct uart_port *p, int offset)
 -{
 -      offset = offset << p->regshift;
 -      return inb(p->iobase + offset);
 -}
 -
 -static void io_serial_out(struct uart_port *p, int offset, int value)
 +static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
  {
 -      offset = offset << p->regshift;
 -      outb(value, p->iobase + offset);
 -}
 +      struct irq_info *i = dev_id;
 +      struct list_head *l, *end = NULL;
 +      int pass_counter = 0, handled = 0;
  
 -static int serial8250_default_handle_irq(struct uart_port *port);
 -static int exar_handle_irq(struct uart_port *port);
 +      DEBUG_INTR("serial8250_interrupt(%d)...", irq);
  
 -static void set_io_from_upio(struct uart_port *p)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(p);
 +      spin_lock(&i->lock);
  
 -      up->dl_read = default_serial_dl_read;
 -      up->dl_write = default_serial_dl_write;
 +      l = i->head;
 +      do {
 +              struct uart_8250_port *up;
 +              struct uart_port *port;
  
 -      switch (p->iotype) {
 -      case UPIO_HUB6:
 -              p->serial_in = hub6_serial_in;
 -              p->serial_out = hub6_serial_out;
 -              break;
 +              up = list_entry(l, struct uart_8250_port, list);
 +              port = &up->port;
  
 -      case UPIO_MEM:
 -              p->serial_in = mem_serial_in;
 -              p->serial_out = mem_serial_out;
 -              break;
 +              if (port->handle_irq(port)) {
 +                      handled = 1;
 +                      end = NULL;
 +              } else if (end == NULL)
 +                      end = l;
  
 -      case UPIO_MEM32:
 -              p->serial_in = mem32_serial_in;
 -              p->serial_out = mem32_serial_out;
 -              break;
 +              l = l->next;
  
 -      case UPIO_MEM32BE:
 -              p->serial_in = mem32be_serial_in;
 -              p->serial_out = mem32be_serial_out;
 -              break;
 +              if (l == i->head && pass_counter++ > PASS_LIMIT) {
 +                      /* If we hit this, we're dead. */
 +                      printk_ratelimited(KERN_ERR
 +                              "serial8250: too much work for irq%d\n", irq);
 +                      break;
 +              }
 +      } while (l != end);
  
 -#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X)
 -      case UPIO_AU:
 -              p->serial_in = au_serial_in;
 -              p->serial_out = au_serial_out;
 -              up->dl_read = au_serial_dl_read;
 -              up->dl_write = au_serial_dl_write;
 -              break;
 -#endif
 +      spin_unlock(&i->lock);
  
 -      default:
 -              p->serial_in = io_serial_in;
 -              p->serial_out = io_serial_out;
 -              break;
 -      }
 -      /* Remember loaded iotype */
 -      up->cur_iotype = p->iotype;
 -      p->handle_irq = serial8250_default_handle_irq;
 -}
 +      DEBUG_INTR("end.\n");
  
 -static void
 -serial_port_out_sync(struct uart_port *p, int offset, int value)
 -{
 -      switch (p->iotype) {
 -      case UPIO_MEM:
 -      case UPIO_MEM32:
 -      case UPIO_MEM32BE:
 -      case UPIO_AU:
 -              p->serial_out(p, offset, value);
 -              p->serial_in(p, UART_LCR);      /* safe, no side-effects */
 -              break;
 -      default:
 -              p->serial_out(p, offset, value);
 -      }
 +      return IRQ_RETVAL(handled);
  }
  
  /*
 - * For the 16C950
 + * To support ISA shared interrupts, we need to have one interrupt
 + * handler that ensures that the IRQ line has been deasserted
 + * before returning.  Failing to do this will result in the IRQ
 + * line being stuck active, and, since ISA irqs are edge triggered,
 + * no more IRQs will be seen.
   */
 -static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
 -{
 -      serial_out(up, UART_SCR, offset);
 -      serial_out(up, UART_ICR, value);
 -}
 -
 -static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
 +static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
  {
 -      unsigned int value;
 -
 -      serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
 -      serial_out(up, UART_SCR, offset);
 -      value = serial_in(up, UART_ICR);
 -      serial_icr_write(up, UART_ACR, up->acr);
 -
 -      return value;
 -}
 +      spin_lock_irq(&i->lock);
  
 -/*
 - * FIFO support.
 - */
 -static void serial8250_clear_fifos(struct uart_8250_port *p)
 -{
 -      if (p->capabilities & UART_CAP_FIFO) {
 -              serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO);
 -              serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO |
 -                             UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
 -              serial_out(p, UART_FCR, 0);
 +      if (!list_empty(i->head)) {
 +              if (i->head == &up->list)
 +                      i->head = i->head->next;
 +              list_del(&up->list);
 +      } else {
 +              BUG_ON(i->head != &up->list);
 +              i->head = NULL;
 +      }
 +      spin_unlock_irq(&i->lock);
 +      /* List empty so throw away the hash node */
 +      if (i->head == NULL) {
 +              hlist_del(&i->node);
 +              kfree(i);
        }
  }
  
 -void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p)
 +static int serial_link_irq_chain(struct uart_8250_port *up)
  {
 -      serial8250_clear_fifos(p);
 -      serial_out(p, UART_FCR, p->fcr);
 -}
 -EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos);
 +      struct hlist_head *h;
 +      struct hlist_node *n;
 +      struct irq_info *i;
 +      int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
  
 -void serial8250_rpm_get(struct uart_8250_port *p)
 -{
 -      if (!(p->capabilities & UART_CAP_RPM))
 -              return;
 -      pm_runtime_get_sync(p->port.dev);
 -}
 -EXPORT_SYMBOL_GPL(serial8250_rpm_get);
 +      mutex_lock(&hash_mutex);
  
 -void serial8250_rpm_put(struct uart_8250_port *p)
 -{
 -      if (!(p->capabilities & UART_CAP_RPM))
 -              return;
 -      pm_runtime_mark_last_busy(p->port.dev);
 -      pm_runtime_put_autosuspend(p->port.dev);
 -}
 -EXPORT_SYMBOL_GPL(serial8250_rpm_put);
 +      h = &irq_lists[up->port.irq % NR_IRQ_HASH];
  
 -/*
 - * These two wrappers ensure that enable_runtime_pm_tx() can be called more than
 - * once and disable_runtime_pm_tx() will still disable RPM because the fifo is
 - * empty and the HW can idle again.
 - */
 -static void serial8250_rpm_get_tx(struct uart_8250_port *p)
 -{
 -      unsigned char rpm_active;
 +      hlist_for_each(n, h) {
 +              i = hlist_entry(n, struct irq_info, node);
 +              if (i->irq == up->port.irq)
 +                      break;
 +      }
  
 -      if (!(p->capabilities & UART_CAP_RPM))
 -              return;
 +      if (n == NULL) {
 +              i = kzalloc(sizeof(struct irq_info), GFP_KERNEL);
 +              if (i == NULL) {
 +                      mutex_unlock(&hash_mutex);
 +                      return -ENOMEM;
 +              }
 +              spin_lock_init(&i->lock);
 +              i->irq = up->port.irq;
 +              hlist_add_head(&i->node, h);
 +      }
 +      mutex_unlock(&hash_mutex);
  
 -      rpm_active = xchg(&p->rpm_tx_active, 1);
 -      if (rpm_active)
 -              return;
 -      pm_runtime_get_sync(p->port.dev);
 -}
 +      spin_lock_irq(&i->lock);
  
 -static void serial8250_rpm_put_tx(struct uart_8250_port *p)
 -{
 -      unsigned char rpm_active;
 +      if (i->head) {
 +              list_add(&up->list, i->head);
 +              spin_unlock_irq(&i->lock);
  
 -      if (!(p->capabilities & UART_CAP_RPM))
 -              return;
 +              ret = 0;
 +      } else {
 +              INIT_LIST_HEAD(&up->list);
 +              i->head = &up->list;
 +              spin_unlock_irq(&i->lock);
 +              irq_flags |= up->port.irqflags;
 +              ret = request_irq(up->port.irq, serial8250_interrupt,
 +                                irq_flags, "serial", i);
 +              if (ret < 0)
 +                      serial_do_unlink(i, up);
 +      }
  
 -      rpm_active = xchg(&p->rpm_tx_active, 0);
 -      if (!rpm_active)
 -              return;
 -      pm_runtime_mark_last_busy(p->port.dev);
 -      pm_runtime_put_autosuspend(p->port.dev);
 +      return ret;
  }
  
 -/*
 - * IER sleep support.  UARTs which have EFRs need the "extended
 - * capability" bit enabled.  Note that on XR16C850s, we need to
 - * reset LCR to write to IER.
 - */
 -static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
 +static void serial_unlink_irq_chain(struct uart_8250_port *up)
  {
 -      unsigned char lcr = 0, efr = 0;
        /*
 -       * Exar UARTs have a SLEEP register that enables or disables
 -       * each UART to enter sleep mode separately.  On the XR17V35x the
 -       * register is accessible to each UART at the UART_EXAR_SLEEP
 -       * offset but the UART channel may only write to the corresponding
 -       * bit.
 +       * yes, some broken gcc emit "warning: 'i' may be used uninitialized"
 +       * but no, we are not going to take a patch that assigns NULL below.
         */
 -      serial8250_rpm_get(p);
 -      if ((p->port.type == PORT_XR17V35X) ||
 -         (p->port.type == PORT_XR17D15X)) {
 -              serial_out(p, UART_EXAR_SLEEP, sleep ? 0xff : 0);
 -              goto out;
 -      }
 -
 -      if (p->capabilities & UART_CAP_SLEEP) {
 -              if (p->capabilities & UART_CAP_EFR) {
 -                      lcr = serial_in(p, UART_LCR);
 -                      efr = serial_in(p, UART_EFR);
 -                      serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B);
 -                      serial_out(p, UART_EFR, UART_EFR_ECB);
 -                      serial_out(p, UART_LCR, 0);
 -              }
 -              serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
 -              if (p->capabilities & UART_CAP_EFR) {
 -                      serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B);
 -                      serial_out(p, UART_EFR, efr);
 -                      serial_out(p, UART_LCR, lcr);
 -              }
 -      }
 -out:
 -      serial8250_rpm_put(p);
 -}
 +      struct irq_info *i;
 +      struct hlist_node *n;
 +      struct hlist_head *h;
  
 -#ifdef CONFIG_SERIAL_8250_RSA
 -/*
 - * Attempts to turn on the RSA FIFO.  Returns zero on failure.
 - * We set the port uart clock rate if we succeed.
 - */
 -static int __enable_rsa(struct uart_8250_port *up)
 -{
 -      unsigned char mode;
 -      int result;
 +      mutex_lock(&hash_mutex);
  
 -      mode = serial_in(up, UART_RSA_MSR);
 -      result = mode & UART_RSA_MSR_FIFO;
 +      h = &irq_lists[up->port.irq % NR_IRQ_HASH];
  
 -      if (!result) {
 -              serial_out(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
 -              mode = serial_in(up, UART_RSA_MSR);
 -              result = mode & UART_RSA_MSR_FIFO;
 +      hlist_for_each(n, h) {
 +              i = hlist_entry(n, struct irq_info, node);
 +              if (i->irq == up->port.irq)
 +                      break;
        }
  
 -      if (result)
 -              up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
 +      BUG_ON(n == NULL);
 +      BUG_ON(i->head == NULL);
  
 -      return result;
 -}
 +      if (list_empty(i->head))
 +              free_irq(up->port.irq, i);
  
 -static void enable_rsa(struct uart_8250_port *up)
 -{
 -      if (up->port.type == PORT_RSA) {
 -              if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
 -                      spin_lock_irq(&up->port.lock);
 -                      __enable_rsa(up);
 -                      spin_unlock_irq(&up->port.lock);
 -              }
 -              if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
 -                      serial_out(up, UART_RSA_FRR, 0);
 -      }
 +      serial_do_unlink(i, up);
 +      mutex_unlock(&hash_mutex);
  }
  
  /*
 - * Attempts to turn off the RSA FIFO.  Returns zero on failure.
 - * It is unknown why interrupts were disabled in here.  However,
 - * the caller is expected to preserve this behaviour by grabbing
 - * the spinlock before calling this function.
 + * This function is used to handle ports that do not have an
 + * interrupt.  This doesn't work very well for 16450's, but gives
 + * barely passable results for a 16550A.  (Although at the expense
 + * of much CPU overhead).
   */
 -static void disable_rsa(struct uart_8250_port *up)
 +static void serial8250_timeout(unsigned long data)
  {
 -      unsigned char mode;
 -      int result;
 -
 -      if (up->port.type == PORT_RSA &&
 -          up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
 -              spin_lock_irq(&up->port.lock);
 +      struct uart_8250_port *up = (struct uart_8250_port *)data;
  
 -              mode = serial_in(up, UART_RSA_MSR);
 -              result = !(mode & UART_RSA_MSR_FIFO);
 +      up->port.handle_irq(&up->port);
 +      mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port));
 +}
  
 -              if (!result) {
 -                      serial_out(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
 -                      mode = serial_in(up, UART_RSA_MSR);
 -                      result = !(mode & UART_RSA_MSR_FIFO);
 -              }
 -
 -              if (result)
 -                      up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
 -              spin_unlock_irq(&up->port.lock);
 -      }
 -}
 -#endif /* CONFIG_SERIAL_8250_RSA */
 -
 -/*
 - * This is a quickie test to see how big the FIFO is.
 - * It doesn't work at all the time, more's the pity.
 - */
 -static int size_fifo(struct uart_8250_port *up)
 -{
 -      unsigned char old_fcr, old_mcr, old_lcr;
 -      unsigned short old_dl;
 -      int count;
 -
 -      old_lcr = serial_in(up, UART_LCR);
 -      serial_out(up, UART_LCR, 0);
 -      old_fcr = serial_in(up, UART_FCR);
 -      old_mcr = serial_in(up, UART_MCR);
 -      serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO |
 -                  UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
 -      serial_out(up, UART_MCR, UART_MCR_LOOP);
 -      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
 -      old_dl = serial_dl_read(up);
 -      serial_dl_write(up, 0x0001);
 -      serial_out(up, UART_LCR, 0x03);
 -      for (count = 0; count < 256; count++)
 -              serial_out(up, UART_TX, count);
 -      mdelay(20);/* FIXME - schedule_timeout */
 -      for (count = 0; (serial_in(up, UART_LSR) & UART_LSR_DR) &&
 -           (count < 256); count++)
 -              serial_in(up, UART_RX);
 -      serial_out(up, UART_FCR, old_fcr);
 -      serial_out(up, UART_MCR, old_mcr);
 -      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
 -      serial_dl_write(up, old_dl);
 -      serial_out(up, UART_LCR, old_lcr);
 -
 -      return count;
 -}
 -
 -/*
 - * Read UART ID using the divisor method - set DLL and DLM to zero
 - * and the revision will be in DLL and device type in DLM.  We
 - * preserve the device state across this.
 - */
 -static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
 -{
 -      unsigned char old_dll, old_dlm, old_lcr;
 -      unsigned int id;
 -
 -      old_lcr = serial_in(p, UART_LCR);
 -      serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A);
 -
 -      old_dll = serial_in(p, UART_DLL);
 -      old_dlm = serial_in(p, UART_DLM);
 -
 -      serial_out(p, UART_DLL, 0);
 -      serial_out(p, UART_DLM, 0);
 -
 -      id = serial_in(p, UART_DLL) | serial_in(p, UART_DLM) << 8;
 -
 -      serial_out(p, UART_DLL, old_dll);
 -      serial_out(p, UART_DLM, old_dlm);
 -      serial_out(p, UART_LCR, old_lcr);
 -
 -      return id;
 -}
 -
 -/*
 - * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
 - * When this function is called we know it is at least a StarTech
 - * 16650 V2, but it might be one of several StarTech UARTs, or one of
 - * its clones.  (We treat the broken original StarTech 16650 V1 as a
 - * 16550, and why not?  Startech doesn't seem to even acknowledge its
 - * existence.)
 - *
 - * What evil have men's minds wrought...
 - */
 -static void autoconfig_has_efr(struct uart_8250_port *up)
 -{
 -      unsigned int id1, id2, id3, rev;
 -
 -      /*
 -       * Everything with an EFR has SLEEP
 -       */
 -      up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
 -
 -      /*
 -       * First we check to see if it's an Oxford Semiconductor UART.
 -       *
 -       * If we have to do this here because some non-National
 -       * Semiconductor clone chips lock up if you try writing to the
 -       * LSR register (which serial_icr_read does)
 -       */
 -
 -      /*
 -       * Check for Oxford Semiconductor 16C950.
 -       *
 -       * EFR [4] must be set else this test fails.
 -       *
 -       * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca)
 -       * claims that it's needed for 952 dual UART's (which are not
 -       * recommended for new designs).
 -       */
 -      up->acr = 0;
 -      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 -      serial_out(up, UART_EFR, UART_EFR_ECB);
 -      serial_out(up, UART_LCR, 0x00);
 -      id1 = serial_icr_read(up, UART_ID1);
 -      id2 = serial_icr_read(up, UART_ID2);
 -      id3 = serial_icr_read(up, UART_ID3);
 -      rev = serial_icr_read(up, UART_REV);
 -
 -      DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev);
 -
 -      if (id1 == 0x16 && id2 == 0xC9 &&
 -          (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
 -              up->port.type = PORT_16C950;
 -
 -              /*
 -               * Enable work around for the Oxford Semiconductor 952 rev B
 -               * chip which causes it to seriously miscalculate baud rates
 -               * when DLL is 0.
 -               */
 -              if (id3 == 0x52 && rev == 0x01)
 -                      up->bugs |= UART_BUG_QUOT;
 -              return;
 -      }
 -
 -      /*
 -       * We check for a XR16C850 by setting DLL and DLM to 0, and then
 -       * reading back DLL and DLM.  The chip type depends on the DLM
 -       * value read back:
 -       *  0x10 - XR16C850 and the DLL contains the chip revision.
 -       *  0x12 - XR16C2850.
 -       *  0x14 - XR16C854.
 -       */
 -      id1 = autoconfig_read_divisor_id(up);
 -      DEBUG_AUTOCONF("850id=%04x ", id1);
 -
 -      id2 = id1 >> 8;
 -      if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) {
 -              up->port.type = PORT_16850;
 -              return;
 -      }
 -
 -      /*
 -       * It wasn't an XR16C850.
 -       *
 -       * We distinguish between the '654 and the '650 by counting
 -       * how many bytes are in the FIFO.  I'm using this for now,
 -       * since that's the technique that was sent to me in the
 -       * serial driver update, but I'm not convinced this works.
 -       * I've had problems doing this in the past.  -TYT
 -       */
 -      if (size_fifo(up) == 64)
 -              up->port.type = PORT_16654;
 -      else
 -              up->port.type = PORT_16650V2;
 -}
 -
 -/*
 - * We detected a chip without a FIFO.  Only two fall into
 - * this category - the original 8250 and the 16450.  The
 - * 16450 has a scratch register (accessible with LCR=0)
 - */
 -static void autoconfig_8250(struct uart_8250_port *up)
 -{
 -      unsigned char scratch, status1, status2;
 -
 -      up->port.type = PORT_8250;
 -
 -      scratch = serial_in(up, UART_SCR);
 -      serial_out(up, UART_SCR, 0xa5);
 -      status1 = serial_in(up, UART_SCR);
 -      serial_out(up, UART_SCR, 0x5a);
 -      status2 = serial_in(up, UART_SCR);
 -      serial_out(up, UART_SCR, scratch);
 -
 -      if (status1 == 0xa5 && status2 == 0x5a)
 -              up->port.type = PORT_16450;
 -}
 -
 -static int broken_efr(struct uart_8250_port *up)
 -{
 -      /*
 -       * Exar ST16C2550 "A2" devices incorrectly detect as
 -       * having an EFR, and report an ID of 0x0201.  See
 -       * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html
 -       */
 -      if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16)
 -              return 1;
 -
 -      return 0;
 -}
 -
 -/*
 - * We know that the chip has FIFOs.  Does it have an EFR?  The
 - * EFR is located in the same register position as the IIR and
 - * we know the top two bits of the IIR are currently set.  The
 - * EFR should contain zero.  Try to read the EFR.
 - */
 -static void autoconfig_16550a(struct uart_8250_port *up)
 -{
 -      unsigned char status1, status2;
 -      unsigned int iersave;
 -
 -      up->port.type = PORT_16550A;
 -      up->capabilities |= UART_CAP_FIFO;
 -
 -      /*
 -       * XR17V35x UARTs have an extra divisor register, DLD
 -       * that gets enabled with when DLAB is set which will
 -       * cause the device to incorrectly match and assign
 -       * port type to PORT_16650.  The EFR for this UART is
 -       * found at offset 0x09. Instead check the Deice ID (DVID)
 -       * register for a 2, 4 or 8 port UART.
 -       */
 -      if (up->port.flags & UPF_EXAR_EFR) {
 -              status1 = serial_in(up, UART_EXAR_DVID);
 -              if (status1 == 0x82 || status1 == 0x84 || status1 == 0x88) {
 -                      DEBUG_AUTOCONF("Exar XR17V35x ");
 -                      up->port.type = PORT_XR17V35X;
 -                      up->capabilities |= UART_CAP_AFE | UART_CAP_EFR |
 -                                              UART_CAP_SLEEP;
 -
 -                      return;
 -              }
 -
 -      }
 -
 -      /*
 -       * Check for presence of the EFR when DLAB is set.
 -       * Only ST16C650V1 UARTs pass this test.
 -       */
 -      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
 -      if (serial_in(up, UART_EFR) == 0) {
 -              serial_out(up, UART_EFR, 0xA8);
 -              if (serial_in(up, UART_EFR) != 0) {
 -                      DEBUG_AUTOCONF("EFRv1 ");
 -                      up->port.type = PORT_16650;
 -                      up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
 -              } else {
 -                      serial_out(up, UART_LCR, 0);
 -                      serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO |
 -                                 UART_FCR7_64BYTE);
 -                      status1 = serial_in(up, UART_IIR) >> 5;
 -                      serial_out(up, UART_FCR, 0);
 -                      serial_out(up, UART_LCR, 0);
 -
 -                      if (status1 == 7)
 -                              up->port.type = PORT_16550A_FSL64;
 -                      else
 -                              DEBUG_AUTOCONF("Motorola 8xxx DUART ");
 -              }
 -              serial_out(up, UART_EFR, 0);
 -              return;
 -      }
 -
 -      /*
 -       * Maybe it requires 0xbf to be written to the LCR.
 -       * (other ST16C650V2 UARTs, TI16C752A, etc)
 -       */
 -      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 -      if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) {
 -              DEBUG_AUTOCONF("EFRv2 ");
 -              autoconfig_has_efr(up);
 -              return;
 -      }
 -
 -      /*
 -       * Check for a National Semiconductor SuperIO chip.
 -       * Attempt to switch to bank 2, read the value of the LOOP bit
 -       * from EXCR1. Switch back to bank 0, change it in MCR. Then
 -       * switch back to bank 2, read it from EXCR1 again and check
 -       * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2
 -       */
 -      serial_out(up, UART_LCR, 0);
 -      status1 = serial_in(up, UART_MCR);
 -      serial_out(up, UART_LCR, 0xE0);
 -      status2 = serial_in(up, 0x02); /* EXCR1 */
 -
 -      if (!((status2 ^ status1) & UART_MCR_LOOP)) {
 -              serial_out(up, UART_LCR, 0);
 -              serial_out(up, UART_MCR, status1 ^ UART_MCR_LOOP);
 -              serial_out(up, UART_LCR, 0xE0);
 -              status2 = serial_in(up, 0x02); /* EXCR1 */
 -              serial_out(up, UART_LCR, 0);
 -              serial_out(up, UART_MCR, status1);
 -
 -              if ((status2 ^ status1) & UART_MCR_LOOP) {
 -                      unsigned short quot;
 -
 -                      serial_out(up, UART_LCR, 0xE0);
 -
 -                      quot = serial_dl_read(up);
 -                      quot <<= 3;
 -
 -                      if (ns16550a_goto_highspeed(up))
 -                              serial_dl_write(up, quot);
 -
 -                      serial_out(up, UART_LCR, 0);
 -
 -                      up->port.uartclk = 921600*16;
 -                      up->port.type = PORT_NS16550A;
 -                      up->capabilities |= UART_NATSEMI;
 -                      return;
 -              }
 -      }
 -
 -      /*
 -       * No EFR.  Try to detect a TI16750, which only sets bit 5 of
 -       * the IIR when 64 byte FIFO mode is enabled when DLAB is set.
 -       * Try setting it with and without DLAB set.  Cheap clones
 -       * set bit 5 without DLAB set.
 -       */
 -      serial_out(up, UART_LCR, 0);
 -      serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
 -      status1 = serial_in(up, UART_IIR) >> 5;
 -      serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
 -      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
 -      serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
 -      status2 = serial_in(up, UART_IIR) >> 5;
 -      serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
 -      serial_out(up, UART_LCR, 0);
 -
 -      DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
 -
 -      if (status1 == 6 && status2 == 7) {
 -              up->port.type = PORT_16750;
 -              up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP;
 -              return;
 -      }
 -
 -      /*
 -       * Try writing and reading the UART_IER_UUE bit (b6).
 -       * If it works, this is probably one of the Xscale platform's
 -       * internal UARTs.
 -       * We're going to explicitly set the UUE bit to 0 before
 -       * trying to write and read a 1 just to make sure it's not
 -       * already a 1 and maybe locked there before we even start start.
 -       */
 -      iersave = serial_in(up, UART_IER);
 -      serial_out(up, UART_IER, iersave & ~UART_IER_UUE);
 -      if (!(serial_in(up, UART_IER) & UART_IER_UUE)) {
 -              /*
 -               * OK it's in a known zero state, try writing and reading
 -               * without disturbing the current state of the other bits.
 -               */
 -              serial_out(up, UART_IER, iersave | UART_IER_UUE);
 -              if (serial_in(up, UART_IER) & UART_IER_UUE) {
 -                      /*
 -                       * It's an Xscale.
 -                       * We'll leave the UART_IER_UUE bit set to 1 (enabled).
 -                       */
 -                      DEBUG_AUTOCONF("Xscale ");
 -                      up->port.type = PORT_XSCALE;
 -                      up->capabilities |= UART_CAP_UUE | UART_CAP_RTOIE;
 -                      return;
 -              }
 -      } else {
 -              /*
 -               * If we got here we couldn't force the IER_UUE bit to 0.
 -               * Log it and continue.
 -               */
 -              DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 ");
 -      }
 -      serial_out(up, UART_IER, iersave);
 -
 -      /*
 -       * Exar uarts have EFR in a weird location
 -       */
 -      if (up->port.flags & UPF_EXAR_EFR) {
 -              DEBUG_AUTOCONF("Exar XR17D15x ");
 -              up->port.type = PORT_XR17D15X;
 -              up->capabilities |= UART_CAP_AFE | UART_CAP_EFR |
 -                                  UART_CAP_SLEEP;
 -
 -              return;
 -      }
 -
 -      /*
 -       * We distinguish between 16550A and U6 16550A by counting
 -       * how many bytes are in the FIFO.
 -       */
 -      if (up->port.type == PORT_16550A && size_fifo(up) == 64) {
 -              up->port.type = PORT_U6_16550A;
 -              up->capabilities |= UART_CAP_AFE;
 -      }
 -}
 -
 -/*
 - * This routine is called by rs_init() to initialize a specific serial
 - * port.  It determines what type of UART chip this serial port is
 - * using: 8250, 16450, 16550, 16550A.  The important question is
 - * whether or not this UART is a 16550A or not, since this will
 - * determine whether or not we can use its FIFO features or not.
 - */
 -static void autoconfig(struct uart_8250_port *up)
 -{
 -      unsigned char status1, scratch, scratch2, scratch3;
 -      unsigned char save_lcr, save_mcr;
 -      struct uart_port *port = &up->port;
 -      unsigned long flags;
 -      unsigned int old_capabilities;
 -
 -      if (!port->iobase && !port->mapbase && !port->membase)
 -              return;
 -
 -      DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ",
 -                     serial_index(port), port->iobase, port->membase);
 -
 -      /*
 -       * We really do need global IRQs disabled here - we're going to
 -       * be frobbing the chips IRQ enable register to see if it exists.
 -       */
 -      spin_lock_irqsave(&port->lock, flags);
 -
 -      up->capabilities = 0;
 -      up->bugs = 0;
 -
 -      if (!(port->flags & UPF_BUGGY_UART)) {
 -              /*
 -               * Do a simple existence test first; if we fail this,
 -               * there's no point trying anything else.
 -               *
 -               * 0x80 is used as a nonsense port to prevent against
 -               * false positives due to ISA bus float.  The
 -               * assumption is that 0x80 is a non-existent port;
 -               * which should be safe since include/asm/io.h also
 -               * makes this assumption.
 -               *
 -               * Note: this is safe as long as MCR bit 4 is clear
 -               * and the device is in "PC" mode.
 -               */
 -              scratch = serial_in(up, UART_IER);
 -              serial_out(up, UART_IER, 0);
 -#ifdef __i386__
 -              outb(0xff, 0x080);
 -#endif
 -              /*
 -               * Mask out IER[7:4] bits for test as some UARTs (e.g. TL
 -               * 16C754B) allow only to modify them if an EFR bit is set.
 -               */
 -              scratch2 = serial_in(up, UART_IER) & 0x0f;
 -              serial_out(up, UART_IER, 0x0F);
 -#ifdef __i386__
 -              outb(0, 0x080);
 -#endif
 -              scratch3 = serial_in(up, UART_IER) & 0x0f;
 -              serial_out(up, UART_IER, scratch);
 -              if (scratch2 != 0 || scratch3 != 0x0F) {
 -                      /*
 -                       * We failed; there's nothing here
 -                       */
 -                      spin_unlock_irqrestore(&port->lock, flags);
 -                      DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
 -                                     scratch2, scratch3);
 -                      goto out;
 -              }
 -      }
 -
 -      save_mcr = serial_in(up, UART_MCR);
 -      save_lcr = serial_in(up, UART_LCR);
 -
 -      /*
 -       * Check to see if a UART is really there.  Certain broken
 -       * internal modems based on the Rockwell chipset fail this
 -       * test, because they apparently don't implement the loopback
 -       * test mode.  So this test is skipped on the COM 1 through
 -       * COM 4 ports.  This *should* be safe, since no board
 -       * manufacturer would be stupid enough to design a board
 -       * that conflicts with COM 1-4 --- we hope!
 -       */
 -      if (!(port->flags & UPF_SKIP_TEST)) {
 -              serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A);
 -              status1 = serial_in(up, UART_MSR) & 0xF0;
 -              serial_out(up, UART_MCR, save_mcr);
 -              if (status1 != 0x90) {
 -                      spin_unlock_irqrestore(&port->lock, flags);
 -                      DEBUG_AUTOCONF("LOOP test failed (%02x) ",
 -                                     status1);
 -                      goto out;
 -              }
 -      }
 -
 -      /*
 -       * We're pretty sure there's a port here.  Lets find out what
 -       * type of port it is.  The IIR top two bits allows us to find
 -       * out if it's 8250 or 16450, 16550, 16550A or later.  This
 -       * determines what we test for next.
 -       *
 -       * We also initialise the EFR (if any) to zero for later.  The
 -       * EFR occupies the same register location as the FCR and IIR.
 -       */
 -      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 -      serial_out(up, UART_EFR, 0);
 -      serial_out(up, UART_LCR, 0);
 -
 -      serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
 -      scratch = serial_in(up, UART_IIR) >> 6;
 -
 -      switch (scratch) {
 -      case 0:
 -              autoconfig_8250(up);
 -              break;
 -      case 1:
 -              port->type = PORT_UNKNOWN;
 -              break;
 -      case 2:
 -              port->type = PORT_16550;
 -              break;
 -      case 3:
 -              autoconfig_16550a(up);
 -              break;
 -      }
 -
 -#ifdef CONFIG_SERIAL_8250_RSA
 -      /*
 -       * Only probe for RSA ports if we got the region.
 -       */
 -      if (port->type == PORT_16550A && up->probe & UART_PROBE_RSA &&
 -          __enable_rsa(up))
 -              port->type = PORT_RSA;
 -#endif
 -
 -      serial_out(up, UART_LCR, save_lcr);
 -
 -      port->fifosize = uart_config[up->port.type].fifo_size;
 -      old_capabilities = up->capabilities;
 -      up->capabilities = uart_config[port->type].flags;
 -      up->tx_loadsz = uart_config[port->type].tx_loadsz;
 -
 -      if (port->type == PORT_UNKNOWN)
 -              goto out_lock;
 -
 -      /*
 -       * Reset the UART.
 -       */
 -#ifdef CONFIG_SERIAL_8250_RSA
 -      if (port->type == PORT_RSA)
 -              serial_out(up, UART_RSA_FRR, 0);
 -#endif
 -      serial_out(up, UART_MCR, save_mcr);
 -      serial8250_clear_fifos(up);
 -      serial_in(up, UART_RX);
 -      if (up->capabilities & UART_CAP_UUE)
 -              serial_out(up, UART_IER, UART_IER_UUE);
 -      else
 -              serial_out(up, UART_IER, 0);
 -
 -out_lock:
 -      spin_unlock_irqrestore(&port->lock, flags);
 -      if (up->capabilities != old_capabilities) {
 -              printk(KERN_WARNING
 -                     "ttyS%d: detected caps %08x should be %08x\n",
 -                     serial_index(port), old_capabilities,
 -                     up->capabilities);
 -      }
 -out:
 -      DEBUG_AUTOCONF("iir=%d ", scratch);
 -      DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name);
 -}
 -
 -static void autoconfig_irq(struct uart_8250_port *up)
 -{
 -      struct uart_port *port = &up->port;
 -      unsigned char save_mcr, save_ier;
 -      unsigned char save_ICP = 0;
 -      unsigned int ICP = 0;
 -      unsigned long irqs;
 -      int irq;
 -
 -      if (port->flags & UPF_FOURPORT) {
 -              ICP = (port->iobase & 0xfe0) | 0x1f;
 -              save_ICP = inb_p(ICP);
 -              outb_p(0x80, ICP);
 -              inb_p(ICP);
 -      }
 -
 -      /* forget possible initially masked and pending IRQ */
 -      probe_irq_off(probe_irq_on());
 -      save_mcr = serial_in(up, UART_MCR);
 -      save_ier = serial_in(up, UART_IER);
 -      serial_out(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
 -
 -      irqs = probe_irq_on();
 -      serial_out(up, UART_MCR, 0);
 -      udelay(10);
 -      if (port->flags & UPF_FOURPORT) {
 -              serial_out(up, UART_MCR,
 -                          UART_MCR_DTR | UART_MCR_RTS);
 -      } else {
 -              serial_out(up, UART_MCR,
 -                          UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
 -      }
 -      serial_out(up, UART_IER, 0x0f); /* enable all intrs */
 -      serial_in(up, UART_LSR);
 -      serial_in(up, UART_RX);
 -      serial_in(up, UART_IIR);
 -      serial_in(up, UART_MSR);
 -      serial_out(up, UART_TX, 0xFF);
 -      udelay(20);
 -      irq = probe_irq_off(irqs);
 -
 -      serial_out(up, UART_MCR, save_mcr);
 -      serial_out(up, UART_IER, save_ier);
 -
 -      if (port->flags & UPF_FOURPORT)
 -              outb_p(save_ICP, ICP);
 -
 -      port->irq = (irq > 0) ? irq : 0;
 -}
 -
 -static inline void __stop_tx(struct uart_8250_port *p)
 -{
 -      if (p->ier & UART_IER_THRI) {
 -              p->ier &= ~UART_IER_THRI;
 -              serial_out(p, UART_IER, p->ier);
 -              serial8250_rpm_put_tx(p);
 -      }
 -}
 -
 -static void serial8250_stop_tx(struct uart_port *port)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -
 -      serial8250_rpm_get(up);
 -      __stop_tx(up);
 -
 -      /*
 -       * We really want to stop the transmitter from sending.
 -       */
 -      if (port->type == PORT_16C950) {
 -              up->acr |= UART_ACR_TXDIS;
 -              serial_icr_write(up, UART_ACR, up->acr);
 -      }
 -      serial8250_rpm_put(up);
 -}
 -
 -static void serial8250_start_tx(struct uart_port *port)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -
 -      serial8250_rpm_get_tx(up);
 -
 -      if (up->dma && !up->dma->tx_dma(up))
 -              return;
 -
 -      if (!(up->ier & UART_IER_THRI)) {
 -              up->ier |= UART_IER_THRI;
 -              serial_port_out(port, UART_IER, up->ier);
 -
 -              if (up->bugs & UART_BUG_TXEN) {
 -                      unsigned char lsr;
 -                      lsr = serial_in(up, UART_LSR);
 -                      up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
 -                      if (lsr & UART_LSR_THRE)
 -                              serial8250_tx_chars(up);
 -              }
 -      }
 -
 -      /*
 -       * Re-enable the transmitter if we disabled it.
 -       */
 -      if (port->type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
 -              up->acr &= ~UART_ACR_TXDIS;
 -              serial_icr_write(up, UART_ACR, up->acr);
 -      }
 -}
 -
 -static void serial8250_throttle(struct uart_port *port)
 -{
 -      port->throttle(port);
 -}
 -
 -static void serial8250_unthrottle(struct uart_port *port)
 -{
 -      port->unthrottle(port);
 -}
 -
 -static void serial8250_stop_rx(struct uart_port *port)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -
 -      serial8250_rpm_get(up);
 -
 -      up->ier &= ~(UART_IER_RLSI | UART_IER_RDI);
 -      up->port.read_status_mask &= ~UART_LSR_DR;
 -      serial_port_out(port, UART_IER, up->ier);
 -
 -      serial8250_rpm_put(up);
 -}
 -
 -static void serial8250_disable_ms(struct uart_port *port)
 -{
 -      struct uart_8250_port *up =
 -              container_of(port, struct uart_8250_port, port);
 -
 -      /* no MSR capabilities */
 -      if (up->bugs & UART_BUG_NOMSR)
 -              return;
 -
 -      up->ier &= ~UART_IER_MSI;
 -      serial_port_out(port, UART_IER, up->ier);
 -}
 -
 -static void serial8250_enable_ms(struct uart_port *port)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -
 -      /* no MSR capabilities */
 -      if (up->bugs & UART_BUG_NOMSR)
 -              return;
 -
 -      up->ier |= UART_IER_MSI;
 -
 -      serial8250_rpm_get(up);
 -      serial_port_out(port, UART_IER, up->ier);
 -      serial8250_rpm_put(up);
 -}
 -
 -/*
 - * serial8250_rx_chars: processes according to the passed in LSR
 - * value, and returns the remaining LSR bits not handled
 - * by this Rx routine.
 - */
 -unsigned char
 -serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
 -{
 -      struct uart_port *port = &up->port;
 -      unsigned char ch;
 -      int max_count = 256;
 -      char flag;
 -
 -      do {
 -              if (likely(lsr & UART_LSR_DR))
 -                      ch = serial_in(up, UART_RX);
 -              else
 -                      /*
 -                       * Intel 82571 has a Serial Over Lan device that will
 -                       * set UART_LSR_BI without setting UART_LSR_DR when
 -                       * it receives a break. To avoid reading from the
 -                       * receive buffer without UART_LSR_DR bit set, we
 -                       * just force the read character to be 0
 -                       */
 -                      ch = 0;
 -
 -              flag = TTY_NORMAL;
 -              port->icount.rx++;
 -
 -              lsr |= up->lsr_saved_flags;
 -              up->lsr_saved_flags = 0;
 -
 -              if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
 -                      if (lsr & UART_LSR_BI) {
 -                              lsr &= ~(UART_LSR_FE | UART_LSR_PE);
 -                              port->icount.brk++;
 -                              /*
 -                               * We do the SysRQ and SAK checking
 -                               * here because otherwise the break
 -                               * may get masked by ignore_status_mask
 -                               * or read_status_mask.
 -                               */
 -                              if (uart_handle_break(port))
 -                                      goto ignore_char;
 -                      } else if (lsr & UART_LSR_PE)
 -                              port->icount.parity++;
 -                      else if (lsr & UART_LSR_FE)
 -                              port->icount.frame++;
 -                      if (lsr & UART_LSR_OE)
 -                              port->icount.overrun++;
 -
 -                      /*
 -                       * Mask off conditions which should be ignored.
 -                       */
 -                      lsr &= port->read_status_mask;
 -
 -                      if (lsr & UART_LSR_BI) {
 -                              DEBUG_INTR("handling break....");
 -                              flag = TTY_BREAK;
 -                      } else if (lsr & UART_LSR_PE)
 -                              flag = TTY_PARITY;
 -                      else if (lsr & UART_LSR_FE)
 -                              flag = TTY_FRAME;
 -              }
 -              if (uart_handle_sysrq_char(port, ch))
 -                      goto ignore_char;
 -
 -              uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
 -
 -ignore_char:
 -              lsr = serial_in(up, UART_LSR);
 -      } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (--max_count > 0));
 -      spin_unlock(&port->lock);
 -      tty_flip_buffer_push(&port->state->port);
 -      spin_lock(&port->lock);
 -      return lsr;
 -}
 -EXPORT_SYMBOL_GPL(serial8250_rx_chars);
 -
 -void serial8250_tx_chars(struct uart_8250_port *up)
 -{
 -      struct uart_port *port = &up->port;
 -      struct circ_buf *xmit = &port->state->xmit;
 -      int count;
 -
 -      if (port->x_char) {
 -              serial_out(up, UART_TX, port->x_char);
 -              port->icount.tx++;
 -              port->x_char = 0;
 -              return;
 -      }
 -      if (uart_tx_stopped(port)) {
 -              serial8250_stop_tx(port);
 -              return;
 -      }
 -      if (uart_circ_empty(xmit)) {
 -              __stop_tx(up);
 -              return;
 -      }
 -
 -      count = up->tx_loadsz;
 -      do {
 -              serial_out(up, UART_TX, xmit->buf[xmit->tail]);
 -              xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 -              port->icount.tx++;
 -              if (uart_circ_empty(xmit))
 -                      break;
 -              if (up->capabilities & UART_CAP_HFIFO) {
 -                      if ((serial_port_in(port, UART_LSR) & BOTH_EMPTY) !=
 -                          BOTH_EMPTY)
 -                              break;
 -              }
 -      } while (--count > 0);
 -
 -      if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 -              uart_write_wakeup(port);
 -
 -      DEBUG_INTR("THRE...");
 -
 -      /*
 -       * With RPM enabled, we have to wait until the FIFO is empty before the
 -       * HW can go idle. So we get here once again with empty FIFO and disable
 -       * the interrupt and RPM in __stop_tx()
 -       */
 -      if (uart_circ_empty(xmit) && !(up->capabilities & UART_CAP_RPM))
 -              __stop_tx(up);
 -}
 -EXPORT_SYMBOL_GPL(serial8250_tx_chars);
 -
 -/* Caller holds uart port lock */
 -unsigned int serial8250_modem_status(struct uart_8250_port *up)
 -{
 -      struct uart_port *port = &up->port;
 -      unsigned int status = serial_in(up, UART_MSR);
 -
 -      status |= up->msr_saved_flags;
 -      up->msr_saved_flags = 0;
 -      if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
 -          port->state != NULL) {
 -              if (status & UART_MSR_TERI)
 -                      port->icount.rng++;
 -              if (status & UART_MSR_DDSR)
 -                      port->icount.dsr++;
 -              if (status & UART_MSR_DDCD)
 -                      uart_handle_dcd_change(port, status & UART_MSR_DCD);
 -              if (status & UART_MSR_DCTS)
 -                      uart_handle_cts_change(port, status & UART_MSR_CTS);
 -
 -              wake_up_interruptible(&port->state->port.delta_msr_wait);
 -      }
 -
 -      return status;
 -}
 -EXPORT_SYMBOL_GPL(serial8250_modem_status);
 -
 -/*
 - * This handles the interrupt from one port.
 - */
 -int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
 -{
 -      unsigned char status;
 -      unsigned long flags;
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -      int dma_err = 0;
 -
 -      if (iir & UART_IIR_NO_INT)
 -              return 0;
 -
 -      spin_lock_irqsave(&port->lock, flags);
 -
 -      status = serial_port_in(port, UART_LSR);
 -
 -      DEBUG_INTR("status = %x...", status);
 -
 -      if (status & (UART_LSR_DR | UART_LSR_BI)) {
 -              if (up->dma)
 -                      dma_err = up->dma->rx_dma(up, iir);
 -
 -              if (!up->dma || dma_err)
 -                      status = serial8250_rx_chars(up, status);
 -      }
 -      serial8250_modem_status(up);
 -      if ((!up->dma || (up->dma && up->dma->tx_err)) &&
 -          (status & UART_LSR_THRE))
 -              serial8250_tx_chars(up);
 -
 -      spin_unlock_irqrestore(&port->lock, flags);
 -      return 1;
 -}
 -EXPORT_SYMBOL_GPL(serial8250_handle_irq);
 -
 -static int serial8250_default_handle_irq(struct uart_port *port)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -      unsigned int iir;
 -      int ret;
 -
 -      serial8250_rpm_get(up);
 -
 -      iir = serial_port_in(port, UART_IIR);
 -      ret = serial8250_handle_irq(port, iir);
 -
 -      serial8250_rpm_put(up);
 -      return ret;
 -}
 -
 -/*
 - * These Exar UARTs have an extra interrupt indicator that could
 - * fire for a few unimplemented interrupts.  One of which is a
 - * wakeup event when coming out of sleep.  Put this here just
 - * to be on the safe side that these interrupts don't go unhandled.
 - */
 -static int exar_handle_irq(struct uart_port *port)
 -{
 -      unsigned char int0, int1, int2, int3;
 -      unsigned int iir = serial_port_in(port, UART_IIR);
 -      int ret;
 -
 -      ret = serial8250_handle_irq(port, iir);
 -
 -      if ((port->type == PORT_XR17V35X) ||
 -         (port->type == PORT_XR17D15X)) {
 -              int0 = serial_port_in(port, 0x80);
 -              int1 = serial_port_in(port, 0x81);
 -              int2 = serial_port_in(port, 0x82);
 -              int3 = serial_port_in(port, 0x83);
 -      }
 -
 -      return ret;
 -}
 -
 -/*
 - * This is the serial driver's interrupt routine.
 - *
 - * Arjan thinks the old way was overly complex, so it got simplified.
 - * Alan disagrees, saying that need the complexity to handle the weird
 - * nature of ISA shared interrupts.  (This is a special exception.)
 - *
 - * In order to handle ISA shared interrupts properly, we need to check
 - * that all ports have been serviced, and therefore the ISA interrupt
 - * line has been de-asserted.
 - *
 - * This means we need to loop through all ports. checking that they
 - * don't have an interrupt pending.
 - */
 -static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
 -{
 -      struct irq_info *i = dev_id;
 -      struct list_head *l, *end = NULL;
 -      int pass_counter = 0, handled = 0;
 -
 -      DEBUG_INTR("serial8250_interrupt(%d)...", irq);
 -
 -      spin_lock(&i->lock);
 -
 -      l = i->head;
 -      do {
 -              struct uart_8250_port *up;
 -              struct uart_port *port;
 -
 -              up = list_entry(l, struct uart_8250_port, list);
 -              port = &up->port;
 -
 -              if (port->handle_irq(port)) {
 -                      handled = 1;
 -                      end = NULL;
 -              } else if (end == NULL)
 -                      end = l;
 -
 -              l = l->next;
 -
 -              if (l == i->head && pass_counter++ > PASS_LIMIT) {
 -                      /* If we hit this, we're dead. */
 -                      printk_ratelimited(KERN_ERR
 -                              "serial8250: too much work for irq%d\n", irq);
 -                      break;
 -              }
 -      } while (l != end);
 -
 -      spin_unlock(&i->lock);
 -
 -      DEBUG_INTR("end.\n");
 -
 -      return IRQ_RETVAL(handled);
 -}
 -
 -/*
 - * To support ISA shared interrupts, we need to have one interrupt
 - * handler that ensures that the IRQ line has been deasserted
 - * before returning.  Failing to do this will result in the IRQ
 - * line being stuck active, and, since ISA irqs are edge triggered,
 - * no more IRQs will be seen.
 - */
 -static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
 -{
 -      spin_lock_irq(&i->lock);
 -
 -      if (!list_empty(i->head)) {
 -              if (i->head == &up->list)
 -                      i->head = i->head->next;
 -              list_del(&up->list);
 -      } else {
 -              BUG_ON(i->head != &up->list);
 -              i->head = NULL;
 -      }
 -      spin_unlock_irq(&i->lock);
 -      /* List empty so throw away the hash node */
 -      if (i->head == NULL) {
 -              hlist_del(&i->node);
 -              kfree(i);
 -      }
 -}
 -
 -static int serial_link_irq_chain(struct uart_8250_port *up)
 -{
 -      struct hlist_head *h;
 -      struct hlist_node *n;
 -      struct irq_info *i;
 -      int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
 -
 -      mutex_lock(&hash_mutex);
 -
 -      h = &irq_lists[up->port.irq % NR_IRQ_HASH];
 -
 -      hlist_for_each(n, h) {
 -              i = hlist_entry(n, struct irq_info, node);
 -              if (i->irq == up->port.irq)
 -                      break;
 -      }
 -
 -      if (n == NULL) {
 -              i = kzalloc(sizeof(struct irq_info), GFP_KERNEL);
 -              if (i == NULL) {
 -                      mutex_unlock(&hash_mutex);
 -                      return -ENOMEM;
 -              }
 -              spin_lock_init(&i->lock);
 -              i->irq = up->port.irq;
 -              hlist_add_head(&i->node, h);
 -      }
 -      mutex_unlock(&hash_mutex);
 -
 -      spin_lock_irq(&i->lock);
 -
 -      if (i->head) {
 -              list_add(&up->list, i->head);
 -              spin_unlock_irq(&i->lock);
 -
 -              ret = 0;
 -      } else {
 -              INIT_LIST_HEAD(&up->list);
 -              i->head = &up->list;
 -              spin_unlock_irq(&i->lock);
 -              irq_flags |= up->port.irqflags;
 -              ret = request_irq(up->port.irq, serial8250_interrupt,
 -                                irq_flags, "serial", i);
 -              if (ret < 0)
 -                      serial_do_unlink(i, up);
 -      }
 -
 -      return ret;
 -}
 -
 -static void serial_unlink_irq_chain(struct uart_8250_port *up)
 -{
 -      /*
 -       * yes, some broken gcc emit "warning: 'i' may be used uninitialized"
 -       * but no, we are not going to take a patch that assigns NULL below.
 -       */
 -      struct irq_info *i;
 -      struct hlist_node *n;
 -      struct hlist_head *h;
 -
 -      mutex_lock(&hash_mutex);
 -
 -      h = &irq_lists[up->port.irq % NR_IRQ_HASH];
 -
 -      hlist_for_each(n, h) {
 -              i = hlist_entry(n, struct irq_info, node);
 -              if (i->irq == up->port.irq)
 -                      break;
 -      }
 -
 -      BUG_ON(n == NULL);
 -      BUG_ON(i->head == NULL);
 -
 -      if (list_empty(i->head))
 -              free_irq(up->port.irq, i);
 -
 -      serial_do_unlink(i, up);
 -      mutex_unlock(&hash_mutex);
 -}
 -
 -/*
 - * This function is used to handle ports that do not have an
 - * interrupt.  This doesn't work very well for 16450's, but gives
 - * barely passable results for a 16550A.  (Although at the expense
 - * of much CPU overhead).
 - */
 -static void serial8250_timeout(unsigned long data)
 -{
 -      struct uart_8250_port *up = (struct uart_8250_port *)data;
 -
 -      up->port.handle_irq(&up->port);
 -      mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port));
 -}
 -
 -static void serial8250_backup_timeout(unsigned long data)
 -{
 -      struct uart_8250_port *up = (struct uart_8250_port *)data;
 -      unsigned int iir, ier = 0, lsr;
 -      unsigned long flags;
 -
 -      spin_lock_irqsave(&up->port.lock, flags);
 -
 -      /*
 -       * Must disable interrupts or else we risk racing with the interrupt
 -       * based handler.
 -       */
 -      if (up->port.irq) {
 -              ier = serial_in(up, UART_IER);
 -              serial_out(up, UART_IER, 0);
 -      }
 -
 -      iir = serial_in(up, UART_IIR);
 -
 -      /*
 -       * This should be a safe test for anyone who doesn't trust the
 -       * IIR bits on their UART, but it's specifically designed for
 -       * the "Diva" UART used on the management processor on many HP
 -       * ia64 and parisc boxes.
 -       */
 -      lsr = serial_in(up, UART_LSR);
 -      up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
 -      if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
 -          (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
 -          (lsr & UART_LSR_THRE)) {
 -              iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
 -              iir |= UART_IIR_THRI;
 -      }
 -
 -      if (!(iir & UART_IIR_NO_INT))
 -              serial8250_tx_chars(up);
 -
 -      if (up->port.irq)
 -              serial_out(up, UART_IER, ier);
 -
 -      spin_unlock_irqrestore(&up->port.lock, flags);
 -
 -      /* Standard timer interval plus 0.2s to keep the port running */
 -      mod_timer(&up->timer,
 -              jiffies + uart_poll_timeout(&up->port) + HZ / 5);
 -}
 -
 -static int univ8250_setup_irq(struct uart_8250_port *up)
 -{
 -      struct uart_port *port = &up->port;
 -      int retval = 0;
 -
 -      /*
 -       * The above check will only give an accurate result the first time
 -       * the port is opened so this value needs to be preserved.
 -       */
 -      if (up->bugs & UART_BUG_THRE) {
 -              pr_debug("ttyS%d - using backup timer\n", serial_index(port));
 -
 -              up->timer.function = serial8250_backup_timeout;
 -              up->timer.data = (unsigned long)up;
 -              mod_timer(&up->timer, jiffies +
 -                        uart_poll_timeout(port) + HZ / 5);
 -      }
 -
 -      /*
 -       * If the "interrupt" for this port doesn't correspond with any
 -       * hardware interrupt, we use a timer-based system.  The original
 -       * driver used to do this with IRQ0.
 -       */
 -      if (!port->irq) {
 -              up->timer.data = (unsigned long)up;
 -              mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
 -      } else
 -              retval = serial_link_irq_chain(up);
 -
 -      return retval;
 -}
 -
 -static void univ8250_release_irq(struct uart_8250_port *up)
 -{
 -      struct uart_port *port = &up->port;
 -
 -      del_timer_sync(&up->timer);
 -      up->timer.function = serial8250_timeout;
 -      if (port->irq)
 -              serial_unlink_irq_chain(up);
 -}
 -
 -static unsigned int serial8250_tx_empty(struct uart_port *port)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -      unsigned long flags;
 -      unsigned int lsr;
 -
 -      serial8250_rpm_get(up);
 -
 -      spin_lock_irqsave(&port->lock, flags);
 -      lsr = serial_port_in(port, UART_LSR);
 -      up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
 -      spin_unlock_irqrestore(&port->lock, flags);
 -
 -      serial8250_rpm_put(up);
 -
 -      return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
 -}
 -
 -static unsigned int serial8250_get_mctrl(struct uart_port *port)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -      unsigned int status;
 -      unsigned int ret;
 -
 -      serial8250_rpm_get(up);
 -      status = serial8250_modem_status(up);
 -      serial8250_rpm_put(up);
 -
 -      ret = 0;
 -      if (status & UART_MSR_DCD)
 -              ret |= TIOCM_CAR;
 -      if (status & UART_MSR_RI)
 -              ret |= TIOCM_RNG;
 -      if (status & UART_MSR_DSR)
 -              ret |= TIOCM_DSR;
 -      if (status & UART_MSR_CTS)
 -              ret |= TIOCM_CTS;
 -      return ret;
 -}
 -
 -void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -      unsigned char mcr = 0;
 -
 -      if (mctrl & TIOCM_RTS)
 -              mcr |= UART_MCR_RTS;
 -      if (mctrl & TIOCM_DTR)
 -              mcr |= UART_MCR_DTR;
 -      if (mctrl & TIOCM_OUT1)
 -              mcr |= UART_MCR_OUT1;
 -      if (mctrl & TIOCM_OUT2)
 -              mcr |= UART_MCR_OUT2;
 -      if (mctrl & TIOCM_LOOP)
 -              mcr |= UART_MCR_LOOP;
 -
 -      mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
 -
 -      serial_port_out(port, UART_MCR, mcr);
 -}
 -EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl);
 -
 -static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
 -{
 -      if (port->set_mctrl)
 -              port->set_mctrl(port, mctrl);
 -      else
 -              serial8250_do_set_mctrl(port, mctrl);
 -}
 -
 -static void serial8250_break_ctl(struct uart_port *port, int break_state)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -      unsigned long flags;
 -
 -      serial8250_rpm_get(up);
 -      spin_lock_irqsave(&port->lock, flags);
 -      if (break_state == -1)
 -              up->lcr |= UART_LCR_SBC;
 -      else
 -              up->lcr &= ~UART_LCR_SBC;
 -      serial_port_out(port, UART_LCR, up->lcr);
 -      spin_unlock_irqrestore(&port->lock, flags);
 -      serial8250_rpm_put(up);
 -}
 -
 -/*
 - *    Wait for transmitter & holding register to empty
 - */
 -static void wait_for_xmitr(struct uart_8250_port *up, int bits)
 -{
 -      unsigned int status, tmout = 10000;
 -
 -      /* Wait up to 10ms for the character(s) to be sent. */
 -      for (;;) {
 -              status = serial_in(up, UART_LSR);
 -
 -              up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
 -
 -              if ((status & bits) == bits)
 -                      break;
 -              if (--tmout == 0)
 -                      break;
 -              udelay(1);
 -      }
 -
 -      /* Wait up to 1s for flow control if necessary */
 -      if (up->port.flags & UPF_CONS_FLOW) {
 -              unsigned int tmout;
 -              for (tmout = 1000000; tmout; tmout--) {
 -                      unsigned int msr = serial_in(up, UART_MSR);
 -                      up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
 -                      if (msr & UART_MSR_CTS)
 -                              break;
 -                      udelay(1);
 -                      touch_nmi_watchdog();
 -              }
 -      }
 -}
 -
 -#ifdef CONFIG_CONSOLE_POLL
 -/*
 - * Console polling routines for writing and reading from the uart while
 - * in an interrupt or debug context.
 - */
 -
 -static int serial8250_get_poll_char(struct uart_port *port)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -      unsigned char lsr;
 -      int status;
 -
 -      serial8250_rpm_get(up);
 -
 -      lsr = serial_port_in(port, UART_LSR);
 -
 -      if (!(lsr & UART_LSR_DR)) {
 -              status = NO_POLL_CHAR;
 -              goto out;
 -      }
 -
 -      status = serial_port_in(port, UART_RX);
 -out:
 -      serial8250_rpm_put(up);
 -      return status;
 -}
 -
 -
 -static void serial8250_put_poll_char(struct uart_port *port,
 -                       unsigned char c)
 -{
 -      unsigned int ier;
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -
 -      serial8250_rpm_get(up);
 -      /*
 -       *      First save the IER then disable the interrupts
 -       */
 -      ier = serial_port_in(port, UART_IER);
 -      if (up->capabilities & UART_CAP_UUE)
 -              serial_port_out(port, UART_IER, UART_IER_UUE);
 -      else
 -              serial_port_out(port, UART_IER, 0);
 -
 -      wait_for_xmitr(up, BOTH_EMPTY);
 -      /*
 -       *      Send the character out.
 -       */
 -      serial_port_out(port, UART_TX, c);
 -
 -      /*
 -       *      Finally, wait for transmitter to become empty
 -       *      and restore the IER
 -       */
 -      wait_for_xmitr(up, BOTH_EMPTY);
 -      serial_port_out(port, UART_IER, ier);
 -      serial8250_rpm_put(up);
 -}
 -
 -#endif /* CONFIG_CONSOLE_POLL */
 -
 -int serial8250_do_startup(struct uart_port *port)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -      unsigned long flags;
 -      unsigned char lsr, iir;
 -      int retval;
 -
 -      if (port->type == PORT_8250_CIR)
 -              return -ENODEV;
 -
 -      if (!port->fifosize)
 -              port->fifosize = uart_config[port->type].fifo_size;
 -      if (!up->tx_loadsz)
 -              up->tx_loadsz = uart_config[port->type].tx_loadsz;
 -      if (!up->capabilities)
 -              up->capabilities = uart_config[port->type].flags;
 -      up->mcr = 0;
 -
 -      if (port->iotype != up->cur_iotype)
 -              set_io_from_upio(port);
 -
 -      serial8250_rpm_get(up);
 -      if (port->type == PORT_16C950) {
 -              /* Wake up and initialize UART */
 -              up->acr = 0;
 -              serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B);
 -              serial_port_out(port, UART_EFR, UART_EFR_ECB);
 -              serial_port_out(port, UART_IER, 0);
 -              serial_port_out(port, UART_LCR, 0);
 -              serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
 -              serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B);
 -              serial_port_out(port, UART_EFR, UART_EFR_ECB);
 -              serial_port_out(port, UART_LCR, 0);
 -      }
 -
 -#ifdef CONFIG_SERIAL_8250_RSA
 -      /*
 -       * If this is an RSA port, see if we can kick it up to the
 -       * higher speed clock.
 -       */
 -      enable_rsa(up);
 -#endif
 -      /*
 -       * Clear the FIFO buffers and disable them.
 -       * (they will be reenabled in set_termios())
 -       */
 -      serial8250_clear_fifos(up);
 -
 -      /*
 -       * Clear the interrupt registers.
 -       */
 -      serial_port_in(port, UART_LSR);
 -      serial_port_in(port, UART_RX);
 -      serial_port_in(port, UART_IIR);
 -      serial_port_in(port, UART_MSR);
 -
 -      /*
 -       * At this point, there's no way the LSR could still be 0xff;
 -       * if it is, then bail out, because there's likely no UART
 -       * here.
 -       */
 -      if (!(port->flags & UPF_BUGGY_UART) &&
 -          (serial_port_in(port, UART_LSR) == 0xff)) {
 -              printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n",
 -                                 serial_index(port));
 -              retval = -ENODEV;
 -              goto out;
 -      }
 -
 -      /*
 -       * For a XR16C850, we need to set the trigger levels
 -       */
 -      if (port->type == PORT_16850) {
 -              unsigned char fctr;
 -
 -              serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 -
 -              fctr = serial_in(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX);
 -              serial_port_out(port, UART_FCTR,
 -                              fctr | UART_FCTR_TRGD | UART_FCTR_RX);
 -              serial_port_out(port, UART_TRG, UART_TRG_96);
 -              serial_port_out(port, UART_FCTR,
 -                              fctr | UART_FCTR_TRGD | UART_FCTR_TX);
 -              serial_port_out(port, UART_TRG, UART_TRG_96);
 -
 -              serial_port_out(port, UART_LCR, 0);
 -      }
 -
 -      if (port->irq) {
 -              unsigned char iir1;
 -              /*
 -               * Test for UARTs that do not reassert THRE when the
 -               * transmitter is idle and the interrupt has already
 -               * been cleared.  Real 16550s should always reassert
 -               * this interrupt whenever the transmitter is idle and
 -               * the interrupt is enabled.  Delays are necessary to
 -               * allow register changes to become visible.
 -               */
 -              spin_lock_irqsave(&port->lock, flags);
 -              if (up->port.irqflags & IRQF_SHARED)
 -                      disable_irq_nosync(port->irq);
 -
 -              wait_for_xmitr(up, UART_LSR_THRE);
 -              serial_port_out_sync(port, UART_IER, UART_IER_THRI);
 -              udelay(1); /* allow THRE to set */
 -              iir1 = serial_port_in(port, UART_IIR);
 -              serial_port_out(port, UART_IER, 0);
 -              serial_port_out_sync(port, UART_IER, UART_IER_THRI);
 -              udelay(1); /* allow a working UART time to re-assert THRE */
 -              iir = serial_port_in(port, UART_IIR);
 -              serial_port_out(port, UART_IER, 0);
 -
 -              if (port->irqflags & IRQF_SHARED)
 -                      enable_irq(port->irq);
 -              spin_unlock_irqrestore(&port->lock, flags);
 -
 -              /*
 -               * If the interrupt is not reasserted, or we otherwise
 -               * don't trust the iir, setup a timer to kick the UART
 -               * on a regular basis.
 -               */
 -              if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) ||
 -                  up->port.flags & UPF_BUG_THRE) {
 -                      up->bugs |= UART_BUG_THRE;
 -              }
 -      }
 -
 -      retval = up->ops->setup_irq(up);
 -      if (retval)
 -              goto out;
 -
 -      /*
 -       * Now, initialize the UART
 -       */
 -      serial_port_out(port, UART_LCR, UART_LCR_WLEN8);
 -
 -      spin_lock_irqsave(&port->lock, flags);
 -      if (up->port.flags & UPF_FOURPORT) {
 -              if (!up->port.irq)
 -                      up->port.mctrl |= TIOCM_OUT1;
 -      } else
 -              /*
 -               * Most PC uarts need OUT2 raised to enable interrupts.
 -               */
 -              if (port->irq)
 -                      up->port.mctrl |= TIOCM_OUT2;
 -
 -      serial8250_set_mctrl(port, port->mctrl);
 -
 -      /* Serial over Lan (SoL) hack:
 -         Intel 8257x Gigabit ethernet chips have a
 -         16550 emulation, to be used for Serial Over Lan.
 -         Those chips take a longer time than a normal
 -         serial device to signalize that a transmission
 -         data was queued. Due to that, the above test generally
 -         fails. One solution would be to delay the reading of
 -         iir. However, this is not reliable, since the timeout
 -         is variable. So, let's just don't test if we receive
 -         TX irq. This way, we'll never enable UART_BUG_TXEN.
 -       */
 -      if (up->port.flags & UPF_NO_TXEN_TEST)
 -              goto dont_test_tx_en;
 -
 -      /*
 -       * Do a quick test to see if we receive an
 -       * interrupt when we enable the TX irq.
 -       */
 -      serial_port_out(port, UART_IER, UART_IER_THRI);
 -      lsr = serial_port_in(port, UART_LSR);
 -      iir = serial_port_in(port, UART_IIR);
 -      serial_port_out(port, UART_IER, 0);
 -
 -      if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
 -              if (!(up->bugs & UART_BUG_TXEN)) {
 -                      up->bugs |= UART_BUG_TXEN;
 -                      pr_debug("ttyS%d - enabling bad tx status workarounds\n",
 -                               serial_index(port));
 -              }
 -      } else {
 -              up->bugs &= ~UART_BUG_TXEN;
 -      }
 -
 -dont_test_tx_en:
 -      spin_unlock_irqrestore(&port->lock, flags);
 -
 -      /*
 -       * Clear the interrupt registers again for luck, and clear the
 -       * saved flags to avoid getting false values from polling
 -       * routines or the previous session.
 -       */
 -      serial_port_in(port, UART_LSR);
 -      serial_port_in(port, UART_RX);
 -      serial_port_in(port, UART_IIR);
 -      serial_port_in(port, UART_MSR);
 -      up->lsr_saved_flags = 0;
 -      up->msr_saved_flags = 0;
 -
 -      /*
 -       * Request DMA channels for both RX and TX.
 -       */
 -      if (up->dma) {
 -              retval = serial8250_request_dma(up);
 -              if (retval) {
 -                      pr_warn_ratelimited("ttyS%d - failed to request DMA\n",
 -                                          serial_index(port));
 -                      up->dma = NULL;
 -              }
 -      }
 -
 -      /*
 -       * Finally, enable interrupts.  Note: Modem status interrupts
 -       * are set via set_termios(), which will be occurring imminently
 -       * anyway, so we don't enable them here.
 -       */
 -      up->ier = UART_IER_RLSI | UART_IER_RDI;
 -      serial_port_out(port, UART_IER, up->ier);
 -
 -      if (port->flags & UPF_FOURPORT) {
 -              unsigned int icp;
 -              /*
 -               * Enable interrupts on the AST Fourport board
 -               */
 -              icp = (port->iobase & 0xfe0) | 0x01f;
 -              outb_p(0x80, icp);
 -              inb_p(icp);
 -      }
 -      retval = 0;
 -out:
 -      serial8250_rpm_put(up);
 -      return retval;
 -}
 -EXPORT_SYMBOL_GPL(serial8250_do_startup);
 -
 -static int serial8250_startup(struct uart_port *port)
 -{
 -      if (port->startup)
 -              return port->startup(port);
 -      return serial8250_do_startup(port);
 -}
 -
 -void serial8250_do_shutdown(struct uart_port *port)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -      unsigned long flags;
 -
 -      serial8250_rpm_get(up);
 -      /*
 -       * Disable interrupts from this port
 -       */
 -      up->ier = 0;
 -      serial_port_out(port, UART_IER, 0);
 -
 -      if (up->dma)
 -              serial8250_release_dma(up);
 -
 -      spin_lock_irqsave(&port->lock, flags);
 -      if (port->flags & UPF_FOURPORT) {
 -              /* reset interrupts on the AST Fourport board */
 -              inb((port->iobase & 0xfe0) | 0x1f);
 -              port->mctrl |= TIOCM_OUT1;
 -      } else
 -              port->mctrl &= ~TIOCM_OUT2;
 -
 -      serial8250_set_mctrl(port, port->mctrl);
 -      spin_unlock_irqrestore(&port->lock, flags);
 -
 -      /*
 -       * Disable break condition and FIFOs
 -       */
 -      serial_port_out(port, UART_LCR,
 -                      serial_port_in(port, UART_LCR) & ~UART_LCR_SBC);
 -      serial8250_clear_fifos(up);
 -
 -#ifdef CONFIG_SERIAL_8250_RSA
 -      /*
 -       * Reset the RSA board back to 115kbps compat mode.
 -       */
 -      disable_rsa(up);
 -#endif
 -
 -      /*
 -       * Read data port to reset things, and then unlink from
 -       * the IRQ chain.
 -       */
 -      serial_port_in(port, UART_RX);
 -      serial8250_rpm_put(up);
 -
 -      up->ops->release_irq(up);
 -}
 -EXPORT_SYMBOL_GPL(serial8250_do_shutdown);
 -
 -static void serial8250_shutdown(struct uart_port *port)
 -{
 -      if (port->shutdown)
 -              port->shutdown(port);
 -      else
 -              serial8250_do_shutdown(port);
 -}
 -
 -/*
 - * XR17V35x UARTs have an extra fractional divisor register (DLD)
 - * Calculate divisor with extra 4-bit fractional portion
 - */
 -static unsigned int xr17v35x_get_divisor(struct uart_8250_port *up,
 -                                       unsigned int baud,
 -                                       unsigned int *frac)
 -{
 -      struct uart_port *port = &up->port;
 -      unsigned int quot_16;
 -
 -      quot_16 = DIV_ROUND_CLOSEST(port->uartclk, baud);
 -      *frac = quot_16 & 0x0f;
 -
 -      return quot_16 >> 4;
 -}
 -
 -static unsigned int serial8250_get_divisor(struct uart_8250_port *up,
 -                                         unsigned int baud,
 -                                         unsigned int *frac)
 -{
 -      struct uart_port *port = &up->port;
 -      unsigned int quot;
 -
 -      /*
 -       * Handle magic divisors for baud rates above baud_base on
 -       * SMSC SuperIO chips.
 -       *
 -       */
 -      if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
 -          baud == (port->uartclk/4))
 -              quot = 0x8001;
 -      else if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
 -               baud == (port->uartclk/8))
 -              quot = 0x8002;
 -      else if (up->port.type == PORT_XR17V35X)
 -              quot = xr17v35x_get_divisor(up, baud, frac);
 -      else
 -              quot = uart_get_divisor(port, baud);
 -
 -      /*
 -       * Oxford Semi 952 rev B workaround
 -       */
 -      if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
 -              quot++;
 -
 -      return quot;
 -}
 -
 -static unsigned char serial8250_compute_lcr(struct uart_8250_port *up,
 -                                          tcflag_t c_cflag)
 -{
 -      unsigned char cval;
 -
 -      switch (c_cflag & CSIZE) {
 -      case CS5:
 -              cval = UART_LCR_WLEN5;
 -              break;
 -      case CS6:
 -              cval = UART_LCR_WLEN6;
 -              break;
 -      case CS7:
 -              cval = UART_LCR_WLEN7;
 -              break;
 -      default:
 -      case CS8:
 -              cval = UART_LCR_WLEN8;
 -              break;
 -      }
 -
 -      if (c_cflag & CSTOPB)
 -              cval |= UART_LCR_STOP;
 -      if (c_cflag & PARENB) {
 -              cval |= UART_LCR_PARITY;
 -              if (up->bugs & UART_BUG_PARITY)
 -                      up->fifo_bug = true;
 -      }
 -      if (!(c_cflag & PARODD))
 -              cval |= UART_LCR_EPAR;
 -#ifdef CMSPAR
 -      if (c_cflag & CMSPAR)
 -              cval |= UART_LCR_SPAR;
 -#endif
 -
 -      return cval;
 -}
 -
 -static void serial8250_set_divisor(struct uart_port *port, unsigned int baud,
 -                          unsigned int quot, unsigned int quot_frac)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -
 -      /* Workaround to enable 115200 baud on OMAP1510 internal ports */
 -      if (is_omap1510_8250(up)) {
 -              if (baud == 115200) {
 -                      quot = 1;
 -                      serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1);
 -              } else
 -                      serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0);
 -      }
 -
 -      /*
 -       * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2,
 -       * otherwise just set DLAB
 -       */
 -      if (up->capabilities & UART_NATSEMI)
 -              serial_port_out(port, UART_LCR, 0xe0);
 -      else
 -              serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB);
 -
 -      serial_dl_write(up, quot);
 -
 -      /* XR17V35x UARTs have an extra fractional divisor register (DLD) */
 -      if (up->port.type == PORT_XR17V35X)
 -              serial_port_out(port, 0x2, quot_frac);
 -}
 -
 -void
 -serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
 -                        struct ktermios *old)
 +static void serial8250_backup_timeout(unsigned long data)
  {
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -      unsigned char cval;
 +      struct uart_8250_port *up = (struct uart_8250_port *)data;
 +      unsigned int iir, ier = 0, lsr;
        unsigned long flags;
 -      unsigned int baud, quot, frac = 0;
 -
 -      cval = serial8250_compute_lcr(up, termios->c_cflag);
 -
 -      /*
 -       * Ask the core to calculate the divisor for us.
 -       */
 -      baud = uart_get_baud_rate(port, termios, old,
 -                                port->uartclk / 16 / 0xffff,
 -                                port->uartclk / 16);
 -      quot = serial8250_get_divisor(up, baud, &frac);
 -
 -      /*
 -       * Ok, we're now changing the port state.  Do it with
 -       * interrupts disabled.
 -       */
 -      serial8250_rpm_get(up);
 -      spin_lock_irqsave(&port->lock, flags);
 -
 -      up->lcr = cval;                                 /* Save computed LCR */
 -
 -      if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) {
 -              /* NOTE: If fifo_bug is not set, a user can set RX_trigger. */
 -              if ((baud < 2400 && !up->dma) || up->fifo_bug) {
 -                      up->fcr &= ~UART_FCR_TRIGGER_MASK;
 -                      up->fcr |= UART_FCR_TRIGGER_1;
 -              }
 -      }
 -
 -      /*
 -       * MCR-based auto flow control.  When AFE is enabled, RTS will be
 -       * deasserted when the receive FIFO contains more characters than
 -       * the trigger, or the MCR RTS bit is cleared.  In the case where
 -       * the remote UART is not using CTS auto flow control, we must
 -       * have sufficient FIFO entries for the latency of the remote
 -       * UART to respond.  IOW, at least 32 bytes of FIFO.
 -       */
 -      if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) {
 -              up->mcr &= ~UART_MCR_AFE;
 -              if (termios->c_cflag & CRTSCTS)
 -                      up->mcr |= UART_MCR_AFE;
 -      }
 -
 -      /*
 -       * Update the per-port timeout.
 -       */
 -      uart_update_timeout(port, termios->c_cflag, baud);
 -
 -      port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
 -      if (termios->c_iflag & INPCK)
 -              port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
 -      if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
 -              port->read_status_mask |= UART_LSR_BI;
 -
 -      /*
 -       * Characteres to ignore
 -       */
 -      port->ignore_status_mask = 0;
 -      if (termios->c_iflag & IGNPAR)
 -              port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
 -      if (termios->c_iflag & IGNBRK) {
 -              port->ignore_status_mask |= UART_LSR_BI;
 -              /*
 -               * If we're ignoring parity and break indicators,
 -               * ignore overruns too (for real raw support).
 -               */
 -              if (termios->c_iflag & IGNPAR)
 -                      port->ignore_status_mask |= UART_LSR_OE;
 -      }
 -
 -      /*
 -       * ignore all characters if CREAD is not set
 -       */
 -      if ((termios->c_cflag & CREAD) == 0)
 -              port->ignore_status_mask |= UART_LSR_DR;
 -
 -      /*
 -       * CTS flow control flag and modem status interrupts
 -       */
 -      up->ier &= ~UART_IER_MSI;
 -      if (!(up->bugs & UART_BUG_NOMSR) &&
 -                      UART_ENABLE_MS(&up->port, termios->c_cflag))
 -              up->ier |= UART_IER_MSI;
 -      if (up->capabilities & UART_CAP_UUE)
 -              up->ier |= UART_IER_UUE;
 -      if (up->capabilities & UART_CAP_RTOIE)
 -              up->ier |= UART_IER_RTOIE;
 -
 -      serial_port_out(port, UART_IER, up->ier);
 -
 -      if (up->capabilities & UART_CAP_EFR) {
 -              unsigned char efr = 0;
 -              /*
 -               * TI16C752/Startech hardware flow control.  FIXME:
 -               * - TI16C752 requires control thresholds to be set.
 -               * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled.
 -               */
 -              if (termios->c_cflag & CRTSCTS)
 -                      efr |= UART_EFR_CTS;
  
 -              serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B);
 -              if (port->flags & UPF_EXAR_EFR)
 -                      serial_port_out(port, UART_XR_EFR, efr);
 -              else
 -                      serial_port_out(port, UART_EFR, efr);
 -      }
 -
 -      serial8250_set_divisor(port, baud, quot, frac);
 +      spin_lock_irqsave(&up->port.lock, flags);
  
        /*
 -       * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
 -       * is written without DLAB set, this mode will be disabled.
 +       * Must disable interrupts or else we risk racing with the interrupt
 +       * based handler.
         */
 -      if (port->type == PORT_16750)
 -              serial_port_out(port, UART_FCR, up->fcr);
 -
 -      serial_port_out(port, UART_LCR, up->lcr);       /* reset DLAB */
 -      if (port->type != PORT_16750) {
 -              /* emulated UARTs (Lucent Venus 167x) need two steps */
 -              if (up->fcr & UART_FCR_ENABLE_FIFO)
 -                      serial_port_out(port, UART_FCR, UART_FCR_ENABLE_FIFO);
 -              serial_port_out(port, UART_FCR, up->fcr);       /* set fcr */
 +      if (up->port.irq) {
 +              ier = serial_in(up, UART_IER);
 +              serial_out(up, UART_IER, 0);
        }
 -      serial8250_set_mctrl(port, port->mctrl);
 -      spin_unlock_irqrestore(&port->lock, flags);
 -      serial8250_rpm_put(up);
 -
 -      /* Don't rewrite B0 */
 -      if (tty_termios_baud_rate(termios))
 -              tty_termios_encode_baud_rate(termios, baud, baud);
 -}
 -EXPORT_SYMBOL(serial8250_do_set_termios);
  
 -static void
 -serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
 -                     struct ktermios *old)
 -{
 -      if (port->set_termios)
 -              port->set_termios(port, termios, old);
 -      else
 -              serial8250_do_set_termios(port, termios, old);
 -}
 +      iir = serial_in(up, UART_IIR);
  
 -static void
 -serial8250_set_ldisc(struct uart_port *port, struct ktermios *termios)
 -{
 -      if (termios->c_line == N_PPS) {
 -              port->flags |= UPF_HARDPPS_CD;
 -              spin_lock_irq(&port->lock);
 -              serial8250_enable_ms(port);
 -              spin_unlock_irq(&port->lock);
 -      } else {
 -              port->flags &= ~UPF_HARDPPS_CD;
 -              if (!UART_ENABLE_MS(port, termios->c_cflag)) {
 -                      spin_lock_irq(&port->lock);
 -                      serial8250_disable_ms(port);
 -                      spin_unlock_irq(&port->lock);
 -              }
 +      /*
 +       * This should be a safe test for anyone who doesn't trust the
 +       * IIR bits on their UART, but it's specifically designed for
 +       * the "Diva" UART used on the management processor on many HP
 +       * ia64 and parisc boxes.
 +       */
 +      lsr = serial_in(up, UART_LSR);
 +      up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
 +      if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
 +          (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
 +          (lsr & UART_LSR_THRE)) {
 +              iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
 +              iir |= UART_IIR_THRI;
        }
 -}
 -
  
 -void serial8250_do_pm(struct uart_port *port, unsigned int state,
 -                    unsigned int oldstate)
 -{
 -      struct uart_8250_port *p = up_to_u8250p(port);
 -
 -      serial8250_set_sleep(p, state != 0);
 -}
 -EXPORT_SYMBOL(serial8250_do_pm);
 +      if (!(iir & UART_IIR_NO_INT))
 +              serial8250_tx_chars(up);
  
 -static void
 -serial8250_pm(struct uart_port *port, unsigned int state,
 -            unsigned int oldstate)
 -{
 -      if (port->pm)
 -              port->pm(port, state, oldstate);
 -      else
 -              serial8250_do_pm(port, state, oldstate);
 -}
 +      if (up->port.irq)
 +              serial_out(up, UART_IER, ier);
  
 -static unsigned int serial8250_port_size(struct uart_8250_port *pt)
 -{
 -      if (pt->port.mapsize)
 -              return pt->port.mapsize;
 -      if (pt->port.iotype == UPIO_AU) {
 -              if (pt->port.type == PORT_RT2880)
 -                      return 0x100;
 -              return 0x1000;
 -      }
 -      if (is_omap1_8250(pt))
 -              return 0x16 << pt->port.regshift;
 +      spin_unlock_irqrestore(&up->port.lock, flags);
  
 -      return 8 << pt->port.regshift;
 +      /* Standard timer interval plus 0.2s to keep the port running */
 +      mod_timer(&up->timer,
 +              jiffies + uart_poll_timeout(&up->port) + HZ / 5);
  }
  
 -/*
 - * Resource handling.
 - */
 -static int serial8250_request_std_resource(struct uart_8250_port *up)
 +static int univ8250_setup_irq(struct uart_8250_port *up)
  {
 -      unsigned int size = serial8250_port_size(up);
        struct uart_port *port = &up->port;
 -      int ret = 0;
 +      int retval = 0;
  
 -      switch (port->iotype) {
 -      case UPIO_AU:
 -      case UPIO_TSI:
 -      case UPIO_MEM32:
 -      case UPIO_MEM32BE:
 -      case UPIO_MEM:
 -              if (!port->mapbase)
 -                      break;
 +      /*
 +       * The above check will only give an accurate result the first time
 +       * the port is opened so this value needs to be preserved.
 +       */
 +      if (up->bugs & UART_BUG_THRE) {
 +              pr_debug("ttyS%d - using backup timer\n", serial_index(port));
  
 -              if (!request_mem_region(port->mapbase, size, "serial")) {
 -                      ret = -EBUSY;
 -                      break;
 -              }
 +              up->timer.function = serial8250_backup_timeout;
 +              up->timer.data = (unsigned long)up;
 +              mod_timer(&up->timer, jiffies +
 +                        uart_poll_timeout(port) + HZ / 5);
 +      }
  
 -              if (port->flags & UPF_IOREMAP) {
 -                      port->membase = ioremap_nocache(port->mapbase, size);
 -                      if (!port->membase) {
 -                              release_mem_region(port->mapbase, size);
 -                              ret = -ENOMEM;
 -                      }
 -              }
 -              break;
 +      /*
 +       * If the "interrupt" for this port doesn't correspond with any
 +       * hardware interrupt, we use a timer-based system.  The original
 +       * driver used to do this with IRQ0.
 +       */
 +      if (!port->irq) {
 +              up->timer.data = (unsigned long)up;
 +              mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
 +      } else
 +              retval = serial_link_irq_chain(up);
  
 -      case UPIO_HUB6:
 -      case UPIO_PORT:
 -              if (!request_region(port->iobase, size, "serial"))
 -                      ret = -EBUSY;
 -              break;
 -      }
 -      return ret;
 +      return retval;
  }
  
 -static void serial8250_release_std_resource(struct uart_8250_port *up)
 +static void univ8250_release_irq(struct uart_8250_port *up)
  {
 -      unsigned int size = serial8250_port_size(up);
        struct uart_port *port = &up->port;
  
 -      switch (port->iotype) {
 -      case UPIO_AU:
 -      case UPIO_TSI:
 -      case UPIO_MEM32:
 -      case UPIO_MEM32BE:
 -      case UPIO_MEM:
 -              if (!port->mapbase)
 -                      break;
 -
 -              if (port->flags & UPF_IOREMAP) {
 -                      iounmap(port->membase);
 -                      port->membase = NULL;
 -              }
 -
 -              release_mem_region(port->mapbase, size);
 -              break;
 -
 -      case UPIO_HUB6:
 -      case UPIO_PORT:
 -              release_region(port->iobase, size);
 -              break;
 -      }
 +      del_timer_sync(&up->timer);
 +      up->timer.function = serial8250_timeout;
 +      if (port->irq)
 +              serial_unlink_irq_chain(up);
  }
  
  #ifdef CONFIG_SERIAL_8250_RSA
@@@ -396,6 -2848,259 +396,6 @@@ static void serial8250_release_rsa_reso
  }
  #endif
  
 -static void serial8250_release_port(struct uart_port *port)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -
 -      serial8250_release_std_resource(up);
 -}
 -
 -static int serial8250_request_port(struct uart_port *port)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -      int ret;
 -
 -      if (port->type == PORT_8250_CIR)
 -              return -ENODEV;
 -
 -      ret = serial8250_request_std_resource(up);
 -
 -      return ret;
 -}
 -
 -static int fcr_get_rxtrig_bytes(struct uart_8250_port *up)
 -{
 -      const struct serial8250_config *conf_type = &uart_config[up->port.type];
 -      unsigned char bytes;
 -
 -      bytes = conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(up->fcr)];
 -
 -      return bytes ? bytes : -EOPNOTSUPP;
 -}
 -
 -static int bytes_to_fcr_rxtrig(struct uart_8250_port *up, unsigned char bytes)
 -{
 -      const struct serial8250_config *conf_type = &uart_config[up->port.type];
 -      int i;
 -
 -      if (!conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(UART_FCR_R_TRIG_00)])
 -              return -EOPNOTSUPP;
 -
 -      for (i = 1; i < UART_FCR_R_TRIG_MAX_STATE; i++) {
 -              if (bytes < conf_type->rxtrig_bytes[i])
 -                      /* Use the nearest lower value */
 -                      return (--i) << UART_FCR_R_TRIG_SHIFT;
 -      }
 -
 -      return UART_FCR_R_TRIG_11;
 -}
 -
 -static int do_get_rxtrig(struct tty_port *port)
 -{
 -      struct uart_state *state = container_of(port, struct uart_state, port);
 -      struct uart_port *uport = state->uart_port;
 -      struct uart_8250_port *up =
 -              container_of(uport, struct uart_8250_port, port);
 -
 -      if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1)
 -              return -EINVAL;
 -
 -      return fcr_get_rxtrig_bytes(up);
 -}
 -
 -static int do_serial8250_get_rxtrig(struct tty_port *port)
 -{
 -      int rxtrig_bytes;
 -
 -      mutex_lock(&port->mutex);
 -      rxtrig_bytes = do_get_rxtrig(port);
 -      mutex_unlock(&port->mutex);
 -
 -      return rxtrig_bytes;
 -}
 -
 -static ssize_t serial8250_get_attr_rx_trig_bytes(struct device *dev,
 -      struct device_attribute *attr, char *buf)
 -{
 -      struct tty_port *port = dev_get_drvdata(dev);
 -      int rxtrig_bytes;
 -
 -      rxtrig_bytes = do_serial8250_get_rxtrig(port);
 -      if (rxtrig_bytes < 0)
 -              return rxtrig_bytes;
 -
 -      return snprintf(buf, PAGE_SIZE, "%d\n", rxtrig_bytes);
 -}
 -
 -static int do_set_rxtrig(struct tty_port *port, unsigned char bytes)
 -{
 -      struct uart_state *state = container_of(port, struct uart_state, port);
 -      struct uart_port *uport = state->uart_port;
 -      struct uart_8250_port *up =
 -              container_of(uport, struct uart_8250_port, port);
 -      int rxtrig;
 -
 -      if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1 ||
 -          up->fifo_bug)
 -              return -EINVAL;
 -
 -      rxtrig = bytes_to_fcr_rxtrig(up, bytes);
 -      if (rxtrig < 0)
 -              return rxtrig;
 -
 -      serial8250_clear_fifos(up);
 -      up->fcr &= ~UART_FCR_TRIGGER_MASK;
 -      up->fcr |= (unsigned char)rxtrig;
 -      serial_out(up, UART_FCR, up->fcr);
 -      return 0;
 -}
 -
 -static int do_serial8250_set_rxtrig(struct tty_port *port, unsigned char bytes)
 -{
 -      int ret;
 -
 -      mutex_lock(&port->mutex);
 -      ret = do_set_rxtrig(port, bytes);
 -      mutex_unlock(&port->mutex);
 -
 -      return ret;
 -}
 -
 -static ssize_t serial8250_set_attr_rx_trig_bytes(struct device *dev,
 -      struct device_attribute *attr, const char *buf, size_t count)
 -{
 -      struct tty_port *port = dev_get_drvdata(dev);
 -      unsigned char bytes;
 -      int ret;
 -
 -      if (!count)
 -              return -EINVAL;
 -
 -      ret = kstrtou8(buf, 10, &bytes);
 -      if (ret < 0)
 -              return ret;
 -
 -      ret = do_serial8250_set_rxtrig(port, bytes);
 -      if (ret < 0)
 -              return ret;
 -
 -      return count;
 -}
 -
 -static DEVICE_ATTR(rx_trig_bytes, S_IRUSR | S_IWUSR | S_IRGRP,
 -                 serial8250_get_attr_rx_trig_bytes,
 -                 serial8250_set_attr_rx_trig_bytes);
 -
 -static struct attribute *serial8250_dev_attrs[] = {
 -      &dev_attr_rx_trig_bytes.attr,
 -      NULL,
 -      };
 -
 -static struct attribute_group serial8250_dev_attr_group = {
 -      .attrs = serial8250_dev_attrs,
 -      };
 -
 -static void register_dev_spec_attr_grp(struct uart_8250_port *up)
 -{
 -      const struct serial8250_config *conf_type = &uart_config[up->port.type];
 -
 -      if (conf_type->rxtrig_bytes[0])
 -              up->port.attr_group = &serial8250_dev_attr_group;
 -}
 -
 -static void serial8250_config_port(struct uart_port *port, int flags)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -      int ret;
 -
 -      if (port->type == PORT_8250_CIR)
 -              return;
 -
 -      /*
 -       * Find the region that we can probe for.  This in turn
 -       * tells us whether we can probe for the type of port.
 -       */
 -      ret = serial8250_request_std_resource(up);
 -      if (ret < 0)
 -              return;
 -
 -      if (port->iotype != up->cur_iotype)
 -              set_io_from_upio(port);
 -
 -      if (flags & UART_CONFIG_TYPE)
 -              autoconfig(up);
 -
 -      /* if access method is AU, it is a 16550 with a quirk */
 -      if (port->type == PORT_16550A && port->iotype == UPIO_AU)
 -              up->bugs |= UART_BUG_NOMSR;
 -
 -      /* HW bugs may trigger IRQ while IIR == NO_INT */
 -      if (port->type == PORT_TEGRA)
 -              up->bugs |= UART_BUG_NOMSR;
 -
 -      if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
 -              autoconfig_irq(up);
 -
 -      if (port->type == PORT_UNKNOWN)
 -              serial8250_release_std_resource(up);
 -
 -      /* Fixme: probably not the best place for this */
 -      if ((port->type == PORT_XR17V35X) ||
 -         (port->type == PORT_XR17D15X))
 -              port->handle_irq = exar_handle_irq;
 -
 -      register_dev_spec_attr_grp(up);
 -      up->fcr = uart_config[up->port.type].fcr;
 -}
 -
 -static int
 -serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
 -{
 -      if (ser->irq >= nr_irqs || ser->irq < 0 ||
 -          ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
 -          ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS ||
 -          ser->type == PORT_STARTECH)
 -              return -EINVAL;
 -      return 0;
 -}
 -
 -static const char *
 -serial8250_type(struct uart_port *port)
 -{
 -      int type = port->type;
 -
 -      if (type >= ARRAY_SIZE(uart_config))
 -              type = 0;
 -      return uart_config[type].name;
 -}
 -
 -static const struct uart_ops serial8250_pops = {
 -      .tx_empty       = serial8250_tx_empty,
 -      .set_mctrl      = serial8250_set_mctrl,
 -      .get_mctrl      = serial8250_get_mctrl,
 -      .stop_tx        = serial8250_stop_tx,
 -      .start_tx       = serial8250_start_tx,
 -      .throttle       = serial8250_throttle,
 -      .unthrottle     = serial8250_unthrottle,
 -      .stop_rx        = serial8250_stop_rx,
 -      .enable_ms      = serial8250_enable_ms,
 -      .break_ctl      = serial8250_break_ctl,
 -      .startup        = serial8250_startup,
 -      .shutdown       = serial8250_shutdown,
 -      .set_termios    = serial8250_set_termios,
 -      .set_ldisc      = serial8250_set_ldisc,
 -      .pm             = serial8250_pm,
 -      .type           = serial8250_type,
 -      .release_port   = serial8250_release_port,
 -      .request_port   = serial8250_request_port,
 -      .config_port    = serial8250_config_port,
 -      .verify_port    = serial8250_verify_port,
 -#ifdef CONFIG_CONSOLE_POLL
 -      .poll_get_char = serial8250_get_poll_char,
 -      .poll_put_char = serial8250_put_poll_char,
 -#endif
 -};
 -
  static const struct uart_ops *base_ops;
  static struct uart_ops univ8250_port_ops;
  
@@@ -434,6 -3139,42 +434,6 @@@ void serial8250_set_isa_configurator
  }
  EXPORT_SYMBOL(serial8250_set_isa_configurator);
  
 -static void serial8250_init_port(struct uart_8250_port *up)
 -{
 -      struct uart_port *port = &up->port;
 -
 -      spin_lock_init(&port->lock);
 -      port->ops = &serial8250_pops;
 -
 -      up->cur_iotype = 0xFF;
 -}
 -
 -static void serial8250_set_defaults(struct uart_8250_port *up)
 -{
 -      struct uart_port *port = &up->port;
 -
 -      if (up->port.flags & UPF_FIXED_TYPE) {
 -              unsigned int type = up->port.type;
 -
 -              if (!up->port.fifosize)
 -                      up->port.fifosize = uart_config[type].fifo_size;
 -              if (!up->tx_loadsz)
 -                      up->tx_loadsz = uart_config[type].tx_loadsz;
 -              if (!up->capabilities)
 -                      up->capabilities = uart_config[type].flags;
 -      }
 -
 -      set_io_from_upio(port);
 -
 -      /* default dma handlers */
 -      if (up->dma) {
 -              if (!up->dma->tx_dma)
 -                      up->dma->tx_dma = serial8250_tx_dma;
 -              if (!up->dma->rx_dma)
 -                      up->dma->rx_dma = serial8250_rx_dma;
 -      }
 -}
 -
  #ifdef CONFIG_SERIAL_8250_RSA
  
  static void univ8250_config_port(struct uart_port *port, int flags)
@@@ -583,6 -3324,94 +583,6 @@@ serial8250_register_ports(struct uart_d
  
  #ifdef CONFIG_SERIAL_8250_CONSOLE
  
 -static void serial8250_console_putchar(struct uart_port *port, int ch)
 -{
 -      struct uart_8250_port *up = up_to_u8250p(port);
 -
 -      wait_for_xmitr(up, UART_LSR_THRE);
 -      serial_port_out(port, UART_TX, ch);
 -}
 -
 -/*
 - *    Print a string to the serial port trying not to disturb
 - *    any possible real use of the port...
 - *
 - *    The console_lock must be held when we get here.
 - */
 -static void serial8250_console_write(struct uart_8250_port *up, const char *s,
 -                                   unsigned int count)
 -{
 -      struct uart_port *port = &up->port;
 -      unsigned long flags;
 -      unsigned int ier;
 -      int locked = 1;
 -
 -      touch_nmi_watchdog();
 -
 -      serial8250_rpm_get(up);
 -
 -      if (port->sysrq)
 -              locked = 0;
 -      else if (oops_in_progress)
 -              locked = spin_trylock_irqsave(&port->lock, flags);
 -      else
 -              spin_lock_irqsave(&port->lock, flags);
 -
 -      /*
 -       *      First save the IER then disable the interrupts
 -       */
 -      ier = serial_port_in(port, UART_IER);
 -
 -      if (up->capabilities & UART_CAP_UUE)
 -              serial_port_out(port, UART_IER, UART_IER_UUE);
 -      else
 -              serial_port_out(port, UART_IER, 0);
 -
 -      /* check scratch reg to see if port powered off during system sleep */
 -      if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) {
 -              struct ktermios termios;
 -              unsigned int baud, quot, frac = 0;
 -
 -              termios.c_cflag = port->cons->cflag;
 -              if (port->state->port.tty && termios.c_cflag == 0)
 -                      termios.c_cflag = port->state->port.tty->termios.c_cflag;
 -
 -              baud = uart_get_baud_rate(port, &termios, NULL,
 -                                        port->uartclk / 16 / 0xffff,
 -                                        port->uartclk / 16);
 -              quot = serial8250_get_divisor(up, baud, &frac);
 -
 -              serial8250_set_divisor(port, baud, quot, frac);
 -              serial_port_out(port, UART_LCR, up->lcr);
 -              serial_port_out(port, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
 -
 -              up->canary = 0;
 -      }
 -
 -      uart_console_write(port, s, count, serial8250_console_putchar);
 -
 -      /*
 -       *      Finally, wait for transmitter to become empty
 -       *      and restore the IER
 -       */
 -      wait_for_xmitr(up, BOTH_EMPTY);
 -      serial_port_out(port, UART_IER, ier);
 -
 -      /*
 -       *      The receive handling will happen properly because the
 -       *      receive ready bit will still be set; it is not cleared
 -       *      on read.  However, modem control will not, we must
 -       *      call it if we have saved something in the saved flags
 -       *      while processing with interrupts off.
 -       */
 -      if (up->msr_saved_flags)
 -              serial8250_modem_status(up);
 -
 -      if (locked)
 -              spin_unlock_irqrestore(&port->lock, flags);
 -      serial8250_rpm_put(up);
 -}
 -
  static void univ8250_console_write(struct console *co, const char *s,
                                   unsigned int count)
  {
        serial8250_console_write(up, s, count);
  }
  
 -static unsigned int probe_baud(struct uart_port *port)
 -{
 -      unsigned char lcr, dll, dlm;
 -      unsigned int quot;
 -
 -      lcr = serial_port_in(port, UART_LCR);
 -      serial_port_out(port, UART_LCR, lcr | UART_LCR_DLAB);
 -      dll = serial_port_in(port, UART_DLL);
 -      dlm = serial_port_in(port, UART_DLM);
 -      serial_port_out(port, UART_LCR, lcr);
 -
 -      quot = (dlm << 8) | dll;
 -      return (port->uartclk / 16) / quot;
 -}
 -
 -static int serial8250_console_setup(struct uart_port *port, char *options, bool probe)
 -{
 -      int baud = 9600;
 -      int bits = 8;
 -      int parity = 'n';
 -      int flow = 'n';
 -
 -      if (!port->iobase && !port->membase)
 -              return -ENODEV;
 -
 -      if (options)
 -              uart_parse_options(options, &baud, &parity, &bits, &flow);
 -      else if (probe)
 -              baud = probe_baud(port);
 -
 -      return uart_set_options(port, port->cons, baud, parity, bits, flow);
 -}
 -
  static int univ8250_console_setup(struct console *co, char *options)
  {
        struct uart_port *port;
diff --combined fs/block_dev.c
@@@ -441,7 -441,7 +441,7 @@@ EXPORT_SYMBOL_GPL(bdev_write_page)
   * accessible at this address.
   */
  long bdev_direct_access(struct block_device *bdev, sector_t sector,
-                       void **addr, unsigned long *pfn, long size)
+                       void __pmem **addr, unsigned long *pfn, long size)
  {
        long avail;
        const struct block_device_operations *ops = bdev->bd_disk->fops;
        sector += get_start_sect(bdev);
        if (sector % (PAGE_SIZE / 512))
                return -EINVAL;
-       avail = ops->direct_access(bdev, sector, addr, pfn, size);
+       avail = ops->direct_access(bdev, sector, addr, pfn);
        if (!avail)
                return -ERANGE;
        return min(avail, size);
@@@ -1769,7 -1769,7 +1769,7 @@@ void iterate_bdevs(void (*func)(struct 
  {
        struct inode *inode, *old_inode = NULL;
  
 -      spin_lock(&inode_sb_list_lock);
 +      spin_lock(&blockdev_superblock->s_inode_list_lock);
        list_for_each_entry(inode, &blockdev_superblock->s_inodes, i_sb_list) {
                struct address_space *mapping = inode->i_mapping;
  
                }
                __iget(inode);
                spin_unlock(&inode->i_lock);
 -              spin_unlock(&inode_sb_list_lock);
 +              spin_unlock(&blockdev_superblock->s_inode_list_lock);
                /*
                 * We hold a reference to 'inode' so it couldn't have been
                 * removed from s_inodes list while we dropped the
 -               * inode_sb_list_lock.  We cannot iput the inode now as we can
 +               * s_inode_list_lock  We cannot iput the inode now as we can
                 * be holding the last reference and we cannot iput it under
 -               * inode_sb_list_lock. So we keep the reference and iput it
 +               * s_inode_list_lock. So we keep the reference and iput it
                 * later.
                 */
                iput(old_inode);
  
                func(I_BDEV(inode), arg);
  
 -              spin_lock(&inode_sb_list_lock);
 +              spin_lock(&blockdev_superblock->s_inode_list_lock);
        }
 -      spin_unlock(&inode_sb_list_lock);
 +      spin_unlock(&blockdev_superblock->s_inode_list_lock);
        iput(old_inode);
  }
diff --combined fs/dax.c
+++ b/fs/dax.c
@@@ -23,6 -23,7 +23,7 @@@
  #include <linux/memcontrol.h>
  #include <linux/mm.h>
  #include <linux/mutex.h>
+ #include <linux/pmem.h>
  #include <linux/sched.h>
  #include <linux/uio.h>
  #include <linux/vmstat.h>
@@@ -34,7 -35,7 +35,7 @@@ int dax_clear_blocks(struct inode *inod
  
        might_sleep();
        do {
-               void *addr;
+               void __pmem *addr;
                unsigned long pfn;
                long count;
  
                        unsigned pgsz = PAGE_SIZE - offset_in_page(addr);
                        if (pgsz > count)
                                pgsz = count;
-                       if (pgsz < PAGE_SIZE)
-                               memset(addr, 0, pgsz);
-                       else
-                               clear_page(addr);
+                       clear_pmem(addr, pgsz);
                        addr += pgsz;
                        size -= pgsz;
                        count -= pgsz;
                }
        } while (size);
  
+       wmb_pmem();
        return 0;
  }
  EXPORT_SYMBOL_GPL(dax_clear_blocks);
  
- static long dax_get_addr(struct buffer_head *bh, void **addr, unsigned blkbits)
+ static long dax_get_addr(struct buffer_head *bh, void __pmem **addr,
+               unsigned blkbits)
  {
        unsigned long pfn;
        sector_t sector = bh->b_blocknr << (blkbits - 9);
        return bdev_direct_access(bh->b_bdev, sector, addr, &pfn, bh->b_size);
  }
  
- static void dax_new_buf(void *addr, unsigned size, unsigned first, loff_t pos,
-                       loff_t end)
+ /* the clear_pmem() calls are ordered by a wmb_pmem() in the caller */
+ static void dax_new_buf(void __pmem *addr, unsigned size, unsigned first,
+               loff_t pos, loff_t end)
  {
        loff_t final = end - pos + first; /* The final byte of the buffer */
  
        if (first > 0)
-               memset(addr, 0, first);
+               clear_pmem(addr, first);
        if (final < size)
-               memset(addr + final, 0, size - final);
+               clear_pmem(addr + final, size - final);
  }
  
  static bool buffer_written(struct buffer_head *bh)
@@@ -106,14 -107,15 +107,15 @@@ static ssize_t dax_io(struct inode *ino
        loff_t pos = start;
        loff_t max = start;
        loff_t bh_max = start;
-       void *addr;
+       void __pmem *addr;
        bool hole = false;
+       bool need_wmb = false;
  
        if (iov_iter_rw(iter) != WRITE)
                end = min(end, i_size_read(inode));
  
        while (pos < end) {
-               unsigned len;
+               size_t len;
                if (pos == max) {
                        unsigned blkbits = inode->i_blkbits;
                        sector_t block = pos >> blkbits;
                                retval = dax_get_addr(bh, &addr, blkbits);
                                if (retval < 0)
                                        break;
-                               if (buffer_unwritten(bh) || buffer_new(bh))
+                               if (buffer_unwritten(bh) || buffer_new(bh)) {
                                        dax_new_buf(addr, retval, first, pos,
                                                                        end);
+                                       need_wmb = true;
+                               }
                                addr += first;
                                size = retval - first;
                        }
                        max = min(pos + size, end);
                }
  
-               if (iov_iter_rw(iter) == WRITE)
-                       len = copy_from_iter_nocache(addr, max - pos, iter);
-               else if (!hole)
-                       len = copy_to_iter(addr, max - pos, iter);
+               if (iov_iter_rw(iter) == WRITE) {
+                       len = copy_from_iter_pmem(addr, max - pos, iter);
+                       need_wmb = true;
+               } else if (!hole)
+                       len = copy_to_iter((void __force *)addr, max - pos,
+                                       iter);
                else
                        len = iov_iter_zero(max - pos, iter);
  
                addr += len;
        }
  
+       if (need_wmb)
+               wmb_pmem();
        return (pos == start) ? retval : pos - start;
  }
  
@@@ -260,11 -269,13 +269,13 @@@ static int dax_load_hole(struct address
  static int copy_user_bh(struct page *to, struct buffer_head *bh,
                        unsigned blkbits, unsigned long vaddr)
  {
-       void *vfrom, *vto;
+       void __pmem *vfrom;
+       void *vto;
        if (dax_get_addr(bh, &vfrom, blkbits) < 0)
                return -EIO;
        vto = kmap_atomic(to);
-       copy_user_page(vto, vfrom, vaddr, to);
+       copy_user_page(vto, (void __force *)vfrom, vaddr, to);
        kunmap_atomic(vto);
        return 0;
  }
@@@ -275,7 -286,7 +286,7 @@@ static int dax_insert_mapping(struct in
        struct address_space *mapping = inode->i_mapping;
        sector_t sector = bh->b_blocknr << (inode->i_blkbits - 9);
        unsigned long vaddr = (unsigned long)vmf->virtual_address;
-       void *addr;
+       void __pmem *addr;
        unsigned long pfn;
        pgoff_t size;
        int error;
                goto out;
        }
  
-       if (buffer_unwritten(bh) || buffer_new(bh))
-               clear_page(addr);
+       if (buffer_unwritten(bh) || buffer_new(bh)) {
+               clear_pmem(addr, PAGE_SIZE);
+               wmb_pmem();
+       }
  
        error = vm_insert_mixed(vma, vaddr, pfn);
  
   * @vma: The virtual memory area where the fault occurred
   * @vmf: The description of the fault
   * @get_block: The filesystem method used to translate file offsets to blocks
 + * @complete_unwritten: The filesystem method used to convert unwritten blocks
 + *    to written so the data written to them is exposed. This is required for
 + *    required by write faults for filesystems that will return unwritten
 + *    extent mappings from @get_block, but it is optional for reads as
 + *    dax_insert_mapping() will always zero unwritten blocks. If the fs does
 + *    not support unwritten extents, the it should pass NULL.
   *
   * When a page fault occurs, filesystems may call this helper in their
   * fault handler for DAX files. __dax_fault() assumes the caller has done all
@@@ -443,12 -450,8 +456,12 @@@ int __dax_fault(struct vm_area_struct *
         * as for normal BH based IO completions.
         */
        error = dax_insert_mapping(inode, &bh, vma, vmf);
 -      if (buffer_unwritten(&bh))
 -              complete_unwritten(&bh, !error);
 +      if (buffer_unwritten(&bh)) {
 +              if (complete_unwritten)
 +                      complete_unwritten(&bh, !error);
 +              else
 +                      WARN_ON_ONCE(!(vmf->flags & FAULT_FLAG_WRITE));
 +      }
  
   out:
        if (error == -ENOMEM)
@@@ -548,11 -551,12 +561,12 @@@ int dax_zero_page_range(struct inode *i
        if (err < 0)
                return err;
        if (buffer_written(&bh)) {
-               void *addr;
+               void __pmem *addr;
                err = dax_get_addr(&bh, &addr, inode->i_blkbits);
                if (err < 0)
                        return err;
-               memset(addr + offset, 0, length);
+               clear_pmem(addr + offset, length);
+               wmb_pmem();
        }
  
        return 0;
diff --combined include/linux/blkdev.h
@@@ -213,6 -213,14 +213,6 @@@ typedef int (prep_rq_fn) (struct reques
  typedef void (unprep_rq_fn) (struct request_queue *, struct request *);
  
  struct bio_vec;
 -struct bvec_merge_data {
 -      struct block_device *bi_bdev;
 -      sector_t bi_sector;
 -      unsigned bi_size;
 -      unsigned long bi_rw;
 -};
 -typedef int (merge_bvec_fn) (struct request_queue *, struct bvec_merge_data *,
 -                           struct bio_vec *);
  typedef void (softirq_done_fn)(struct request *);
  typedef int (dma_drain_needed_fn)(struct request *);
  typedef int (lld_busy_fn) (struct request_queue *q);
@@@ -250,7 -258,6 +250,7 @@@ struct blk_queue_tag 
  struct queue_limits {
        unsigned long           bounce_pfn;
        unsigned long           seg_boundary_mask;
 +      unsigned long           virt_boundary_mask;
  
        unsigned int            max_hw_sectors;
        unsigned int            chunk_sectors;
        unsigned int            io_min;
        unsigned int            io_opt;
        unsigned int            max_discard_sectors;
 +      unsigned int            max_hw_discard_sectors;
        unsigned int            max_write_same_sectors;
        unsigned int            discard_granularity;
        unsigned int            discard_alignment;
@@@ -299,6 -305,7 +299,6 @@@ struct request_queue 
        make_request_fn         *make_request_fn;
        prep_rq_fn              *prep_rq_fn;
        unprep_rq_fn            *unprep_rq_fn;
 -      merge_bvec_fn           *merge_bvec_fn;
        softirq_done_fn         *softirq_done_fn;
        rq_timed_out_fn         *rq_timed_out_fn;
        dma_drain_needed_fn     *dma_drain_needed;
  
        struct blk_mq_tag_set   *tag_set;
        struct list_head        tag_set_list;
 +      struct bio_set          *bio_split;
  };
  
  #define QUEUE_FLAG_QUEUED     1       /* uses generic tag queueing */
  #define QUEUE_FLAG_DEAD        19     /* queue tear-down finished */
  #define QUEUE_FLAG_INIT_DONE   20     /* queue is initialized */
  #define QUEUE_FLAG_NO_SG_MERGE 21     /* don't attempt to merge SG segments*/
 -#define QUEUE_FLAG_SG_GAPS     22     /* queue doesn't support SG gaps */
  
  #define QUEUE_FLAG_DEFAULT    ((1 << QUEUE_FLAG_IO_STAT) |            \
                                 (1 << QUEUE_FLAG_STACKABLE)    |       \
@@@ -775,8 -782,6 +775,8 @@@ extern void blk_rq_unprep_clone(struct 
  extern int blk_insert_cloned_request(struct request_queue *q,
                                     struct request *rq);
  extern void blk_delay_queue(struct request_queue *, unsigned long);
 +extern void blk_queue_split(struct request_queue *, struct bio **,
 +                          struct bio_set *);
  extern void blk_recount_segments(struct request_queue *, struct bio *);
  extern int scsi_verify_blk_ioctl(struct block_device *, unsigned int);
  extern int scsi_cmd_blk_ioctl(struct block_device *, fmode_t,
@@@ -981,9 -986,9 +981,9 @@@ extern int blk_queue_dma_drain(struct r
                               void *buf, unsigned int size);
  extern void blk_queue_lld_busy(struct request_queue *q, lld_busy_fn *fn);
  extern void blk_queue_segment_boundary(struct request_queue *, unsigned long);
 +extern void blk_queue_virt_boundary(struct request_queue *, unsigned long);
  extern void blk_queue_prep_rq(struct request_queue *, prep_rq_fn *pfn);
  extern void blk_queue_unprep_rq(struct request_queue *, unprep_rq_fn *ufn);
 -extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *);
  extern void blk_queue_dma_alignment(struct request_queue *, int);
  extern void blk_queue_update_dma_alignment(struct request_queue *, int);
  extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *);
@@@ -1133,7 -1138,6 +1133,7 @@@ extern int blk_verify_command(unsigned 
  enum blk_default_limits {
        BLK_MAX_SEGMENTS        = 128,
        BLK_SAFE_MAX_SECTORS    = 255,
 +      BLK_DEF_MAX_SECTORS     = 2560,
        BLK_MAX_SEGMENT_SIZE    = 65536,
        BLK_SEG_BOUNDARY_MASK   = 0xFFFFFFFFUL,
  };
@@@ -1150,11 -1154,6 +1150,11 @@@ static inline unsigned long queue_segme
        return q->limits.seg_boundary_mask;
  }
  
 +static inline unsigned long queue_virt_boundary(struct request_queue *q)
 +{
 +      return q->limits.virt_boundary_mask;
 +}
 +
  static inline unsigned int queue_max_sectors(struct request_queue *q)
  {
        return q->limits.max_sectors;
@@@ -1355,19 -1354,6 +1355,19 @@@ static inline void put_dev_sector(Secto
        page_cache_release(p.v);
  }
  
 +/*
 + * Check if adding a bio_vec after bprv with offset would create a gap in
 + * the SG list. Most drivers don't care about this, but some do.
 + */
 +static inline bool bvec_gap_to_prev(struct request_queue *q,
 +                              struct bio_vec *bprv, unsigned int offset)
 +{
 +      if (!queue_virt_boundary(q))
 +              return false;
 +      return offset ||
 +              ((bprv->bv_offset + bprv->bv_len) & queue_virt_boundary(q));
 +}
 +
  struct work_struct;
  int kblockd_schedule_work(struct work_struct *work);
  int kblockd_schedule_delayed_work(struct delayed_work *dwork, unsigned long delay);
@@@ -1569,8 -1555,8 +1569,8 @@@ struct block_device_operations 
        int (*rw_page)(struct block_device *, sector_t, struct page *, int rw);
        int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
        int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
-       long (*direct_access)(struct block_device *, sector_t,
-                                       void **, unsigned long *pfn, long size);
+       long (*direct_access)(struct block_device *, sector_t, void __pmem **,
+                       unsigned long *pfn);
        unsigned int (*check_events) (struct gendisk *disk,
                                      unsigned int clearing);
        /* ->media_changed() is DEPRECATED, use ->check_events() instead */
@@@ -1588,8 -1574,8 +1588,8 @@@ extern int __blkdev_driver_ioctl(struc
  extern int bdev_read_page(struct block_device *, sector_t, struct page *);
  extern int bdev_write_page(struct block_device *, sector_t, struct page *,
                                                struct writeback_control *);
- extern long bdev_direct_access(struct block_device *, sector_t, void **addr,
-                                               unsigned long *pfn, long size);
+ extern long bdev_direct_access(struct block_device *, sector_t,
+               void __pmem **addr, unsigned long *pfn, long size);
  #else /* CONFIG_BLOCK */
  
  struct block_device;
diff --combined include/linux/mm.h
@@@ -124,10 -124,8 +124,10 @@@ extern unsigned int kobjsize(const voi
  #define VM_MAYSHARE   0x00000080
  
  #define VM_GROWSDOWN  0x00000100      /* general info on the segment */
 +#define VM_UFFD_MISSING       0x00000200      /* missing pages tracking */
  #define VM_PFNMAP     0x00000400      /* Page-ranges managed without "struct page", just pure PFN */
  #define VM_DENYWRITE  0x00000800      /* ETXTBSY on write attempts.. */
 +#define VM_UFFD_WP    0x00001000      /* wrprotect pages tracking */
  
  #define VM_LOCKED     0x00002000
  #define VM_IO           0x00004000    /* Memory mapped I/O or similar */
@@@ -247,7 -245,6 +247,7 @@@ struct vm_fault 
  struct vm_operations_struct {
        void (*open)(struct vm_area_struct * area);
        void (*close)(struct vm_area_struct * area);
 +      int (*mremap)(struct vm_area_struct * area);
        int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf);
        void (*map_pages)(struct vm_area_struct *vma, struct vm_fault *vmf);
  
@@@ -372,7 -369,14 +372,14 @@@ static inline int put_page_unless_one(s
  }
  
  extern int page_is_ram(unsigned long pfn);
- extern int region_is_ram(resource_size_t phys_addr, unsigned long size);
+ enum {
+       REGION_INTERSECTS,
+       REGION_DISJOINT,
+       REGION_MIXED,
+ };
+ int region_intersects(resource_size_t offset, size_t size, const char *type);
  
  /* Support for virtually mapped pages */
  struct page *vmalloc_to_page(const void *addr);
@@@ -1005,34 -1009,6 +1012,34 @@@ static inline int page_mapped(struct pa
        return atomic_read(&(page)->_mapcount) >= 0;
  }
  
 +/*
 + * Return true only if the page has been allocated with
 + * ALLOC_NO_WATERMARKS and the low watermark was not
 + * met implying that the system is under some pressure.
 + */
 +static inline bool page_is_pfmemalloc(struct page *page)
 +{
 +      /*
 +       * Page index cannot be this large so this must be
 +       * a pfmemalloc page.
 +       */
 +      return page->index == -1UL;
 +}
 +
 +/*
 + * Only to be called by the page allocator on a freshly allocated
 + * page.
 + */
 +static inline void set_page_pfmemalloc(struct page *page)
 +{
 +      page->index = -1UL;
 +}
 +
 +static inline void clear_page_pfmemalloc(struct page *page)
 +{
 +      page->index = 0;
 +}
 +
  /*
   * Different kinds of faults, as returned by handle_mm_fault().
   * Used to decide whether a process gets delivered SIGBUS or
@@@ -1836,7 -1812,7 +1843,7 @@@ extern int vma_adjust(struct vm_area_st
  extern struct vm_area_struct *vma_merge(struct mm_struct *,
        struct vm_area_struct *prev, unsigned long addr, unsigned long end,
        unsigned long vm_flags, struct anon_vma *, struct file *, pgoff_t,
 -      struct mempolicy *);
 +      struct mempolicy *, struct vm_userfaultfd_ctx);
  extern struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *);
  extern int split_vma(struct mm_struct *,
        struct vm_area_struct *, unsigned long addr, int new_below);
diff --combined include/linux/mmzone.h
@@@ -319,7 -319,11 +319,11 @@@ enum zone_type 
        ZONE_HIGHMEM,
  #endif
        ZONE_MOVABLE,
+ #ifdef CONFIG_ZONE_DEVICE
+       ZONE_DEVICE,
+ #endif
        __MAX_NR_ZONES
  };
  
  #ifndef __GENERATING_BOUNDS_H
@@@ -690,6 -694,14 +694,6 @@@ struct zonelist 
  #endif
  };
  
 -#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
 -struct node_active_region {
 -      unsigned long start_pfn;
 -      unsigned long end_pfn;
 -      int nid;
 -};
 -#endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */
 -
  #ifndef CONFIG_DISCONTIGMEM
  /* The array of struct pages - for discontigmem use pgdat->lmem_map */
  extern struct page *mem_map;
@@@ -786,6 -798,25 +790,25 @@@ static inline bool pgdat_is_empty(pg_da
        return !pgdat->node_start_pfn && !pgdat->node_spanned_pages;
  }
  
+ static inline int zone_id(const struct zone *zone)
+ {
+       struct pglist_data *pgdat = zone->zone_pgdat;
+       return zone - pgdat->node_zones;
+ }
+ #ifdef CONFIG_ZONE_DEVICE
+ static inline bool is_dev_zone(const struct zone *zone)
+ {
+       return zone_id(zone) == ZONE_DEVICE;
+ }
+ #else
+ static inline bool is_dev_zone(const struct zone *zone)
+ {
+       return false;
+ }
+ #endif
  #include <linux/memory_hotplug.h>
  
  extern struct mutex zonelists_mutex;
diff --combined kernel/Makefile
@@@ -45,6 -45,7 +45,6 @@@ ifneq ($(CONFIG_SMP),y
  obj-y += up.o
  endif
  obj-$(CONFIG_UID16) += uid16.o
 -obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o
  obj-$(CONFIG_MODULES) += module.o
  obj-$(CONFIG_MODULE_SIG) += module_signing.o
  obj-$(CONFIG_KALLSYMS) += kallsyms.o
@@@ -54,7 -55,6 +54,7 @@@ obj-$(CONFIG_BACKTRACE_SELF_TEST) += ba
  obj-$(CONFIG_COMPAT) += compat.o
  obj-$(CONFIG_CGROUPS) += cgroup.o
  obj-$(CONFIG_CGROUP_FREEZER) += cgroup_freezer.o
 +obj-$(CONFIG_CGROUP_PIDS) += cgroup_pids.o
  obj-$(CONFIG_CPUSETS) += cpuset.o
  obj-$(CONFIG_UTS_NS) += utsname.o
  obj-$(CONFIG_USER_NS) += user_namespace.o
@@@ -64,7 -64,7 +64,7 @@@ obj-$(CONFIG_SMP) += stop_machine.
  obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o
  obj-$(CONFIG_AUDIT) += audit.o auditfilter.o
  obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
 -obj-$(CONFIG_AUDIT_WATCH) += audit_watch.o
 +obj-$(CONFIG_AUDIT_WATCH) += audit_watch.o audit_fsnotify.o
  obj-$(CONFIG_AUDIT_TREE) += audit_tree.o
  obj-$(CONFIG_GCOV_KERNEL) += gcov/
  obj-$(CONFIG_KPROBES) += kprobes.o
@@@ -99,6 -99,8 +99,8 @@@ obj-$(CONFIG_JUMP_LABEL) += jump_label.
  obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
  obj-$(CONFIG_TORTURE_TEST) += torture.o
  
+ obj-$(CONFIG_HAS_IOMEM) += memremap.o
  $(obj)/configs.o: $(obj)/config_data.h
  
  # config_data.h contains the same information as ikconfig.h but gzipped.
@@@ -111,3 -113,99 +113,3 @@@ $(obj)/config_data.gz: $(KCONFIG_CONFIG
  targets += config_data.h
  $(obj)/config_data.h: $(obj)/config_data.gz FORCE
        $(call filechk,ikconfiggz)
 -
 -###############################################################################
 -#
 -# Roll all the X.509 certificates that we can find together and pull them into
 -# the kernel so that they get loaded into the system trusted keyring during
 -# boot.
 -#
 -# We look in the source root and the build root for all files whose name ends
 -# in ".x509".  Unfortunately, this will generate duplicate filenames, so we
 -# have make canonicalise the pathnames and then sort them to discard the
 -# duplicates.
 -#
 -###############################################################################
 -ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y)
 -X509_CERTIFICATES-y := $(wildcard *.x509) $(wildcard $(srctree)/*.x509)
 -X509_CERTIFICATES-$(CONFIG_MODULE_SIG) += $(objtree)/signing_key.x509
 -X509_CERTIFICATES-raw := $(sort $(foreach CERT,$(X509_CERTIFICATES-y), \
 -                              $(or $(realpath $(CERT)),$(CERT))))
 -X509_CERTIFICATES := $(subst $(realpath $(objtree))/,,$(X509_CERTIFICATES-raw))
 -
 -ifeq ($(X509_CERTIFICATES),)
 -$(warning *** No X.509 certificates found ***)
 -endif
 -
 -ifneq ($(wildcard $(obj)/.x509.list),)
 -ifneq ($(shell cat $(obj)/.x509.list),$(X509_CERTIFICATES))
 -$(warning X.509 certificate list changed to "$(X509_CERTIFICATES)" from "$(shell cat $(obj)/.x509.list)")
 -$(shell rm $(obj)/.x509.list)
 -endif
 -endif
 -
 -kernel/system_certificates.o: $(obj)/x509_certificate_list
 -
 -quiet_cmd_x509certs  = CERTS   $@
 -      cmd_x509certs  = cat $(X509_CERTIFICATES) /dev/null >$@ $(foreach X509,$(X509_CERTIFICATES),; $(kecho) "  - Including cert $(X509)")
 -
 -targets += $(obj)/x509_certificate_list
 -$(obj)/x509_certificate_list: $(X509_CERTIFICATES) $(obj)/.x509.list
 -      $(call if_changed,x509certs)
 -
 -targets += $(obj)/.x509.list
 -$(obj)/.x509.list:
 -      @echo $(X509_CERTIFICATES) >$@
 -endif
 -
 -clean-files := x509_certificate_list .x509.list
 -
 -ifeq ($(CONFIG_MODULE_SIG),y)
 -###############################################################################
 -#
 -# If module signing is requested, say by allyesconfig, but a key has not been
 -# supplied, then one will need to be generated to make sure the build does not
 -# fail and that the kernel may be used afterwards.
 -#
 -###############################################################################
 -ifndef CONFIG_MODULE_SIG_HASH
 -$(error Could not determine digest type to use from kernel config)
 -endif
 -
 -signing_key.priv signing_key.x509: x509.genkey
 -      @echo "###"
 -      @echo "### Now generating an X.509 key pair to be used for signing modules."
 -      @echo "###"
 -      @echo "### If this takes a long time, you might wish to run rngd in the"
 -      @echo "### background to keep the supply of entropy topped up.  It"
 -      @echo "### needs to be run as root, and uses a hardware random"
 -      @echo "### number generator if one is available."
 -      @echo "###"
 -      openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \
 -              -batch -x509 -config x509.genkey \
 -              -outform DER -out signing_key.x509 \
 -              -keyout signing_key.priv 2>&1
 -      @echo "###"
 -      @echo "### Key pair generated."
 -      @echo "###"
 -
 -x509.genkey:
 -      @echo Generating X.509 key generation config
 -      @echo  >x509.genkey "[ req ]"
 -      @echo >>x509.genkey "default_bits = 4096"
 -      @echo >>x509.genkey "distinguished_name = req_distinguished_name"
 -      @echo >>x509.genkey "prompt = no"
 -      @echo >>x509.genkey "string_mask = utf8only"
 -      @echo >>x509.genkey "x509_extensions = myexts"
 -      @echo >>x509.genkey
 -      @echo >>x509.genkey "[ req_distinguished_name ]"
 -      @echo >>x509.genkey "#O = Unspecified company"
 -      @echo >>x509.genkey "CN = Build time autogenerated kernel key"
 -      @echo >>x509.genkey "#emailAddress = unspecified.user@unspecified.company"
 -      @echo >>x509.genkey
 -      @echo >>x509.genkey "[ myexts ]"
 -      @echo >>x509.genkey "basicConstraints=critical,CA:FALSE"
 -      @echo >>x509.genkey "keyUsage=digitalSignature"
 -      @echo >>x509.genkey "subjectKeyIdentifier=hash"
 -      @echo >>x509.genkey "authorityKeyIdentifier=keyid"
 -endif
diff --combined lib/Kconfig
@@@ -53,6 -53,9 +53,6 @@@ config GENERIC_I
  config STMP_DEVICE
        bool
  
 -config PERCPU_RWSEM
 -      bool
 -
  config ARCH_USE_CMPXCHG_LOCKREF
        bool
  
@@@ -457,6 -460,16 +457,6 @@@ config ARCH_HAS_ATOMIC64_DEC_IF_POSITIV
  config LRU_CACHE
        tristate
  
 -config AVERAGE
 -      bool "Averaging functions"
 -      help
 -        This option is provided for the case where no in-kernel-tree
 -        modules require averaging functions, but a module built outside
 -        the kernel tree does. Such modules that use library averaging
 -        functions require Y here.
 -
 -        If unsure, say N.
 -
  config CLZ_TAB
        bool
  
@@@ -508,13 -521,6 +508,13 @@@ config UCS2_STRIN
  
  source "lib/fonts/Kconfig"
  
 +config SG_SPLIT
 +      def_bool n
 +      help
 +       Provides a heler to split scatterlists into chunks, each chunk being a
 +       scatterlist. This should be selected by a driver or an API which
 +       whishes to split a scatterlist amongst multiple DMA channel.
 +
  #
  # sg chaining option
  #
@@@ -525,4 -531,7 +525,7 @@@ config ARCH_HAS_SG_CHAI
  config ARCH_HAS_PMEM_API
        bool
  
+ config ARCH_HAS_MMIO_FLUSH
+       bool
  endmenu
diff --combined lib/pci_iomap.c
@@@ -41,61 -41,13 +41,58 @@@ void __iomem *pci_iomap_range(struct pc
                len = maxlen;
        if (flags & IORESOURCE_IO)
                return __pci_ioport_map(dev, start, len);
-       if (flags & IORESOURCE_MEM) {
-               if (flags & IORESOURCE_CACHEABLE)
-                       return ioremap(start, len);
-               return ioremap_nocache(start, len);
-       }
+       if (flags & IORESOURCE_MEM)
+               return ioremap(start, len);
        /* What? */
        return NULL;
  }
  EXPORT_SYMBOL(pci_iomap_range);
  
 +/**
 + * pci_iomap_wc_range - create a virtual WC mapping cookie for a PCI BAR
 + * @dev: PCI device that owns the BAR
 + * @bar: BAR number
 + * @offset: map memory at the given offset in BAR
 + * @maxlen: max length of the memory to map
 + *
 + * Using this function you will get a __iomem address to your device BAR.
 + * You can access it using ioread*() and iowrite*(). These functions hide
 + * the details if this is a MMIO or PIO address space and will just do what
 + * you expect from them in the correct way. When possible write combining
 + * is used.
 + *
 + * @maxlen specifies the maximum length to map. If you want to get access to
 + * the complete BAR from offset to the end, pass %0 here.
 + * */
 +void __iomem *pci_iomap_wc_range(struct pci_dev *dev,
 +                               int bar,
 +                               unsigned long offset,
 +                               unsigned long maxlen)
 +{
 +      resource_size_t start = pci_resource_start(dev, bar);
 +      resource_size_t len = pci_resource_len(dev, bar);
 +      unsigned long flags = pci_resource_flags(dev, bar);
 +
 +
 +      if (flags & IORESOURCE_IO)
 +              return NULL;
 +
 +      if (len <= offset || !start)
 +              return NULL;
 +
 +      len -= offset;
 +      start += offset;
 +      if (maxlen && len > maxlen)
 +              len = maxlen;
 +
 +      if (flags & IORESOURCE_MEM)
 +              return ioremap_wc(start, len);
 +
 +      /* What? */
 +      return NULL;
 +}
 +EXPORT_SYMBOL_GPL(pci_iomap_wc_range);
 +
  /**
   * pci_iomap - create a virtual mapping cookie for a PCI BAR
   * @dev: PCI device that owns the BAR
@@@ -115,25 -67,4 +112,25 @@@ void __iomem *pci_iomap(struct pci_dev 
        return pci_iomap_range(dev, bar, 0, maxlen);
  }
  EXPORT_SYMBOL(pci_iomap);
 +
 +/**
 + * pci_iomap_wc - create a virtual WC mapping cookie for a PCI BAR
 + * @dev: PCI device that owns the BAR
 + * @bar: BAR number
 + * @maxlen: length of the memory to map
 + *
 + * Using this function you will get a __iomem address to your device BAR.
 + * You can access it using ioread*() and iowrite*(). These functions hide
 + * the details if this is a MMIO or PIO address space and will just do what
 + * you expect from them in the correct way. When possible write combining
 + * is used.
 + *
 + * @maxlen specifies the maximum length to map. If you want to get access to
 + * the complete BAR without checking for its length first, pass %0 here.
 + * */
 +void __iomem *pci_iomap_wc(struct pci_dev *dev, int bar, unsigned long maxlen)
 +{
 +      return pci_iomap_wc_range(dev, bar, 0, maxlen);
 +}
 +EXPORT_SYMBOL_GPL(pci_iomap_wc);
  #endif /* CONFIG_PCI */
diff --combined mm/Kconfig
@@@ -299,9 -299,15 +299,9 @@@ config BOUNC
  # On the 'tile' arch, USB OHCI needs the bounce pool since tilegx will often
  # have more than 4GB of memory, but we don't currently use the IOTLB to present
  # a 32-bit address to OHCI.  So we need to use a bounce pool instead.
 -#
 -# We also use the bounce pool to provide stable page writes for jbd.  jbd
 -# initiates buffer writeback without locking the page or setting PG_writeback,
 -# and fixing that behavior (a second time; jbd2 doesn't have this problem) is
 -# a major rework effort.  Instead, use the bounce buffer to snapshot pages
 -# (until jbd goes away).  The only jbd user is ext3.
  config NEED_BOUNCE_POOL
        bool
 -      default y if (TILE && USB_OHCI_HCD) || (BLK_DEV_INTEGRITY && JBD)
 +      default y if TILE && USB_OHCI_HCD
  
  config NR_QUICK
        int
@@@ -648,3 -654,20 +648,20 @@@ config DEFERRED_STRUCT_PAGE_INI
          when kswapd starts. This has a potential performance impact on
          processes running early in the lifetime of the systemm until kswapd
          finishes the initialisation.
+ config ZONE_DEVICE
+       bool "Device memory (pmem, etc...) hotplug support" if EXPERT
+       default !ZONE_DMA
+       depends on !ZONE_DMA
+       depends on MEMORY_HOTPLUG
+       depends on MEMORY_HOTREMOVE
+       depends on X86_64 #arch_add_memory() comprehends device memory
+       help
+         Device memory hotplug support allows for establishing pmem,
+         or other device driver discovered memory regions, in the
+         memmap. This allows pfn_to_page() lookups of otherwise
+         "device-physical" addresses which is needed for using a DAX
+         mapping in an O_DIRECT operation, among other things.
+         If FS_DAX is enabled, then say Y.
diff --combined mm/memory_hotplug.c
@@@ -446,7 -446,7 +446,7 @@@ static int __meminit __add_zone(struct 
        int nr_pages = PAGES_PER_SECTION;
        int nid = pgdat->node_id;
        int zone_type;
 -      unsigned long flags;
 +      unsigned long flags, pfn;
        int ret;
  
        zone_type = zone - pgdat->node_zones;
        pgdat_resize_unlock(zone->zone_pgdat, &flags);
        memmap_init_zone(nr_pages, nid, zone_type,
                         phys_start_pfn, MEMMAP_HOTPLUG);
 +
 +      /* online_page_range is called later and expects pages reserved */
 +      for (pfn = phys_start_pfn; pfn < phys_start_pfn + nr_pages; pfn++) {
 +              if (!pfn_valid(pfn))
 +                      continue;
 +
 +              SetPageReserved(pfn_to_page(pfn));
 +      }
        return 0;
  }
  
@@@ -778,7 -770,10 +778,10 @@@ int __remove_pages(struct zone *zone, u
  
        start = phys_start_pfn << PAGE_SHIFT;
        size = nr_pages * PAGE_SIZE;
-       ret = release_mem_region_adjustable(&iomem_resource, start, size);
+       /* in the ZONE_DEVICE case device driver owns the memory region */
+       if (!is_dev_zone(zone))
+               ret = release_mem_region_adjustable(&iomem_resource, start, size);
        if (ret) {
                resource_size_t endres = start + size - 1;
  
@@@ -1215,8 -1210,13 +1218,13 @@@ static int should_add_memory_movable(in
        return 0;
  }
  
- int zone_for_memory(int nid, u64 start, u64 size, int zone_default)
+ int zone_for_memory(int nid, u64 start, u64 size, int zone_default,
+               bool for_device)
  {
+ #ifdef CONFIG_ZONE_DEVICE
+       if (for_device)
+               return ZONE_DEVICE;
+ #endif
        if (should_add_memory_movable(nid, start, size))
                return ZONE_MOVABLE;
  
@@@ -1248,14 -1248,6 +1256,14 @@@ int __ref add_memory(int nid, u64 start
  
        mem_hotplug_begin();
  
 +      /*
 +       * Add new range to memblock so that when hotadd_new_pgdat() is called
 +       * to allocate new pgdat, get_pfn_range_for_nid() will be able to find
 +       * this new range and calculate total pages correctly.  The range will
 +       * be removed at hot-remove time.
 +       */
 +      memblock_add_node(start, size, nid);
 +
        new_node = !node_online(nid);
        if (new_node) {
                pgdat = hotadd_new_pgdat(nid, start);
        }
  
        /* call arch's memory hotadd */
-       ret = arch_add_memory(nid, start, size);
+       ret = arch_add_memory(nid, start, size, false);
  
        if (ret < 0)
                goto error;
@@@ -1293,7 -1285,6 +1301,7 @@@ error
        if (new_pgdat)
                rollback_node_hotadd(nid, pgdat);
        release_memory_resource(res);
 +      memblock_remove(start, size);
  
  out:
        mem_hotplug_done();
@@@ -2022,8 -2013,6 +2030,8 @@@ void __ref remove_memory(int nid, u64 s
  
        /* remove memmap entry */
        firmware_map_remove(start, start + size, "System RAM");
 +      memblock_free(start, size);
 +      memblock_remove(start, size);
  
        arch_remove_memory(start, size);
  
diff --combined mm/page_alloc.c
@@@ -18,6 -18,7 +18,6 @@@
  #include <linux/mm.h>
  #include <linux/swap.h>
  #include <linux/interrupt.h>
 -#include <linux/rwsem.h>
  #include <linux/pagemap.h>
  #include <linux/jiffies.h>
  #include <linux/bootmem.h>
@@@ -206,6 -207,9 +206,9 @@@ static char * const zone_names[MAX_NR_Z
         "HighMem",
  #endif
         "Movable",
+ #ifdef CONFIG_ZONE_DEVICE
+        "Device",
+ #endif
  };
  
  int min_free_kbytes = 1024;
@@@ -980,21 -984,21 +983,21 @@@ static void __init __free_pages_boot_co
  
  #if defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID) || \
        defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP)
 -/* Only safe to use early in boot when initialisation is single-threaded */
 +
  static struct mminit_pfnnid_cache early_pfnnid_cache __meminitdata;
  
  int __meminit early_pfn_to_nid(unsigned long pfn)
  {
 +      static DEFINE_SPINLOCK(early_pfn_lock);
        int nid;
  
 -      /* The system will behave unpredictably otherwise */
 -      BUG_ON(system_state != SYSTEM_BOOTING);
 -
 +      spin_lock(&early_pfn_lock);
        nid = __early_pfn_to_nid(pfn, &early_pfnnid_cache);
 -      if (nid >= 0)
 -              return nid;
 -      /* just returns 0 */
 -      return 0;
 +      if (nid < 0)
 +              nid = 0;
 +      spin_unlock(&early_pfn_lock);
 +
 +      return nid;
  }
  #endif
  
@@@ -1059,15 -1063,7 +1062,15 @@@ static void __init deferred_free_range(
                __free_pages_boot_core(page, pfn, 0);
  }
  
 -static __initdata DECLARE_RWSEM(pgdat_init_rwsem);
 +/* Completion tracking for deferred_init_memmap() threads */
 +static atomic_t pgdat_init_n_undone __initdata;
 +static __initdata DECLARE_COMPLETION(pgdat_init_all_done_comp);
 +
 +static inline void __init pgdat_init_report_one_done(void)
 +{
 +      if (atomic_dec_and_test(&pgdat_init_n_undone))
 +              complete(&pgdat_init_all_done_comp);
 +}
  
  /* Initialise remaining memory on a node */
  static int __init deferred_init_memmap(void *data)
        const struct cpumask *cpumask = cpumask_of_node(pgdat->node_id);
  
        if (first_init_pfn == ULONG_MAX) {
 -              up_read(&pgdat_init_rwsem);
 +              pgdat_init_report_one_done();
                return 0;
        }
  
@@@ -1184,8 -1180,7 +1187,8 @@@ free_range
  
        pr_info("node %d initialised, %lu pages in %ums\n", nid, nr_pages,
                                        jiffies_to_msecs(jiffies - start));
 -      up_read(&pgdat_init_rwsem);
 +
 +      pgdat_init_report_one_done();
        return 0;
  }
  
@@@ -1193,17 -1188,14 +1196,17 @@@ void __init page_alloc_init_late(void
  {
        int nid;
  
 +      /* There will be num_node_state(N_MEMORY) threads */
 +      atomic_set(&pgdat_init_n_undone, num_node_state(N_MEMORY));
        for_each_node_state(nid, N_MEMORY) {
 -              down_read(&pgdat_init_rwsem);
                kthread_run(deferred_init_memmap, NODE_DATA(nid), "pgdatinit%d", nid);
        }
  
        /* Block until all are initialised */
 -      down_write(&pgdat_init_rwsem);
 -      up_write(&pgdat_init_rwsem);
 +      wait_for_completion(&pgdat_init_all_done_comp);
 +
 +      /* Reinit limits that are based on free pages after the kernel is up */
 +      files_maxfiles_init();
  }
  #endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */
  
@@@ -1296,10 -1288,6 +1299,10 @@@ static inline int check_new_page(struc
                bad_reason = "non-NULL mapping";
        if (unlikely(atomic_read(&page->_count) != 0))
                bad_reason = "nonzero _count";
 +      if (unlikely(page->flags & __PG_HWPOISON)) {
 +              bad_reason = "HWPoisoned (hardware-corrupted)";
 +              bad_flags = __PG_HWPOISON;
 +      }
        if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_PREP)) {
                bad_reason = "PAGE_FLAGS_CHECK_AT_PREP flag set";
                bad_flags = PAGE_FLAGS_CHECK_AT_PREP;
@@@ -1343,15 -1331,12 +1346,15 @@@ static int prep_new_page(struct page *p
        set_page_owner(page, order, gfp_flags);
  
        /*
 -       * page->pfmemalloc is set when ALLOC_NO_WATERMARKS was necessary to
 +       * page is set pfmemalloc when ALLOC_NO_WATERMARKS was necessary to
         * allocate the page. The expectation is that the caller is taking
         * steps that will free more memory. The caller should avoid the page
         * being used for !PFMEMALLOC purposes.
         */
 -      page->pfmemalloc = !!(alloc_flags & ALLOC_NO_WATERMARKS);
 +      if (alloc_flags & ALLOC_NO_WATERMARKS)
 +              set_page_pfmemalloc(page);
 +      else
 +              clear_page_pfmemalloc(page);
  
        return 0;
  }
@@@ -3348,7 -3333,7 +3351,7 @@@ refill
                atomic_add(size - 1, &page->_count);
  
                /* reset page count bias and offset to start of new frag */
 -              nc->pfmemalloc = page->pfmemalloc;
 +              nc->pfmemalloc = page_is_pfmemalloc(page);
                nc->pagecnt_bias = size;
                nc->offset = size;
        }
@@@ -5063,10 -5048,6 +5066,10 @@@ static unsigned long __meminit zone_spa
  {
        unsigned long zone_start_pfn, zone_end_pfn;
  
 +      /* When hotadd a new node, the node should be empty */
 +      if (!node_start_pfn && !node_end_pfn)
 +              return 0;
 +
        /* Get the start and end of the zone */
        zone_start_pfn = arch_zone_lowest_possible_pfn[zone_type];
        zone_end_pfn = arch_zone_highest_possible_pfn[zone_type];
@@@ -5130,10 -5111,6 +5133,10 @@@ static unsigned long __meminit zone_abs
        unsigned long zone_high = arch_zone_highest_possible_pfn[zone_type];
        unsigned long zone_start_pfn, zone_end_pfn;
  
 +      /* When hotadd a new node, the node should be empty */
 +      if (!node_start_pfn && !node_end_pfn)
 +              return 0;
 +
        zone_start_pfn = clamp(node_start_pfn, zone_low, zone_high);
        zone_end_pfn = clamp(node_end_pfn, zone_low, zone_high);