summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CREDITS5
-rw-r--r--Documentation/arm64/memory.txt12
-rw-r--r--Documentation/cgroups/memory.txt4
-rw-r--r--Documentation/devicetree/bindings/net/mdio-gpio.txt9
-rw-r--r--Documentation/filesystems/proc.txt16
-rw-r--r--Documentation/networking/netdev-features.txt2
-rw-r--r--Documentation/networking/vxlan.txt4
-rw-r--r--MAINTAINERS82
-rw-r--r--Makefile2
-rw-r--r--arch/alpha/kernel/osf_sys.c6
-rw-r--r--arch/arm/boot/Makefile10
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi4
-rw-r--r--arch/arm/include/asm/io.h4
-rw-r--r--arch/arm/include/asm/sched_clock.h2
-rw-r--r--arch/arm/include/asm/vfpmacros.h12
-rw-r--r--arch/arm/include/uapi/asm/hwcap.h3
-rw-r--r--arch/arm/kernel/sched_clock.c18
-rw-r--r--arch/arm/mach-at91/at91rm9200_devices.c2
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c2
-rw-r--r--arch/arm/mach-at91/at91sam9261_devices.c2
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c2
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c12
-rw-r--r--arch/arm/mach-davinci/dm644x.c3
-rw-r--r--arch/arm/mach-exynos/dma.c3
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h1
-rw-r--r--arch/arm/mach-highbank/system.c3
-rw-r--r--arch/arm/mach-imx/clk-gate2.c2
-rw-r--r--arch/arm/mach-imx/ehci-imx25.c2
-rw-r--r--arch/arm/mach-imx/ehci-imx35.c2
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c5
-rw-r--r--arch/arm/mach-omap2/clockdomains44xx_data.c2
-rw-r--r--arch/arm/mach-omap2/common-board-devices.c34
-rw-r--r--arch/arm/mach-omap2/devices.c79
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c63
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c36
-rw-r--r--arch/arm/mach-omap2/twl-common.c3
-rw-r--r--arch/arm/mach-omap2/vc.c2
-rw-r--r--arch/arm/mach-pxa/hx4700.c8
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c8
-rw-r--r--arch/arm/mm/alignment.c2
-rw-r--r--arch/arm/plat-omap/i2c.c21
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h6
-rw-r--r--arch/arm/tools/Makefile2
-rw-r--r--arch/arm/vfp/vfpmodule.c9
-rw-r--r--arch/arm/xen/enlighten.c11
-rw-r--r--arch/arm64/Kconfig1
-rw-r--r--arch/arm64/include/asm/elf.h5
-rw-r--r--arch/arm64/include/asm/fpsimd.h5
-rw-r--r--arch/arm64/include/asm/io.h10
-rw-r--r--arch/arm64/include/asm/pgtable-hwdef.h6
-rw-r--r--arch/arm64/include/asm/pgtable.h40
-rw-r--r--arch/arm64/include/asm/processor.h2
-rw-r--r--arch/arm64/include/asm/unistd.h1
-rw-r--r--arch/arm64/kernel/perf_event.c10
-rw-r--r--arch/arm64/kernel/process.c18
-rw-r--r--arch/arm64/kernel/smp.c3
-rw-r--r--arch/arm64/mm/init.c2
-rw-r--r--arch/h8300/include/asm/cache.h3
-rw-r--r--arch/ia64/mm/init.c1
-rw-r--r--arch/m68k/include/asm/signal.h6
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-l2c.c1
-rw-r--r--arch/mips/fw/arc/misc.c1
-rw-r--r--arch/mips/include/asm/bitops.h128
-rw-r--r--arch/mips/include/asm/compat.h2
-rw-r--r--arch/mips/include/asm/io.h1
-rw-r--r--arch/mips/include/asm/irqflags.h207
-rw-r--r--arch/mips/include/asm/thread_info.h6
-rw-r--r--arch/mips/lib/Makefile5
-rw-r--r--arch/mips/lib/bitops.c179
-rw-r--r--arch/mips/lib/mips-atomic.c176
-rw-r--r--arch/mips/mti-malta/malta-platform.c3
-rw-r--r--arch/parisc/kernel/signal32.c6
-rw-r--r--arch/parisc/kernel/sys_parisc.c2
-rw-r--r--arch/powerpc/boot/dts/mpc5200b.dtsi6
-rw-r--r--arch/powerpc/boot/dts/o2d.dtsi6
-rw-r--r--arch/powerpc/boot/dts/pcm030.dts7
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pic.c9
-rw-r--r--arch/s390/Kconfig1
-rw-r--r--arch/s390/include/asm/cio.h2
-rw-r--r--arch/s390/include/asm/compat.h2
-rw-r--r--arch/s390/include/asm/pgtable.h35
-rw-r--r--arch/s390/include/asm/topology.h3
-rw-r--r--arch/s390/include/uapi/asm/ptrace.h4
-rw-r--r--arch/s390/kernel/compat_signal.c14
-rw-r--r--arch/s390/kernel/sclp.S8
-rw-r--r--arch/s390/kernel/signal.c14
-rw-r--r--arch/s390/kernel/topology.c6
-rw-r--r--arch/s390/lib/uaccess_pt.c2
-rw-r--r--arch/s390/mm/gup.c7
-rw-r--r--arch/sparc/Kconfig1
-rw-r--r--arch/sparc/crypto/Makefile16
-rw-r--r--arch/sparc/crypto/aes_glue.c2
-rw-r--r--arch/sparc/crypto/camellia_glue.c2
-rw-r--r--arch/sparc/crypto/crc32c_glue.c2
-rw-r--r--arch/sparc/crypto/des_glue.c2
-rw-r--r--arch/sparc/crypto/md5_glue.c2
-rw-r--r--arch/sparc/crypto/sha1_glue.c2
-rw-r--r--arch/sparc/crypto/sha256_glue.c2
-rw-r--r--arch/sparc/crypto/sha512_glue.c2
-rw-r--r--arch/sparc/include/asm/atomic_64.h4
-rw-r--r--arch/sparc/include/asm/backoff.h69
-rw-r--r--arch/sparc/include/asm/compat.h5
-rw-r--r--arch/sparc/include/asm/processor_64.h17
-rw-r--r--arch/sparc/include/asm/prom.h8
-rw-r--r--arch/sparc/include/asm/thread_info_64.h5
-rw-r--r--arch/sparc/include/asm/ttable.h24
-rw-r--r--arch/sparc/include/uapi/asm/unistd.h7
-rw-r--r--arch/sparc/kernel/entry.h7
-rw-r--r--arch/sparc/kernel/leon_kernel.c6
-rw-r--r--arch/sparc/kernel/perf_event.c22
-rw-r--r--arch/sparc/kernel/process_64.c42
-rw-r--r--arch/sparc/kernel/ptrace_64.c4
-rw-r--r--arch/sparc/kernel/setup_64.c21
-rw-r--r--arch/sparc/kernel/signal_64.c4
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c5
-rw-r--r--arch/sparc/kernel/systbls_32.S1
-rw-r--r--arch/sparc/kernel/systbls_64.S2
-rw-r--r--arch/sparc/kernel/unaligned_64.c36
-rw-r--r--arch/sparc/kernel/visemul.c23
-rw-r--r--arch/sparc/kernel/vmlinux.lds.S5
-rw-r--r--arch/sparc/kernel/winfixup.S2
-rw-r--r--arch/sparc/lib/atomic_64.S16
-rw-r--r--arch/sparc/lib/ksyms.c1
-rw-r--r--arch/sparc/math-emu/math_64.c2
-rw-r--r--arch/unicore32/Kconfig7
-rw-r--r--arch/unicore32/include/asm/Kbuild1
-rw-r--r--arch/unicore32/include/asm/bug.h5
-rw-r--r--arch/unicore32/include/asm/cmpxchg.h2
-rw-r--r--arch/unicore32/include/asm/kvm_para.h1
-rw-r--r--arch/unicore32/include/asm/processor.h5
-rw-r--r--arch/unicore32/include/asm/ptrace.h76
-rw-r--r--arch/unicore32/include/uapi/asm/Kbuild7
-rw-r--r--arch/unicore32/include/uapi/asm/byteorder.h (renamed from arch/unicore32/include/asm/byteorder.h)0
-rw-r--r--arch/unicore32/include/uapi/asm/ptrace.h90
-rw-r--r--arch/unicore32/include/uapi/asm/sigcontext.h (renamed from arch/unicore32/include/asm/sigcontext.h)0
-rw-r--r--arch/unicore32/include/uapi/asm/unistd.h (renamed from arch/unicore32/include/asm/unistd.h)1
-rw-r--r--arch/unicore32/kernel/entry.S20
-rw-r--r--arch/unicore32/kernel/process.c58
-rw-r--r--arch/unicore32/kernel/setup.h6
-rw-r--r--arch/unicore32/kernel/sys.c63
-rw-r--r--arch/unicore32/mm/fault.c37
-rw-r--r--arch/x86/include/asm/xen/hypercall.h21
-rw-r--r--arch/x86/kvm/cpuid.h3
-rw-r--r--arch/x86/kvm/vmx.c11
-rw-r--r--arch/x86/kvm/x86.c3
-rw-r--r--block/blk-exec.c8
-rw-r--r--crypto/cryptd.c11
-rw-r--r--drivers/ata/ahci_platform.c2
-rw-r--r--drivers/ata/libata-acpi.c11
-rw-r--r--drivers/ata/libata-core.c4
-rw-r--r--drivers/ata/libata-scsi.c2
-rw-r--r--drivers/ata/pata_arasan_cf.c8
-rw-r--r--drivers/ata/sata_highbank.c4
-rw-r--r--drivers/ata/sata_svw.c35
-rw-r--r--drivers/base/platform.c7
-rw-r--r--drivers/base/power/qos.c2
-rw-r--r--drivers/block/aoe/aoecmd.c2
-rw-r--r--drivers/block/floppy.c5
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c18
-rw-r--r--drivers/block/mtip32xx/mtip32xx.h6
-rw-r--r--drivers/bluetooth/ath3k.c1
-rw-r--r--drivers/bluetooth/btusb.c1
-rw-r--r--drivers/bus/omap-ocp2scp.c68
-rw-r--r--drivers/clk/ux500/u8500_clk.c50
-rw-r--r--drivers/firewire/sbp2.c2
-rw-r--r--drivers/gpio/Kconfig4
-rw-r--r--drivers/gpio/gpio-mcp23s08.c6
-rw-r--r--drivers/gpio/gpio-mvebu.c23
-rw-r--r--drivers/gpu/drm/drm_fops.c44
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c11
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c22
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.c31
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c12
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv40.c8
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv40.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/object.h14
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/clock.h3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c19
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c3
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c54
-rw-r--r--drivers/gpu/drm/radeon/atombios_encoders.c2
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c4
-rw-r--r--drivers/gpu/drm/radeon/evergreen_cs.c3
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_agp.c5
-rw-r--r--drivers/gpu/drm/radeon/si.c1
-rw-r--r--drivers/gpu/drm/radeon/sid.h1
-rw-r--r--drivers/gpu/drm/ttm/ttm_page_alloc.c5
-rw-r--r--drivers/gpu/drm/ttm/ttm_tt.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c5
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c2
-rw-r--r--drivers/hid/hid-microsoft.c6
-rw-r--r--drivers/hid/hidraw.c69
-rw-r--r--drivers/hwmon/asb100.c2
-rw-r--r--drivers/hwmon/w83627ehf.c1
-rw-r--r--drivers/hwmon/w83627hf.c2
-rw-r--r--drivers/hwmon/w83781d.c2
-rw-r--r--drivers/hwmon/w83791d.c2
-rw-r--r--drivers/hwmon/w83792d.c2
-rw-r--r--drivers/hwmon/w83l786ng.c2
-rw-r--r--drivers/i2c/busses/i2c-at91.c7
-rw-r--r--drivers/i2c/busses/i2c-mxs.c2
-rw-r--r--drivers/i2c/busses/i2c-omap.c36
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c1
-rw-r--r--drivers/i2c/muxes/i2c-mux-pinctrl.c2
-rw-r--r--drivers/input/input-mt.c4
-rw-r--r--drivers/input/mousedev.c4
-rw-r--r--drivers/input/touchscreen/ads7846.c6
-rw-r--r--drivers/iommu/intel-iommu.c4
-rw-r--r--drivers/iommu/tegra-smmu.c1
-rw-r--r--drivers/irqchip/irq-bcm2835.c3
-rw-r--r--drivers/isdn/Kconfig2
-rw-r--r--drivers/isdn/i4l/Kconfig2
-rw-r--r--drivers/isdn/i4l/isdn_common.c4
-rw-r--r--drivers/leds/ledtrig-cpu.c21
-rw-r--r--drivers/md/dm.c8
-rw-r--r--drivers/md/md.c27
-rw-r--r--drivers/md/raid10.c131
-rw-r--r--drivers/md/raid5.c79
-rw-r--r--drivers/mmc/host/dw_mmc-exynos.c8
-rw-r--r--drivers/mmc/host/dw_mmc-pltfm.c6
-rw-r--r--drivers/mmc/host/dw_mmc-pltfm.h2
-rw-r--r--drivers/mmc/host/dw_mmc.c62
-rw-r--r--drivers/mmc/host/mxcmmc.c2
-rw-r--r--drivers/mmc/host/omap_hsmmc.c19
-rw-r--r--drivers/mmc/host/sdhci-dove.c38
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c11
-rw-r--r--drivers/mmc/host/sdhci-pci.c2
-rw-r--r--drivers/mmc/host/sdhci-pltfm.c7
-rw-r--r--drivers/mmc/host/sdhci-s3c.c30
-rw-r--r--drivers/mmc/host/sdhci.c44
-rw-r--r--drivers/mmc/host/sdhci.h1
-rw-r--r--drivers/mmc/host/sh_mmcif.c2
-rw-r--r--drivers/net/bonding/bond_main.c7
-rw-r--r--drivers/net/ethernet/8390/ne.c1
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c4
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c11
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.c6
-rw-r--r--drivers/net/ethernet/freescale/gianfar.c5
-rw-r--r--drivers/net/ethernet/jme.c36
-rw-r--r--drivers/net/ethernet/marvell/skge.c2
-rw-r--r--drivers/net/ethernet/micrel/ksz884x.c20
-rw-r--r--drivers/net/ethernet/realtek/8139cp.c22
-rw-r--r--drivers/net/ethernet/realtek/r8169.c5
-rw-r--r--drivers/net/ethernet/sis/sis900.c2
-rw-r--r--drivers/net/ethernet/smsc/smsc911x.c17
-rw-r--r--drivers/net/ethernet/tile/tilegx.c2
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet_main.c16
-rw-r--r--drivers/net/ethernet/xscale/ixp4xx_eth.c8
-rw-r--r--drivers/net/irda/sir_dev.c2
-rw-r--r--drivers/net/phy/mdio-bitbang.c1
-rw-r--r--drivers/net/phy/mdio-gpio.c11
-rw-r--r--drivers/net/team/team_mode_broadcast.c6
-rw-r--r--drivers/net/usb/cdc_eem.c3
-rw-r--r--drivers/net/usb/cdc_ncm.c22
-rw-r--r--drivers/net/usb/smsc95xx.c5
-rw-r--r--drivers/net/usb/usbnet.c8
-rw-r--r--drivers/net/vxlan.c10
-rw-r--r--drivers/net/wan/ixp4xx_hss.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c2
-rw-r--r--drivers/net/wireless/b43legacy/pio.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c16
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c23
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c8
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c11
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c11
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c1
-rw-r--r--drivers/net/xen-netfront.c98
-rw-r--r--drivers/nfc/pn533.c25
-rw-r--r--drivers/pci/bus.c3
-rw-r--r--drivers/pci/pci-driver.c12
-rw-r--r--drivers/pci/pci-sysfs.c34
-rw-r--r--drivers/pci/pci.c32
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c20
-rw-r--r--drivers/pci/pcie/portdrv_core.c3
-rw-r--r--drivers/pci/proc.c8
-rw-r--r--drivers/pinctrl/Kconfig4
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear.c2
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear1310.c365
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear1340.c41
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear320.c8
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear3xx.h1
-rw-r--r--drivers/rapidio/rio.c2
-rw-r--r--drivers/regulator/core.c33
-rw-r--r--drivers/s390/char/con3215.c12
-rw-r--r--drivers/s390/cio/css.h3
-rw-r--r--drivers/s390/cio/device.c8
-rw-r--r--drivers/s390/cio/idset.c3
-rw-r--r--drivers/s390/net/qeth_core_main.c24
-rw-r--r--drivers/s390/net/qeth_l2_main.c13
-rw-r--r--drivers/scsi/isci/request.c2
-rw-r--r--drivers/scsi/qlogicpti.c13
-rw-r--r--drivers/scsi/scsi.c45
-rw-r--r--drivers/scsi/scsi_lib.c22
-rw-r--r--drivers/scsi/sd.c202
-rw-r--r--drivers/scsi/sd.h7
-rw-r--r--drivers/staging/android/android_alarm.h4
-rw-r--r--drivers/tty/hvc/hvc_console.c7
-rw-r--r--drivers/tty/serial/max310x.c1
-rw-r--r--drivers/usb/core/hcd.c16
-rw-r--r--drivers/usb/early/ehci-dbgp.c15
-rw-r--r--drivers/usb/gadget/u_ether.c3
-rw-r--r--drivers/usb/host/ehci-ls1x.c2
-rw-r--r--drivers/usb/host/ohci-xls.c2
-rw-r--r--drivers/usb/musb/musb_gadget.c30
-rw-r--r--drivers/usb/musb/ux500.c2
-rw-r--r--drivers/usb/otg/Kconfig4
-rw-r--r--drivers/usb/serial/keyspan.c3
-rw-r--r--drivers/usb/serial/option.c9
-rw-r--r--drivers/usb/serial/usb_wwan.c10
-rw-r--r--drivers/usb/storage/scsiglue.c6
-rw-r--r--drivers/video/omap2/dss/dsi.c13
-rw-r--r--drivers/video/omap2/dss/dss.c18
-rw-r--r--drivers/video/omap2/dss/hdmi.c4
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c2
-rw-r--r--drivers/virtio/virtio.c4
-rw-r--r--drivers/xen/Makefile1
-rw-r--r--drivers/xen/events.c2
-rw-r--r--drivers/xen/fallback.c80
-rw-r--r--drivers/xen/privcmd.c18
-rw-r--r--fs/cifs/cifsacl.c49
-rw-r--r--fs/cifs/dir.c11
-rw-r--r--fs/eventpoll.c38
-rw-r--r--fs/ext3/balloc.c5
-rw-r--r--fs/file.c1
-rw-r--r--fs/gfs2/file.c14
-rw-r--r--fs/gfs2/lops.c16
-rw-r--r--fs/gfs2/quota.c7
-rw-r--r--fs/gfs2/rgrp.c33
-rw-r--r--fs/gfs2/super.c3
-rw-r--r--fs/gfs2/trans.c8
-rw-r--r--fs/notify/fanotify/fanotify.c1
-rw-r--r--fs/notify/fanotify/fanotify_user.c3
-rw-r--r--fs/proc/base.c109
-rw-r--r--fs/pstore/platform.c3
-rw-r--r--fs/reiserfs/inode.c10
-rw-r--r--fs/reiserfs/stree.c4
-rw-r--r--fs/reiserfs/super.c60
-rw-r--r--fs/ubifs/find.c12
-rw-r--r--fs/ubifs/lprops.c6
-rw-r--r--fs/ubifs/ubifs.h3
-rw-r--r--fs/xfs/xfs_alloc.c43
-rw-r--r--fs/xfs/xfs_alloc.h3
-rw-r--r--fs/xfs/xfs_alloc_btree.c2
-rw-r--r--fs/xfs/xfs_aops.c54
-rw-r--r--fs/xfs/xfs_attr_leaf.c20
-rw-r--r--fs/xfs/xfs_bmap.c63
-rw-r--r--fs/xfs/xfs_bmap.h9
-rw-r--r--fs/xfs/xfs_buf.c14
-rw-r--r--fs/xfs/xfs_buf_item.c18
-rw-r--r--fs/xfs/xfs_fsops.c21
-rw-r--r--fs/xfs/xfs_ialloc.c1
-rw-r--r--fs/xfs/xfs_inode.c3
-rw-r--r--fs/xfs/xfs_ioctl.c2
-rw-r--r--fs/xfs/xfs_iomap.c4
-rw-r--r--fs/xfs/xfs_log.c19
-rw-r--r--fs/xfs/xfs_log_recover.c2
-rw-r--r--include/drm/drm_pciids.h1
-rw-r--r--include/linux/clk-provider.h4
-rw-r--r--include/linux/i2c-omap.h1
-rw-r--r--include/linux/mm.h4
-rw-r--r--include/linux/mmc/dw_mmc.h6
-rw-r--r--include/linux/mmc/sdhci.h1
-rw-r--r--include/linux/mmzone.h2
-rw-r--r--include/linux/of_address.h4
-rw-r--r--include/linux/platform_data/omap_ocp2scp.h31
-rw-r--r--include/linux/ptp_clock_kernel.h3
-rw-r--r--include/linux/rio.h2
-rw-r--r--include/linux/spi/ads7846.h5
-rw-r--r--include/net/xfrm.h2
-rw-r--r--include/scsi/scsi_device.h4
-rw-r--r--include/uapi/linux/eventpoll.h1
-rw-r--r--include/uapi/linux/oom.h9
-rw-r--r--include/xen/hvm.h34
-rw-r--r--kernel/futex.c41
-rw-r--r--kernel/module.c27
-rw-r--r--mm/bootmem.c10
-rw-r--r--mm/highmem.c2
-rw-r--r--mm/memcontrol.c67
-rw-r--r--mm/memory.c10
-rw-r--r--mm/memory_hotplug.c7
-rw-r--r--mm/mmap.c2
-rw-r--r--mm/mmzone.c6
-rw-r--r--mm/nobootmem.c3
-rw-r--r--mm/page_alloc.c38
-rw-r--r--mm/shmem.c18
-rw-r--r--mm/swapfile.c4
-rw-r--r--mm/vmscan.c27
-rw-r--r--net/batman-adv/soft-interface.c12
-rw-r--r--net/batman-adv/translation-table.c15
-rw-r--r--net/bluetooth/hci_core.c4
-rw-r--r--net/bluetooth/mgmt.c12
-rw-r--r--net/bluetooth/smp.c2
-rw-r--r--net/core/dev.c6
-rw-r--r--net/core/dev_addr_lists.c3
-rw-r--r--net/core/net-sysfs.c20
-rw-r--r--net/core/rtnetlink.c3
-rw-r--r--net/ipv4/inet_diag.c5
-rw-r--r--net/ipv4/ip_sockglue.c35
-rw-r--r--net/ipv4/ip_vti.c5
-rw-r--r--net/ipv4/route.c9
-rw-r--r--net/ipv4/tcp.c4
-rw-r--r--net/ipv4/tcp_input.c15
-rw-r--r--net/ipv4/tcp_metrics.c12
-rw-r--r--net/ipv4/tcp_output.c4
-rw-r--r--net/ipv4/xfrm4_policy.c13
-rw-r--r--net/ipv6/inet6_connection_sock.c3
-rw-r--r--net/ipv6/ip6_gre.c8
-rw-r--r--net/ipv6/ipv6_sockglue.c1
-rw-r--r--net/ipv6/ndisc.c3
-rw-r--r--net/mac80211/cfg.c3
-rw-r--r--net/mac80211/ibss.c8
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/main.c6
-rw-r--r--net/mac80211/scan.c2
-rw-r--r--net/mac80211/sta_info.c11
-rw-r--r--net/mac80211/status.c9
-rw-r--r--net/mac80211/tx.c9
-rw-r--r--net/mac80211/util.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_ip.c4
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipport.c7
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportip.c7
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportnet.c7
-rw-r--r--net/netfilter/nfnetlink_cttimeout.c3
-rw-r--r--net/nfc/llcp/llcp.c2
-rw-r--r--net/sched/sch_qfq.c109
-rw-r--r--net/sctp/proc.c8
-rw-r--r--net/tipc/handler.c1
-rw-r--r--net/wireless/reg.c5
-rw-r--r--scripts/Makefile.modinst3
-rwxr-xr-xscripts/checkpatch.pl6
-rw-r--r--scripts/kconfig/expr.h5
-rw-r--r--scripts/kconfig/list.h91
-rw-r--r--scripts/kconfig/lkc_proto.h4
-rw-r--r--scripts/kconfig/mconf.c6
-rw-r--r--scripts/kconfig/menu.c14
-rwxr-xr-xscripts/sign-file6
-rw-r--r--security/device_cgroup.c18
-rw-r--r--security/selinux/netnode.c3
-rw-r--r--sound/core/oss/mixer_oss.c1
-rw-r--r--sound/core/oss/pcm_oss.c1
-rw-r--r--sound/core/pcm_native.c6
-rw-r--r--sound/core/sound.c2
-rw-r--r--sound/core/sound_oss.c2
-rw-r--r--sound/i2c/other/ak4113.c2
-rw-r--r--sound/i2c/other/ak4114.c2
-rw-r--r--sound/i2c/other/ak4117.c2
-rw-r--r--sound/pci/es1968.c11
-rw-r--r--sound/pci/fm801.c11
-rw-r--r--sound/pci/hda/hda_codec.c11
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_intel.c41
-rw-r--r--sound/pci/hda/patch_analog.c1
-rw-r--r--sound/pci/hda/patch_cirrus.c22
-rw-r--r--sound/pci/hda/patch_realtek.c28
-rw-r--r--sound/pci/hda/patch_via.c36
-rw-r--r--sound/pci/rme9652/hdspm.c5
-rw-r--r--sound/soc/codecs/arizona.c4
-rw-r--r--sound/soc/codecs/cs4271.c11
-rw-r--r--sound/soc/codecs/cs42l52.c5
-rw-r--r--sound/soc/codecs/wm5102.c552
-rw-r--r--sound/soc/codecs/wm8978.c2
-rw-r--r--sound/soc/codecs/wm8994.c2
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.c3
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c74
-rw-r--r--sound/soc/mxs/mxs-saif.c17
-rw-r--r--sound/soc/samsung/Kconfig2
-rw-r--r--sound/soc/samsung/bells.c2
-rw-r--r--sound/soc/soc-core.c5
-rw-r--r--sound/soc/soc-dapm.c2
-rw-r--r--sound/usb/card.c6
-rw-r--r--sound/usb/endpoint.c13
-rw-r--r--sound/usb/endpoint.h1
-rw-r--r--sound/usb/midi.c8
-rw-r--r--sound/usb/pcm.c5
-rw-r--r--tools/power/x86/turbostat/turbostat.c28
-rw-r--r--tools/testing/selftests/Makefile2
-rw-r--r--tools/testing/selftests/epoll/Makefile11
-rw-r--r--tools/testing/selftests/epoll/test_epoll.c344
491 files changed, 5396 insertions, 2604 deletions
diff --git a/CREDITS b/CREDITS
index d8fe12a9421..2346b09ca8b 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1823,6 +1823,11 @@ S: Kattreinstr 38
S: D-64295
S: Germany
+N: Avi Kivity
+E: avi.kivity@gmail.com
+D: Kernel-based Virtual Machine (KVM)
+S: Ra'annana, Israel
+
N: Andi Kleen
E: andi@firstfloor.org
U: http://www.halobates.de
diff --git a/Documentation/arm64/memory.txt b/Documentation/arm64/memory.txt
index dbbdcbba75a..4110cca96bd 100644
--- a/Documentation/arm64/memory.txt
+++ b/Documentation/arm64/memory.txt
@@ -27,17 +27,17 @@ Start End Size Use
-----------------------------------------------------------------------
0000000000000000 0000007fffffffff 512GB user
-ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc
+ffffff8000000000 ffffffbbfffeffff ~240GB vmalloc
-ffffffbbfffd0000 ffffffbcfffdffff 64KB [guard page]
+ffffffbbffff0000 ffffffbbffffffff 64KB [guard page]
-ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O space
+ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
-ffffffbbffff0000 ffffffbcffffffff 64KB [guard page]
+ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap]
-ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
+ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space
-ffffffbe00000000 ffffffbffbffffff ~8GB [guard, future vmmemap]
+ffffffbbffff0000 ffffffbcffffffff ~2MB [guard]
ffffffbffc000000 ffffffbfffffffff 64MB modules
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
index c07f7b4fb88..71c4da41344 100644
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -466,6 +466,10 @@ Note:
5.3 swappiness
Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
+Please note that unlike the global swappiness, memcg knob set to 0
+really prevents from any swapping even if there is a swap storage
+available. This might lead to memcg OOM killer if there are no file
+pages to reclaim.
Following cgroups' swappiness can't be changed.
- root cgroup (uses /proc/sys/vm/swappiness).
diff --git a/Documentation/devicetree/bindings/net/mdio-gpio.txt b/Documentation/devicetree/bindings/net/mdio-gpio.txt
index bc954952901..c79bab02536 100644
--- a/Documentation/devicetree/bindings/net/mdio-gpio.txt
+++ b/Documentation/devicetree/bindings/net/mdio-gpio.txt
@@ -8,9 +8,16 @@ gpios property as described in section VIII.1 in the following order:
MDC, MDIO.
+Note: Each gpio-mdio bus should have an alias correctly numbered in "aliases"
+node.
+
Example:
-mdio {
+aliases {
+ mdio-gpio0 = <&mdio0>;
+};
+
+mdio0: mdio {
compatible = "virtual,mdio-gpio";
#address-cells = <1>;
#size-cells = <0>;
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index a1793d670cd..3844d21d6ca 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -33,7 +33,7 @@ Table of Contents
2 Modifying System Parameters
3 Per-Process Parameters
- 3.1 /proc/<pid>/oom_score_adj - Adjust the oom-killer
+ 3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj - Adjust the oom-killer
score
3.2 /proc/<pid>/oom_score - Display current oom-killer score
3.3 /proc/<pid>/io - Display the IO accounting fields
@@ -1320,10 +1320,10 @@ of the kernel.
CHAPTER 3: PER-PROCESS PARAMETERS
------------------------------------------------------------------------------
-3.1 /proc/<pid>/oom_score_adj- Adjust the oom-killer score
+3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj- Adjust the oom-killer score
--------------------------------------------------------------------------------
-This file can be used to adjust the badness heuristic used to select which
+These file can be used to adjust the badness heuristic used to select which
process gets killed in out of memory conditions.
The badness heuristic assigns a value to each candidate task ranging from 0
@@ -1361,6 +1361,12 @@ same system, cpuset, mempolicy, or memory controller resources to use at least
equivalent to discounting 50% of the task's allowed memory from being considered
as scoring against the task.
+For backwards compatibility with previous kernels, /proc/<pid>/oom_adj may also
+be used to tune the badness score. Its acceptable values range from -16
+(OOM_ADJUST_MIN) to +15 (OOM_ADJUST_MAX) and a special value of -17
+(OOM_DISABLE) to disable oom killing entirely for that task. Its value is
+scaled linearly with /proc/<pid>/oom_score_adj.
+
The value of /proc/<pid>/oom_score_adj may be reduced no lower than the last
value set by a CAP_SYS_RESOURCE process. To reduce the value any lower
requires CAP_SYS_RESOURCE.
@@ -1375,7 +1381,9 @@ minimal amount of work.
-------------------------------------------------------------
This file can be used to check the current score used by the oom-killer is for
-any given <pid>.
+any given <pid>. Use it together with /proc/<pid>/oom_score_adj to tune which
+process should be killed in an out-of-memory situation.
+
3.3 /proc/<pid>/io - Display the IO accounting fields
-------------------------------------------------------
diff --git a/Documentation/networking/netdev-features.txt b/Documentation/networking/netdev-features.txt
index 4164f5c02e4..f310edec8a7 100644
--- a/Documentation/networking/netdev-features.txt
+++ b/Documentation/networking/netdev-features.txt
@@ -164,4 +164,4 @@ read the CRC recorded by the NIC on receipt of the packet.
This requests that the NIC receive all possible frames, including errored
frames (such as bad FCS, etc). This can be helpful when sniffing a link with
bad packets on it. Some NICs may receive more packets if also put into normal
-PROMISC mdoe.
+PROMISC mode.
diff --git a/Documentation/networking/vxlan.txt b/Documentation/networking/vxlan.txt
index 5b34b762d7d..6d993510f09 100644
--- a/Documentation/networking/vxlan.txt
+++ b/Documentation/networking/vxlan.txt
@@ -32,7 +32,7 @@ no entry is in the forwarding table.
# ip link delete vxlan0
3. Show vxlan info
- # ip -d show vxlan0
+ # ip -d link show vxlan0
It is possible to create, destroy and display the vxlan
forwarding table using the new bridge command.
@@ -41,7 +41,7 @@ forwarding table using the new bridge command.
# bridge fdb add to 00:17:42:8a:b4:05 dst 192.19.0.2 dev vxlan0
2. Delete forwarding table entry
- # bridge fdb delete 00:17:42:8a:b4:05
+ # bridge fdb delete 00:17:42:8a:b4:05 dev vxlan0
3. Show forwarding table
# bridge fdb show dev vxlan0
diff --git a/MAINTAINERS b/MAINTAINERS
index 59203e77ce9..244b2f229e5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -526,10 +526,10 @@ F: drivers/video/geode/
F: arch/x86/include/asm/geode.h
AMD IOMMU (AMD-VI)
-M: Joerg Roedel <joerg.roedel@amd.com>
+M: Joerg Roedel <joro@8bytes.org>
L: iommu@lists.linux-foundation.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
-S: Supported
+S: Maintained
F: drivers/iommu/amd_iommu*.[ch]
F: include/linux/amd-iommu.h
@@ -841,6 +841,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git
F: arch/arm/mach-sa1100/jornada720.c
F: arch/arm/mach-sa1100/include/mach/jornada720.h
+ARM/IGEP MACHINE SUPPORT
+M: Enric Balletbo i Serra <eballetbo@gmail.com>
+M: Javier Martinez Canillas <javier@dowhile0.org>
+L: linux-omap@vger.kernel.org
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm/mach-omap2/board-igep0020.c
+
ARM/INCOME PXA270 SUPPORT
M: Marek Vasut <marek.vasut@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -3598,6 +3606,49 @@ F: drivers/hid/hid-hyperv.c
F: drivers/net/hyperv/
F: drivers/staging/hv/
+I2C OVER PARALLEL PORT
+M: Jean Delvare <khali@linux-fr.org>
+L: linux-i2c@vger.kernel.org
+S: Maintained
+F: Documentation/i2c/busses/i2c-parport
+F: Documentation/i2c/busses/i2c-parport-light
+F: drivers/i2c/busses/i2c-parport.c
+F: drivers/i2c/busses/i2c-parport-light.c
+
+I2C/SMBUS CONTROLLER DRIVERS FOR PC
+M: Jean Delvare <khali@linux-fr.org>
+L: linux-i2c@vger.kernel.org
+S: Maintained
+F: Documentation/i2c/busses/i2c-ali1535
+F: Documentation/i2c/busses/i2c-ali1563
+F: Documentation/i2c/busses/i2c-ali15x3
+F: Documentation/i2c/busses/i2c-amd756
+F: Documentation/i2c/busses/i2c-amd8111
+F: Documentation/i2c/busses/i2c-i801
+F: Documentation/i2c/busses/i2c-nforce2
+F: Documentation/i2c/busses/i2c-piix4
+F: Documentation/i2c/busses/i2c-sis5595
+F: Documentation/i2c/busses/i2c-sis630
+F: Documentation/i2c/busses/i2c-sis96x
+F: Documentation/i2c/busses/i2c-via
+F: Documentation/i2c/busses/i2c-viapro
+F: drivers/i2c/busses/i2c-ali1535.c
+F: drivers/i2c/busses/i2c-ali1563.c
+F: drivers/i2c/busses/i2c-ali15x3.c
+F: drivers/i2c/busses/i2c-amd756.c
+F: drivers/i2c/busses/i2c-amd756-s4882.c
+F: drivers/i2c/busses/i2c-amd8111.c
+F: drivers/i2c/busses/i2c-i801.c
+F: drivers/i2c/busses/i2c-isch.c
+F: drivers/i2c/busses/i2c-nforce2.c
+F: drivers/i2c/busses/i2c-nforce2-s4985.c
+F: drivers/i2c/busses/i2c-piix4.c
+F: drivers/i2c/busses/i2c-sis5595.c
+F: drivers/i2c/busses/i2c-sis630.c
+F: drivers/i2c/busses/i2c-sis96x.c
+F: drivers/i2c/busses/i2c-via.c
+F: drivers/i2c/busses/i2c-viapro.c
+
I2C/SMBUS STUB DRIVER
M: "Mark M. Hoffman" <mhoffman@lightlink.com>
L: linux-i2c@vger.kernel.org
@@ -3605,9 +3656,8 @@ S: Maintained
F: drivers/i2c/busses/i2c-stub.c
I2C SUBSYSTEM
-M: "Jean Delvare (PC drivers, core)" <khali@linux-fr.org>
+M: Wolfram Sang <w.sang@pengutronix.de>
M: "Ben Dooks (embedded platforms)" <ben-linux@fluff.org>
-M: "Wolfram Sang (embedded platforms)" <w.sang@pengutronix.de>
L: linux-i2c@vger.kernel.org
W: http://i2c.wiki.kernel.org/
T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/
@@ -3618,6 +3668,13 @@ F: drivers/i2c/
F: include/linux/i2c.h
F: include/linux/i2c-*.h
+I2C-TAOS-EVM DRIVER
+M: Jean Delvare <khali@linux-fr.org>
+L: linux-i2c@vger.kernel.org
+S: Maintained
+F: Documentation/i2c/busses/i2c-taos-evm
+F: drivers/i2c/busses/i2c-taos-evm.c
+
I2C-TINY-USB DRIVER
M: Till Harbaum <till@harbaum.org>
L: linux-i2c@vger.kernel.org
@@ -4231,8 +4288,8 @@ F: include/linux/lockd/
F: include/linux/sunrpc/
KERNEL VIRTUAL MACHINE (KVM)
-M: Avi Kivity <avi@redhat.com>
M: Marcelo Tosatti <mtosatti@redhat.com>
+M: Gleb Natapov <gleb@redhat.com>
L: kvm@vger.kernel.org
W: http://kvm.qumranet.com
S: Supported
@@ -7210,6 +7267,14 @@ L: linux-xtensa@linux-xtensa.org
S: Maintained
F: arch/xtensa/
+THERMAL
+M: Zhang Rui <rui.zhang@intel.com>
+L: linux-pm@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git
+S: Supported
+F: drivers/thermal/
+F: include/linux/thermal.h
+
THINKPAD ACPI EXTRAS DRIVER
M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br>
L: ibm-acpi-devel@lists.sourceforge.net
@@ -7887,13 +7952,6 @@ M: Roger Luethi <rl@hellgate.ch>
S: Maintained
F: drivers/net/ethernet/via/via-rhine.c
-VIAPRO SMBUS DRIVER
-M: Jean Delvare <khali@linux-fr.org>
-L: linux-i2c@vger.kernel.org
-S: Maintained
-F: Documentation/i2c/busses/i2c-viapro
-F: drivers/i2c/busses/i2c-viapro.c
-
VIA SD/MMC CARD CONTROLLER DRIVER
M: Bruce Chang <brucechang@via.com.tw>
M: Harald Welte <HaraldWelte@viatech.com>
diff --git a/Makefile b/Makefile
index a1ccf225c4e..9f6ca124e89 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 3
PATCHLEVEL = 7
SUBLEVEL = 0
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc6
NAME = Terrified Chipmunk
# *DOCUMENTATION*
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 1e6956a9060..14db93e4c8a 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -445,7 +445,7 @@ struct procfs_args {
* unhappy with OSF UFS. [CHECKME]
*/
static int
-osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
+osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags)
{
int retval;
struct cdfs_args tmp;
@@ -465,7 +465,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
}
static int
-osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
+osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags)
{
int retval;
struct cdfs_args tmp;
@@ -485,7 +485,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
}
static int
-osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags)
+osf_procfs_mount(const char *dirname, struct procfs_args __user *args, int flags)
{
struct procfs_args tmp;
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index f2aa09eb658..9137df539b6 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -33,7 +33,7 @@ ifeq ($(CONFIG_XIP_KERNEL),y)
$(obj)/xipImage: vmlinux FORCE
$(call if_changed,objcopy)
- $(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))'
+ @$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))'
$(obj)/Image $(obj)/zImage: FORCE
@echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)'
@@ -48,14 +48,14 @@ $(obj)/xipImage: FORCE
$(obj)/Image: vmlinux FORCE
$(call if_changed,objcopy)
- $(kecho) ' Kernel: $@ is ready'
+ @$(kecho) ' Kernel: $@ is ready'
$(obj)/compressed/vmlinux: $(obj)/Image FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
- $(kecho) ' Kernel: $@ is ready'
+ @$(kecho) ' Kernel: $@ is ready'
endif
@@ -90,7 +90,7 @@ fi
$(obj)/uImage: $(obj)/zImage FORCE
@$(check_for_multiple_loadaddr)
$(call if_changed,uimage)
- $(kecho) ' Image $@ is ready'
+ @$(kecho) ' Image $@ is ready'
$(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
$(Q)$(MAKE) $(build)=$(obj)/bootp $@
@@ -98,7 +98,7 @@ $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
$(obj)/bootpImage: $(obj)/bootp/bootp FORCE
$(call if_changed,objcopy)
- $(kecho) ' Kernel: $@ is ready'
+ @$(kecho) ' Kernel: $@ is ready'
PHONY += initrd FORCE
initrd:
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index b1497c7d7d6..df7f2270fc9 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -73,8 +73,8 @@
pinmux: pinmux {
compatible = "nvidia,tegra30-pinmux";
- reg = <0x70000868 0xd0 /* Pad control registers */
- 0x70003000 0x3e0>; /* Mux registers */
+ reg = <0x70000868 0xd4 /* Pad control registers */
+ 0x70003000 0x3e4>; /* Mux registers */
};
serial@70006000 {
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 35c1ed89b93..42f042ee4ad 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -64,7 +64,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
static inline void __raw_writew(u16 val, volatile void __iomem *addr)
{
asm volatile("strh %1, %0"
- : "+Qo" (*(volatile u16 __force *)addr)
+ : "+Q" (*(volatile u16 __force *)addr)
: "r" (val));
}
@@ -72,7 +72,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr)
{
u16 val;
asm volatile("ldrh %1, %0"
- : "+Qo" (*(volatile u16 __force *)addr),
+ : "+Q" (*(volatile u16 __force *)addr),
"=r" (val));
return val;
}
diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h
index 05b8e82ec9f..e3f75726343 100644
--- a/arch/arm/include/asm/sched_clock.h
+++ b/arch/arm/include/asm/sched_clock.h
@@ -10,7 +10,5 @@
extern void sched_clock_postinit(void);
extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate);
-extern void setup_sched_clock_needs_suspend(u32 (*read)(void), int bits,
- unsigned long rate);
#endif
diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h
index 6a6f1e485f4..301c1db3e99 100644
--- a/arch/arm/include/asm/vfpmacros.h
+++ b/arch/arm/include/asm/vfpmacros.h
@@ -27,9 +27,9 @@
#if __LINUX_ARM_ARCH__ <= 6
ldr \tmp, =elf_hwcap @ may not have MVFR regs
ldr \tmp, [\tmp, #0]
- tst \tmp, #HWCAP_VFPv3D16
- ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
- addne \base, \base, #32*4 @ step over unused register space
+ tst \tmp, #HWCAP_VFPD32
+ ldcnel p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
+ addeq \base, \base, #32*4 @ step over unused register space
#else
VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field
@@ -51,9 +51,9 @@
#if __LINUX_ARM_ARCH__ <= 6
ldr \tmp, =elf_hwcap @ may not have MVFR regs
ldr \tmp, [\tmp, #0]
- tst \tmp, #HWCAP_VFPv3D16
- stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
- addne \base, \base, #32*4 @ step over unused register space
+ tst \tmp, #HWCAP_VFPD32
+ stcnel p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
+ addeq \base, \base, #32*4 @ step over unused register space
#else
VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field
diff --git a/arch/arm/include/uapi/asm/hwcap.h b/arch/arm/include/uapi/asm/hwcap.h
index f254f6503cc..3688fd15a32 100644
--- a/arch/arm/include/uapi/asm/hwcap.h
+++ b/arch/arm/include/uapi/asm/hwcap.h
@@ -18,11 +18,12 @@
#define HWCAP_THUMBEE (1 << 11)
#define HWCAP_NEON (1 << 12)
#define HWCAP_VFPv3 (1 << 13)
-#define HWCAP_VFPv3D16 (1 << 14)
+#define HWCAP_VFPv3D16 (1 << 14) /* also set for VFPv4-D16 */
#define HWCAP_TLS (1 << 15)
#define HWCAP_VFPv4 (1 << 16)
#define HWCAP_IDIVA (1 << 17)
#define HWCAP_IDIVT (1 << 18)
+#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */
#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
index e21bac20d90..fc6692e2b60 100644
--- a/arch/arm/kernel/sched_clock.c
+++ b/arch/arm/kernel/sched_clock.c
@@ -107,13 +107,6 @@ static void sched_clock_poll(unsigned long wrap_ticks)
update_sched_clock();
}
-void __init setup_sched_clock_needs_suspend(u32 (*read)(void), int bits,
- unsigned long rate)
-{
- setup_sched_clock(read, bits, rate);
- cd.needs_suspend = true;
-}
-
void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
{
unsigned long r, w;
@@ -189,18 +182,15 @@ void __init sched_clock_postinit(void)
static int sched_clock_suspend(void)
{
sched_clock_poll(sched_clock_timer.data);
- if (cd.needs_suspend)
- cd.suspended = true;
+ cd.suspended = true;
return 0;
}
static void sched_clock_resume(void)
{
- if (cd.needs_suspend) {
- cd.epoch_cyc = read_sched_clock();
- cd.epoch_cyc_copy = cd.epoch_cyc;
- cd.suspended = false;
- }
+ cd.epoch_cyc = read_sched_clock();
+ cd.epoch_cyc_copy = cd.epoch_cyc;
+ cd.suspended = false;
}
static struct syscore_ops sched_clock_ops = {
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 1e122bcd784..3cee0e6ea7c 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -68,7 +68,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
/* Enable overcurrent notification */
for (i = 0; i < data->ports; i++) {
- if (data->overcurrent_pin[i])
+ if (gpio_is_valid(data->overcurrent_pin[i]))
at91_set_gpio_input(data->overcurrent_pin[i], 1);
}
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index aa1e5872988..414bd855fb0 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
/* Enable overcurrent notification */
for (i = 0; i < data->ports; i++) {
- if (data->overcurrent_pin[i])
+ if (gpio_is_valid(data->overcurrent_pin[i]))
at91_set_gpio_input(data->overcurrent_pin[i], 1);
}
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index b9487696b7b..cd604aad8e9 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
/* Enable overcurrent notification */
for (i = 0; i < data->ports; i++) {
- if (data->overcurrent_pin[i])
+ if (gpio_is_valid(data->overcurrent_pin[i]))
at91_set_gpio_input(data->overcurrent_pin[i], 1);
}
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index cb85da2ecce..9c61e59a210 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -78,7 +78,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
/* Enable overcurrent notification */
for (i = 0; i < data->ports; i++) {
- if (data->overcurrent_pin[i])
+ if (gpio_is_valid(data->overcurrent_pin[i]))
at91_set_gpio_input(data->overcurrent_pin[i], 1);
}
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index b1596072dcc..fcd233cb33d 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -1841,8 +1841,8 @@ static struct resource sha_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = AT91SAM9G45_ID_AESTDESSHA,
- .end = AT91SAM9G45_ID_AESTDESSHA,
+ .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
+ .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
.flags = IORESOURCE_IRQ,
},
};
@@ -1874,8 +1874,8 @@ static struct resource tdes_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = AT91SAM9G45_ID_AESTDESSHA,
- .end = AT91SAM9G45_ID_AESTDESSHA,
+ .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
+ .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
.flags = IORESOURCE_IRQ,
},
};
@@ -1910,8 +1910,8 @@ static struct resource aes_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = AT91SAM9G45_ID_AESTDESSHA,
- .end = AT91SAM9G45_ID_AESTDESSHA,
+ .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
+ .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
.flags = IORESOURCE_IRQ,
},
};
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index cd0c8b1e1ec..14e9947bad6 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -713,8 +713,7 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type,
break;
case VPBE_ENC_CUSTOM_TIMINGS:
if (pclock <= 27000000) {
- v |= DM644X_VPSS_MUXSEL_PLL2_MODE |
- DM644X_VPSS_DACCLKEN;
+ v |= DM644X_VPSS_DACCLKEN;
writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
} else {
/*
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
index 21d568b3b14..87e07d6fc61 100644
--- a/arch/arm/mach-exynos/dma.c
+++ b/arch/arm/mach-exynos/dma.c
@@ -275,6 +275,9 @@ static int __init exynos_dma_init(void)
exynos_pdma1_pdata.nr_valid_peri =
ARRAY_SIZE(exynos4210_pdma1_peri);
exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri;
+
+ if (samsung_rev() == EXYNOS4210_REV_0)
+ exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1;
} else if (soc_is_exynos4212() || soc_is_exynos4412()) {
exynos_pdma0_pdata.nr_valid_peri =
ARRAY_SIZE(exynos4212_pdma0_peri);
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 8480849affb..ed4da4544cd 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -90,6 +90,7 @@
#define EXYNOS4_PA_MDMA0 0x10810000
#define EXYNOS4_PA_MDMA1 0x12850000
+#define EXYNOS4_PA_S_MDMA1 0x12840000
#define EXYNOS4_PA_PDMA0 0x12680000
#define EXYNOS4_PA_PDMA1 0x12690000
#define EXYNOS5_PA_MDMA0 0x10800000
diff --git a/arch/arm/mach-highbank/system.c b/arch/arm/mach-highbank/system.c
index 82c27230d4a..86e37cd9376 100644
--- a/arch/arm/mach-highbank/system.c
+++ b/arch/arm/mach-highbank/system.c
@@ -28,6 +28,7 @@ void highbank_restart(char mode, const char *cmd)
hignbank_set_pwr_soft_reset();
scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
- cpu_do_idle();
+ while (1)
+ cpu_do_idle();
}
diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
index 3c1b8ff9a0a..cc49c7ae186 100644
--- a/arch/arm/mach-imx/clk-gate2.c
+++ b/arch/arm/mach-imx/clk-gate2.c
@@ -112,7 +112,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
clk = clk_register(dev, &gate->hw);
if (IS_ERR(clk))
- kfree(clk);
+ kfree(gate);
return clk;
}
diff --git a/arch/arm/mach-imx/ehci-imx25.c b/arch/arm/mach-imx/ehci-imx25.c
index 412c583a24b..576af744695 100644
--- a/arch/arm/mach-imx/ehci-imx25.c
+++ b/arch/arm/mach-imx/ehci-imx25.c
@@ -30,7 +30,7 @@
#define MX25_H1_SIC_SHIFT 21
#define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
#define MX25_H1_PP_BIT (1 << 18)
-#define MX25_H1_PM_BIT (1 << 8)
+#define MX25_H1_PM_BIT (1 << 16)
#define MX25_H1_IPPUE_UP_BIT (1 << 7)
#define MX25_H1_IPPUE_DOWN_BIT (1 << 6)
#define MX25_H1_TLL_BIT (1 << 5)
diff --git a/arch/arm/mach-imx/ehci-imx35.c b/arch/arm/mach-imx/ehci-imx35.c
index 779e16eb65c..293397852e4 100644
--- a/arch/arm/mach-imx/ehci-imx35.c
+++ b/arch/arm/mach-imx/ehci-imx35.c
@@ -30,7 +30,7 @@
#define MX35_H1_SIC_SHIFT 21
#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT)
#define MX35_H1_PP_BIT (1 << 18)
-#define MX35_H1_PM_BIT (1 << 8)
+#define MX35_H1_PM_BIT (1 << 16)
#define MX35_H1_IPPUE_UP_BIT (1 << 7)
#define MX35_H1_IPPUE_DOWN_BIT (1 << 6)
#define MX35_H1_TLL_BIT (1 << 5)
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 48d5e41dfbf..37859069444 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -580,6 +580,11 @@ static void __init igep_wlan_bt_init(void)
} else
return;
+ /* Make sure that the GPIO pins are muxed correctly */
+ omap_mux_init_gpio(igep_wlan_bt_gpios[0].gpio, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(igep_wlan_bt_gpios[1].gpio, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(igep_wlan_bt_gpios[2].gpio, OMAP_PIN_OUTPUT);
+
err = gpio_request_array(igep_wlan_bt_gpios,
ARRAY_SIZE(igep_wlan_bt_gpios));
if (err) {
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index b56d06b4878..95192a062d5 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS,
.wkdep_srcs = iss_wkup_sleep_deps,
.sleepdep_srcs = iss_wkup_sleep_deps,
- .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .flags = CLKDM_CAN_SWSUP,
};
static struct clockdomain l3_dss_44xx_clkdm = {
diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c
index 48daac2581b..84551f205e4 100644
--- a/arch/arm/mach-omap2/common-board-devices.c
+++ b/arch/arm/mach-omap2/common-board-devices.c
@@ -64,30 +64,36 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
struct spi_board_info *spi_bi = &ads7846_spi_board_info;
int err;
- err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
- if (err) {
- pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
- return;
- }
+ /*
+ * If a board defines get_pendown_state() function, request the pendown
+ * GPIO and set the GPIO debounce time.
+ * If a board does not define the get_pendown_state() function, then
+ * the ads7846 driver will setup the pendown GPIO itself.
+ */
+ if (board_pdata && board_pdata->get_pendown_state) {
+ err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
+ if (err) {
+ pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
+ return;
+ }
- if (gpio_debounce)
- gpio_set_debounce(gpio_pendown, gpio_debounce);
+ if (gpio_debounce)
+ gpio_set_debounce(gpio_pendown, gpio_debounce);
+
+ gpio_export(gpio_pendown, 0);
+ }
spi_bi->bus_num = bus_num;
spi_bi->irq = gpio_to_irq(gpio_pendown);
+ ads7846_config.gpio_pendown = gpio_pendown;
+
if (board_pdata) {
board_pdata->gpio_pendown = gpio_pendown;
+ board_pdata->gpio_pendown_debounce = gpio_debounce;
spi_bi->platform_data = board_pdata;
- if (board_pdata->get_pendown_state)
- gpio_export(gpio_pendown, 0);
- } else {
- ads7846_config.gpio_pendown = gpio_pendown;
}
- if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state))
- gpio_free(gpio_pendown);
-
spi_register_board_info(&ads7846_spi_board_info, 1);
}
#else
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index cba60e05e32..c72b5a72772 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -19,6 +19,7 @@
#include <linux/of.h>
#include <linux/pinctrl/machine.h>
#include <linux/platform_data/omap4-keypad.h>
+#include <linux/platform_data/omap_ocp2scp.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
@@ -613,6 +614,83 @@ static void omap_init_vout(void)
static inline void omap_init_vout(void) {}
#endif
+#if defined(CONFIG_OMAP_OCP2SCP) || defined(CONFIG_OMAP_OCP2SCP_MODULE)
+static int count_ocp2scp_devices(struct omap_ocp2scp_dev *ocp2scp_dev)
+{
+ int cnt = 0;
+
+ while (ocp2scp_dev->drv_name != NULL) {
+ cnt++;
+ ocp2scp_dev++;
+ }
+
+ return cnt;
+}
+
+static void omap_init_ocp2scp(void)
+{
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+ int bus_id = -1, dev_cnt = 0, i;
+ struct omap_ocp2scp_dev *ocp2scp_dev;
+ const char *oh_name, *name;
+ struct omap_ocp2scp_platform_data *pdata;
+
+ if (!cpu_is_omap44xx())
+ return;
+
+ oh_name = "ocp2scp_usb_phy";
+ name = "omap-ocp2scp";
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("%s: could not find omap_hwmod for %s\n", __func__,
+ oh_name);
+ return;
+ }
+
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ pr_err("%s: No memory for ocp2scp pdata\n", __func__);
+ return;
+ }
+
+ ocp2scp_dev = oh->dev_attr;
+ dev_cnt = count_ocp2scp_devices(ocp2scp_dev);
+
+ if (!dev_cnt) {
+ pr_err("%s: No devices connected to ocp2scp\n", __func__);
+ kfree(pdata);
+ return;
+ }
+
+ pdata->devices = kzalloc(sizeof(struct omap_ocp2scp_dev *)
+ * dev_cnt, GFP_KERNEL);
+ if (!pdata->devices) {
+ pr_err("%s: No memory for ocp2scp pdata devices\n", __func__);
+ kfree(pdata);
+ return;
+ }
+
+ for (i = 0; i < dev_cnt; i++, ocp2scp_dev++)
+ pdata->devices[i] = ocp2scp_dev;
+
+ pdata->dev_cnt = dev_cnt;
+
+ pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL,
+ 0, false);
+ if (IS_ERR(pdev)) {
+ pr_err("Could not build omap_device for %s %s\n",
+ name, oh_name);
+ kfree(pdata->devices);
+ kfree(pdata);
+ return;
+ }
+}
+#else
+static inline void omap_init_ocp2scp(void) { }
+#endif
+
/*-------------------------------------------------------------------------*/
static int __init omap2_init_devices(void)
@@ -640,6 +718,7 @@ static int __init omap2_init_devices(void)
omap_init_sham();
omap_init_aes();
omap_init_vout();
+ omap_init_ocp2scp();
return 0;
}
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index b969ab1d258..87cc6d058de 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -422,6 +422,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)
}
/**
+ * _wait_softreset_complete - wait for an OCP softreset to complete
+ * @oh: struct omap_hwmod * to wait on
+ *
+ * Wait until the IP block represented by @oh reports that its OCP
+ * softreset is complete. This can be triggered by software (see
+ * _ocp_softreset()) or by hardware upon returning from off-mode (one
+ * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT
+ * microseconds. Returns the number of microseconds waited.
+ */
+static int _wait_softreset_complete(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_class_sysconfig *sysc;
+ u32 softrst_mask;
+ int c = 0;
+
+ sysc = oh->class->sysc;
+
+ if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
+ omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs)
+ & SYSS_RESETDONE_MASK),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+ else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
+ softrst_mask = (0x1 << sysc->sysc_fields->srst_shift);
+ omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs)
+ & softrst_mask),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+ }
+
+ return c;
+}
+
+/**
* _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v
* @oh: struct omap_hwmod *
*
@@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh)
if (!oh->class->sysc)
return;
+ /*
+ * Wait until reset has completed, this is needed as the IP
+ * block is reset automatically by hardware in some cases
+ * (off-mode for example), and the drivers require the
+ * IP to be ready when they access it
+ */
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
+ _enable_optional_clocks(oh);
+ _wait_softreset_complete(oh);
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
+ _disable_optional_clocks(oh);
+
v = oh->_sysc_cache;
sf = oh->class->sysc->sysc_flags;
@@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)
*/
static int _ocp_softreset(struct omap_hwmod *oh)
{
- u32 v, softrst_mask;
+ u32 v;
int c = 0;
int ret = 0;
@@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh)
if (oh->class->sysc->srst_udelay)
udelay(oh->class->sysc->srst_udelay);
- if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
- omap_test_timeout((omap_hwmod_read(oh,
- oh->class->sysc->syss_offs)
- & SYSS_RESETDONE_MASK),
- MAX_MODULE_SOFTRESET_WAIT, c);
- else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
- softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
- omap_test_timeout(!(omap_hwmod_read(oh,
- oh->class->sysc->sysc_offs)
- & softrst_mask),
- MAX_MODULE_SOFTRESET_WAIT, c);
- }
-
+ c = _wait_softreset_complete(oh);
if (c == MAX_MODULE_SOFTRESET_WAIT)
pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
oh->name, MAX_MODULE_SOFTRESET_WAIT);
@@ -2352,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh)
if (oh->_state != _HWMOD_STATE_INITIALIZED)
return -EINVAL;
+ if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK)
+ return -EPERM;
+
if (oh->rst_lines_cnt == 0) {
r = _enable(oh);
if (r) {
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 652d0285bd6..0b1249e0039 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -21,6 +21,7 @@
#include <linux/io.h>
#include <linux/platform_data/gpio-omap.h>
#include <linux/power/smartreflex.h>
+#include <linux/platform_data/omap_ocp2scp.h>
#include <plat/omap_hwmod.h>
#include <plat/i2c.h>
@@ -2125,6 +2126,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = {
.name = "mcpdm",
.class = &omap44xx_mcpdm_hwmod_class,
.clkdm_name = "abe_clkdm",
+ /*
+ * It's suspected that the McPDM requires an off-chip main
+ * functional clock, controlled via I2C. This IP block is
+ * currently reset very early during boot, before I2C is
+ * available, so it doesn't seem that we have any choice in
+ * the kernel other than to avoid resetting it.
+ */
+ .flags = HWMOD_EXT_OPT_MAIN_CLK,
.mpu_irqs = omap44xx_mcpdm_irqs,
.sdma_reqs = omap44xx_mcpdm_sdma_reqs,
.main_clk = "mcpdm_fck",
@@ -2681,6 +2690,32 @@ static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = {
.sysc = &omap44xx_ocp2scp_sysc,
};
+/* ocp2scp dev_attr */
+static struct resource omap44xx_usb_phy_and_pll_addrs[] = {
+ {
+ .name = "usb_phy",
+ .start = 0x4a0ad080,
+ .end = 0x4a0ae000,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* XXX: Remove this once control module driver is in place */
+ .name = "ctrl_dev",
+ .start = 0x4a002300,
+ .end = 0x4a002303,
+ .flags = IORESOURCE_MEM,
+ },
+ { }
+};
+
+static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = {
+ {
+ .drv_name = "omap-usb2",
+ .res = omap44xx_usb_phy_and_pll_addrs,
+ },
+ { }
+};
+
/* ocp2scp_usb_phy */
static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
.name = "ocp2scp_usb_phy",
@@ -2694,6 +2729,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
.modulemode = MODULEMODE_HWCTRL,
},
},
+ .dev_attr = ocp2scp_dev_attr,
};
/*
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index 635e109f5ad..a256135d8e4 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -73,6 +73,7 @@ void __init omap4_pmic_init(const char *pmic_type,
{
/* PMIC part*/
omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);
+ omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT);
omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data);
/* Register additional devices on i2c1 bus if needed */
@@ -366,7 +367,7 @@ static struct regulator_init_data omap4_clk32kg_idata = {
};
static struct regulator_consumer_supply omap4_vdd1_supply[] = {
- REGULATOR_SUPPLY("vcc", "mpu.0"),
+ REGULATOR_SUPPLY("vcc", "cpu0"),
};
static struct regulator_consumer_supply omap4_vdd2_supply[] = {
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 880249b1701..75878c37959 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -264,7 +264,7 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)
if (initialized) {
if (voltdm->pmic->i2c_high_speed != i2c_high_speed)
- pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).",
+ pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n",
__func__, voltdm->name, i2c_high_speed);
return;
}
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index 5ecbd17b564..e2c6391863f 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -28,6 +28,7 @@
#include <linux/mfd/asic3.h>
#include <linux/mtd/physmap.h>
#include <linux/pda_power.h>
+#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/gpio-regulator.h>
@@ -556,7 +557,7 @@ static struct platform_device hx4700_lcd = {
*/
static struct platform_pwm_backlight_data backlight_data = {
- .pwm_id = 1,
+ .pwm_id = -1, /* Superseded by pwm_lookup */
.max_brightness = 200,
.dft_brightness = 100,
.pwm_period_ns = 30923,
@@ -571,6 +572,10 @@ static struct platform_device backlight = {
},
};
+static struct pwm_lookup hx4700_pwm_lookup[] = {
+ PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL),
+};
+
/*
* USB "Transceiver"
*/
@@ -872,6 +877,7 @@ static void __init hx4700_init(void)
pxa_set_stuart_info(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
+ pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup));
pxa_set_ficp_info(&ficp_info);
pxa27x_set_i2c_power_info(NULL);
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 438f02fe122..842596d4d31 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -86,10 +86,7 @@ static void spitz_discharge1(int on)
gpio_set_value(SPITZ_GPIO_LED_GREEN, on);
}
-static unsigned long gpio18_config[] = {
- GPIO18_RDY,
- GPIO18_GPIO,
-};
+static unsigned long gpio18_config = GPIO18_GPIO;
static void spitz_presuspend(void)
{
@@ -112,7 +109,7 @@ static void spitz_presuspend(void)
PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0);
- pxa2xx_mfp_config(&gpio18_config[0], 1);
+ pxa2xx_mfp_config(&gpio18_config, 1);
gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown");
gpio_free(18);
@@ -131,7 +128,6 @@ static void spitz_presuspend(void)
static void spitz_postsuspend(void)
{
- pxa2xx_mfp_config(&gpio18_config[1], 1);
}
static int spitz_should_wakeup(unsigned int resume_on_alarm)
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 023f443784e..b820edaf318 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -745,7 +745,7 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs,
static int
do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
- union offset_union offset;
+ union offset_union uninitialized_var(offset);
unsigned long instr = 0, instrptr;
int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
unsigned int type;
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index a5683a84c6e..6013831a043 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -26,12 +26,14 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
+#include <linux/i2c-omap.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <mach/irqs.h>
#include <plat/i2c.h>
+#include <plat/omap-pm.h>
#include <plat/omap_device.h>
#define OMAP_I2C_SIZE 0x3f
@@ -127,6 +129,16 @@ static inline int omap1_i2c_add_bus(int bus_id)
#ifdef CONFIG_ARCH_OMAP2PLUS
+/*
+ * XXX This function is a temporary compatibility wrapper - only
+ * needed until the I2C driver can be converted to call
+ * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
+ */
+static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
+{
+ omap_pm_set_max_mpu_wakeup_lat(dev, t);
+}
+
static inline int omap2_i2c_add_bus(int bus_id)
{
int l;
@@ -158,6 +170,15 @@ static inline int omap2_i2c_add_bus(int bus_id)
dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr;
pdata->flags = dev_attr->flags;
+ /*
+ * When waiting for completion of a i2c transfer, we need to
+ * set a wake up latency constraint for the MPU. This is to
+ * ensure quick enough wakeup from idle, when transfer
+ * completes.
+ * Only omap3 has support for constraints
+ */
+ if (cpu_is_omap34xx())
+ pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
pdev = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
NULL, 0, 0);
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index b3349f7b1a2..1db02943802 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -443,6 +443,11 @@ struct omap_hwmod_omap4_prcm {
* in order to complete the reset. Optional clocks will be disabled
* again after the reset.
* HWMOD_16BIT_REG: Module has 16bit registers
+ * HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for
+ * this IP block comes from an off-chip source and is not always
+ * enabled. This prevents the hwmod code from being able to
+ * enable and reset the IP block early. XXX Eventually it should
+ * be possible to query the clock framework for this information.
*/
#define HWMOD_SWSUP_SIDLE (1 << 0)
#define HWMOD_SWSUP_MSTANDBY (1 << 1)
@@ -453,6 +458,7 @@ struct omap_hwmod_omap4_prcm {
#define HWMOD_NO_IDLEST (1 << 6)
#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)
#define HWMOD_16BIT_REG (1 << 8)
+#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9)
/*
* omap_hwmod._int_flags definitions
diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile
index cd60a81163e..32d05c8219d 100644
--- a/arch/arm/tools/Makefile
+++ b/arch/arm/tools/Makefile
@@ -5,6 +5,6 @@
#
include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types
- $(kecho) ' Generating $@'
+ @$(kecho) ' Generating $@'
@mkdir -p $(dir $@)
$(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; }
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index c834b32af27..3b44e0dd0a9 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -701,11 +701,14 @@ static int __init vfp_init(void)
elf_hwcap |= HWCAP_VFPv3;
/*
- * Check for VFPv3 D16. CPUs in this configuration
- * only have 16 x 64bit registers.
+ * Check for VFPv3 D16 and VFPv4 D16. CPUs in
+ * this configuration only have 16 x 64bit
+ * registers.
*/
if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1)
- elf_hwcap |= HWCAP_VFPv3D16;
+ elf_hwcap |= HWCAP_VFPv3D16; /* also v4-D16 */
+ else
+ elf_hwcap |= HWCAP_VFPD32;
}
#endif
/*
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 59bcb96ac36..f5760927544 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -166,3 +166,14 @@ void free_xenballooned_pages(int nr_pages, struct page **pages)
*pages = NULL;
}
EXPORT_SYMBOL_GPL(free_xenballooned_pages);
+
+/* In the hypervisor.S file. */
+EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version);
+EXPORT_SYMBOL_GPL(HYPERVISOR_console_io);
+EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op);
+EXPORT_SYMBOL_GPL(privcmd_call);
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index ef54a59a9e8..15ac18a56c9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1,6 +1,7 @@
config ARM64
def_bool y
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
+ select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
select GENERIC_CLOCKEVENTS
select GENERIC_HARDIRQS_NO_DEPRECATED
select GENERIC_IOMAP
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index cf284649dfc..07fea290d7c 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -25,12 +25,10 @@
#include <asm/user.h>
typedef unsigned long elf_greg_t;
-typedef unsigned long elf_freg_t[3];
#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct user_fp elf_fpregset_t;
+typedef struct user_fpsimd_state elf_fpregset_t;
#define EM_AARCH64 183
@@ -87,7 +85,6 @@ typedef struct user_fp elf_fpregset_t;
#define R_AARCH64_MOVW_PREL_G2_NC 292
#define R_AARCH64_MOVW_PREL_G3 293
-
/*
* These are used to set parameters in the core dumps.
*/
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index b42fab9f62a..c43b4ac1300 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -25,9 +25,8 @@
* - FPSR and FPCR
* - 32 128-bit data registers
*
- * Note that user_fp forms a prefix of this structure, which is relied
- * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must
- * form a prefix of struct fpsimd_state.
+ * Note that user_fpsimd forms a prefix of this structure, which is
+ * relied upon in the ptrace FP/SIMD accessors.
*/
struct fpsimd_state {
union {
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 74a2a7d304a..d2f05a60827 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -114,7 +114,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
* I/O port access primitives.
*/
#define IO_SPACE_LIMIT 0xffff
-#define PCI_IOBASE ((void __iomem *)0xffffffbbfffe0000UL)
+#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M))
static inline u8 inb(unsigned long addr)
{
@@ -222,12 +222,12 @@ extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot
extern void __iounmap(volatile void __iomem *addr);
#define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY)
-#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
+#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC))
-#define ioremap(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE)
-#define ioremap_nocache(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE)
-#define ioremap_wc(addr, size) __ioremap((addr), (size), PROT_NORMAL_NC)
+#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
+#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
+#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
#define iounmap __iounmap
#define ARCH_HAS_IOREMAP_WC
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 0f3b4581d92..75fd13d289b 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -38,7 +38,8 @@
#define PMD_SECT_S (_AT(pmdval_t, 3) << 8)
#define PMD_SECT_AF (_AT(pmdval_t, 1) << 10)
#define PMD_SECT_NG (_AT(pmdval_t, 1) << 11)
-#define PMD_SECT_XN (_AT(pmdval_t, 1) << 54)
+#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 53)
+#define PMD_SECT_UXN (_AT(pmdval_t, 1) << 54)
/*
* AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
@@ -57,7 +58,8 @@
#define PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
#define PTE_AF (_AT(pteval_t, 1) << 10) /* Access Flag */
#define PTE_NG (_AT(pteval_t, 1) << 11) /* nG */
-#define PTE_XN (_AT(pteval_t, 1) << 54) /* XN */
+#define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */
+#define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */
/*
* AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 8960239be72..14aba2db677 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -62,23 +62,23 @@ extern pgprot_t pgprot_default;
#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
-#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_XN | PTE_RDONLY)
-#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN)
-#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG)
-#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
-#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY)
-#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
-#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY)
-#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_XN | PTE_DIRTY)
-#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_DIRTY)
-
-#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_XN | PTE_RDONLY)
-#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN)
-#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG)
-#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
-#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY)
-#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY)
-#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY)
+#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
+#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
+#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
+#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
+#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY)
+#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY)
+
+#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
+#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
+#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
+#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
+#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
#endif /* __ASSEMBLY__ */
@@ -130,10 +130,10 @@ extern struct page *empty_zero_page;
#define pte_young(pte) (pte_val(pte) & PTE_AF)
#define pte_special(pte) (pte_val(pte) & PTE_SPECIAL)
#define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY))
-#define pte_exec(pte) (!(pte_val(pte) & PTE_XN))
+#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN))
#define pte_present_exec_user(pte) \
- ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_XN)) == \
+ ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \
(PTE_VALID | PTE_USER))
#define PTE_BIT_FUNC(fn,op) \
@@ -262,7 +262,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
- const pteval_t mask = PTE_USER | PTE_XN | PTE_RDONLY;
+ const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY;
pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
return pte;
}
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 5d810044fed..77f696c1433 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -43,6 +43,8 @@
#else
#define STACK_TOP STACK_TOP_MAX
#endif /* CONFIG_COMPAT */
+
+#define ARCH_LOW_ADDRESS_LIMIT PHYS_MASK
#endif /* __KERNEL__ */
struct debug_info {
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 63f853f8b71..68aff2816e8 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -14,7 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef CONFIG_COMPAT
-#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION
#define __ARCH_WANT_COMPAT_STAT64
#define __ARCH_WANT_SYS_GETHOSTNAME
#define __ARCH_WANT_SYS_PAUSE
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index ecbf2d81ec5..c76c7241125 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -613,17 +613,11 @@ enum armv8_pmuv3_perf_types {
ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19,
ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A,
ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D,
-
- /*
- * This isn't an architected event.
- * We detect this event number and use the cycle counter instead.
- */
- ARMV8_PMUV3_PERFCTR_CPU_CYCLES = 0xFF,
};
/* PMUv3 HW events mapping. */
static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES,
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED,
[PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
[PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
@@ -1106,7 +1100,7 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc,
unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT;
/* Always place a cycle counter into the cycle counter. */
- if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) {
+ if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) {
if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask))
return -EAGAIN;
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index f22965ea1cf..e04cebdbb47 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -310,24 +310,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
}
/*
- * Fill in the task's elfregs structure for a core dump.
- */
-int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs)
-{
- elf_core_copy_regs(elfregs, task_pt_regs(t));
- return 1;
-}
-
-/*
- * fill in the fpe structure for a core dump...
- */
-int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
-{
- return 0;
-}
-EXPORT_SYMBOL(dump_fpu);
-
-/*
* Shuffle the argument into the correct register before calling the
* thread function. x1 is the thread argument, x2 is the pointer to
* the thread function, and x3 points to the exit function.
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 226b6bf6e9c..538300f2273 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -211,8 +211,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
* before we continue.
*/
set_cpu_online(cpu, true);
- while (!cpu_active(cpu))
- cpu_relax();
+ complete(&cpu_running);
/*
* OK, it's off to the idle thread for us
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index efbf7df05d3..4cd28931dba 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -80,7 +80,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
#ifdef CONFIG_ZONE_DMA32
/* 4GB maximum for 32-bit only capable devices */
max_dma32 = min(max, MAX_DMA32_PFN);
- zone_size[ZONE_DMA32] = max_dma32 - min;
+ zone_size[ZONE_DMA32] = max(min, max_dma32) - min;
#endif
zone_size[ZONE_NORMAL] = max - max_dma32;
diff --git a/arch/h8300/include/asm/cache.h b/arch/h8300/include/asm/cache.h
index c6350283649..05887a1d80e 100644
--- a/arch/h8300/include/asm/cache.h
+++ b/arch/h8300/include/asm/cache.h
@@ -2,7 +2,8 @@
#define __ARCH_H8300_CACHE_H
/* bytes per L1 cache line */
-#define L1_CACHE_BYTES 4
+#define L1_CACHE_SHIFT 2
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
/* m68k-elf-gcc 2.95.2 doesn't like these */
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index acd5b68e887..082e383c1b6 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -637,7 +637,6 @@ mem_init (void)
high_memory = __va(max_low_pfn * PAGE_SIZE);
- reset_zone_present_pages();
for_each_online_pgdat(pgdat)
if (pgdat->bdata->node_bootmem_map)
totalram_pages += free_all_bootmem_node(pgdat);
diff --git a/arch/m68k/include/asm/signal.h b/arch/m68k/include/asm/signal.h
index 67e489d8d1b..2df26b57c26 100644
--- a/arch/m68k/include/asm/signal.h
+++ b/arch/m68k/include/asm/signal.h
@@ -41,7 +41,7 @@ struct k_sigaction {
static inline void sigaddset(sigset_t *set, int _sig)
{
asm ("bfset %0{%1,#1}"
- : "+od" (*set)
+ : "+o" (*set)
: "id" ((_sig - 1) ^ 31)
: "cc");
}
@@ -49,7 +49,7 @@ static inline void sigaddset(sigset_t *set, int _sig)
static inline void sigdelset(sigset_t *set, int _sig)
{
asm ("bfclr %0{%1,#1}"
- : "+od" (*set)
+ : "+o" (*set)
: "id" ((_sig - 1) ^ 31)
: "cc");
}
@@ -65,7 +65,7 @@ static inline int __gen_sigismember(sigset_t *set, int _sig)
int ret;
asm ("bfextu %1{%2,#1},%0"
: "=d" (ret)
- : "od" (*set), "id" ((_sig-1) ^ 31)
+ : "o" (*set), "id" ((_sig-1) ^ 31)
: "cc");
return ret;
}
diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c
index d38246e33dd..9f883bf7695 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-l2c.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c
@@ -30,6 +30,7 @@
* measurement, and debugging facilities.
*/
+#include <linux/irqflags.h>
#include <asm/octeon/cvmx.h>
#include <asm/octeon/cvmx-l2c.h>
#include <asm/octeon/cvmx-spinlock.h>
diff --git a/arch/mips/fw/arc/misc.c b/arch/mips/fw/arc/misc.c
index 7cf80ca2c1d..f9f5307434c 100644
--- a/arch/mips/fw/arc/misc.c
+++ b/arch/mips/fw/arc/misc.c
@@ -11,6 +11,7 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/irqflags.h>
#include <asm/bcache.h>
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index 82ad35ce2b4..46ac73abd5e 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -14,7 +14,6 @@
#endif
#include <linux/compiler.h>
-#include <linux/irqflags.h>
#include <linux/types.h>
#include <asm/barrier.h>
#include <asm/byteorder.h> /* sigh ... */
@@ -44,6 +43,24 @@
#define smp_mb__before_clear_bit() smp_mb__before_llsc()
#define smp_mb__after_clear_bit() smp_llsc_mb()
+
+/*
+ * These are the "slower" versions of the functions and are in bitops.c.
+ * These functions call raw_local_irq_{save,restore}().
+ */
+void __mips_set_bit(unsigned long nr, volatile unsigned long *addr);
+void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr);
+void __mips_change_bit(unsigned long nr, volatile unsigned long *addr);
+int __mips_test_and_set_bit(unsigned long nr,
+ volatile unsigned long *addr);
+int __mips_test_and_set_bit_lock(unsigned long nr,
+ volatile unsigned long *addr);
+int __mips_test_and_clear_bit(unsigned long nr,
+ volatile unsigned long *addr);
+int __mips_test_and_change_bit(unsigned long nr,
+ volatile unsigned long *addr);
+
+
/*
* set_bit - Atomically set a bit in memory
* @nr: the bit to set
@@ -57,7 +74,7 @@
static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
unsigned long temp;
if (kernel_uses_llsc && R10000_LLSC_WAR) {
@@ -92,17 +109,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
: "=&r" (temp), "+m" (*m)
: "ir" (1UL << bit));
} while (unlikely(!temp));
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- *a |= mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ __mips_set_bit(nr, addr);
}
/*
@@ -118,7 +126,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
{
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
unsigned long temp;
if (kernel_uses_llsc && R10000_LLSC_WAR) {
@@ -153,17 +161,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
: "=&r" (temp), "+m" (*m)
: "ir" (~(1UL << bit)));
} while (unlikely(!temp));
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- *a &= ~mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ __mips_clear_bit(nr, addr);
}
/*
@@ -191,7 +190,7 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad
*/
static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
{
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
if (kernel_uses_llsc && R10000_LLSC_WAR) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
@@ -220,17 +219,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
: "=&r" (temp), "+m" (*m)
: "ir" (1UL << bit));
} while (unlikely(!temp));
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- *a ^= mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ __mips_change_bit(nr, addr);
}
/*
@@ -244,7 +234,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
static inline int test_and_set_bit(unsigned long nr,
volatile unsigned long *addr)
{
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
unsigned long res;
smp_mb__before_llsc();
@@ -281,18 +271,8 @@ static inline int test_and_set_bit(unsigned long nr,
} while (unlikely(!res));
res = temp & (1UL << bit);
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- res = (mask & *a);
- *a |= mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ res = __mips_test_and_set_bit(nr, addr);
smp_llsc_mb();
@@ -310,7 +290,7 @@ static inline int test_and_set_bit(unsigned long nr,
static inline int test_and_set_bit_lock(unsigned long nr,
volatile unsigned long *addr)
{
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
unsigned long res;
if (kernel_uses_llsc && R10000_LLSC_WAR) {
@@ -345,18 +325,8 @@ static inline int test_and_set_bit_lock(unsigned long nr,
} while (unlikely(!res));
res = temp & (1UL << bit);
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- res = (mask & *a);
- *a |= mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ res = __mips_test_and_set_bit_lock(nr, addr);
smp_llsc_mb();
@@ -373,7 +343,7 @@ static inline int test_and_set_bit_lock(unsigned long nr,
static inline int test_and_clear_bit(unsigned long nr,
volatile unsigned long *addr)
{
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
unsigned long res;
smp_mb__before_llsc();
@@ -428,18 +398,8 @@ static inline int test_and_clear_bit(unsigned long nr,
} while (unlikely(!res));
res = temp & (1UL << bit);
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- res = (mask & *a);
- *a &= ~mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ res = __mips_test_and_clear_bit(nr, addr);
smp_llsc_mb();
@@ -457,7 +417,7 @@ static inline int test_and_clear_bit(unsigned long nr,
static inline int test_and_change_bit(unsigned long nr,
volatile unsigned long *addr)
{
- unsigned short bit = nr & SZLONG_MASK;
+ int bit = nr & SZLONG_MASK;
unsigned long res;
smp_mb__before_llsc();
@@ -494,18 +454,8 @@ static inline int test_and_change_bit(unsigned long nr,
} while (unlikely(!res));
res = temp & (1UL << bit);
- } else {
- volatile unsigned long *a = addr;
- unsigned long mask;
- unsigned long flags;
-
- a += nr >> SZLONG_LOG;
- mask = 1UL << bit;
- raw_local_irq_save(flags);
- res = (mask & *a);
- *a ^= mask;
- raw_local_irq_restore(flags);
- }
+ } else
+ res = __mips_test_and_change_bit(nr, addr);
smp_llsc_mb();
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index 58277e0e9cd..3c5d1464b7b 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -290,7 +290,7 @@ struct compat_shmid64_ds {
static inline int is_compat_task(void)
{
- return test_thread_flag(TIF_32BIT);
+ return test_thread_flag(TIF_32BIT_ADDR);
}
#endif /* _ASM_COMPAT_H */
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 29d9c23c20c..ff2e0345e01 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -15,6 +15,7 @@
#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/irqflags.h>
#include <asm/addrspace.h>
#include <asm/bug.h>
diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h
index 309cbcd6909..9f3384c789d 100644
--- a/arch/mips/include/asm/irqflags.h
+++ b/arch/mips/include/asm/irqflags.h
@@ -16,83 +16,13 @@
#include <linux/compiler.h>
#include <asm/hazards.h>
-__asm__(
- " .macro arch_local_irq_enable \n"
- " .set push \n"
- " .set reorder \n"
- " .set noat \n"
-#ifdef CONFIG_MIPS_MT_SMTC
- " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n"
- " ori $1, 0x400 \n"
- " xori $1, 0x400 \n"
- " mtc0 $1, $2, 1 \n"
-#elif defined(CONFIG_CPU_MIPSR2)
- " ei \n"
-#else
- " mfc0 $1,$12 \n"
- " ori $1,0x1f \n"
- " xori $1,0x1e \n"
- " mtc0 $1,$12 \n"
-#endif
- " irq_enable_hazard \n"
- " .set pop \n"
- " .endm");
+#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC)
-extern void smtc_ipi_replay(void);
-
-static inline void arch_local_irq_enable(void)
-{
-#ifdef CONFIG_MIPS_MT_SMTC
- /*
- * SMTC kernel needs to do a software replay of queued
- * IPIs, at the cost of call overhead on each local_irq_enable()
- */
- smtc_ipi_replay();
-#endif
- __asm__ __volatile__(
- "arch_local_irq_enable"
- : /* no outputs */
- : /* no inputs */
- : "memory");
-}
-
-
-/*
- * For cli() we have to insert nops to make sure that the new value
- * has actually arrived in the status register before the end of this
- * macro.
- * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
- * no nops at all.
- */
-/*
- * For TX49, operating only IE bit is not enough.
- *
- * If mfc0 $12 follows store and the mfc0 is last instruction of a
- * page and fetching the next instruction causes TLB miss, the result
- * of the mfc0 might wrongly contain EXL bit.
- *
- * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
- *
- * Workaround: mask EXL bit of the result or place a nop before mfc0.
- */
__asm__(
" .macro arch_local_irq_disable\n"
" .set push \n"
" .set noat \n"
-#ifdef CONFIG_MIPS_MT_SMTC
- " mfc0 $1, $2, 1 \n"
- " ori $1, 0x400 \n"
- " .set noreorder \n"
- " mtc0 $1, $2, 1 \n"
-#elif defined(CONFIG_CPU_MIPSR2)
" di \n"
-#else
- " mfc0 $1,$12 \n"
- " ori $1,0x1f \n"
- " xori $1,0x1f \n"
- " .set noreorder \n"
- " mtc0 $1,$12 \n"
-#endif
" irq_disable_hazard \n"
" .set pop \n"
" .endm \n");
@@ -106,46 +36,14 @@ static inline void arch_local_irq_disable(void)
: "memory");
}
-__asm__(
- " .macro arch_local_save_flags flags \n"
- " .set push \n"
- " .set reorder \n"
-#ifdef CONFIG_MIPS_MT_SMTC
- " mfc0 \\flags, $2, 1 \n"
-#else
- " mfc0 \\flags, $12 \n"
-#endif
- " .set pop \n"
- " .endm \n");
-
-static inline unsigned long arch_local_save_flags(void)
-{
- unsigned long flags;
- asm volatile("arch_local_save_flags %0" : "=r" (flags));
- return flags;
-}
__asm__(
" .macro arch_local_irq_save result \n"
" .set push \n"
" .set reorder \n"
" .set noat \n"
-#ifdef CONFIG_MIPS_MT_SMTC
- " mfc0 \\result, $2, 1 \n"
- " ori $1, \\result, 0x400 \n"
- " .set noreorder \n"
- " mtc0 $1, $2, 1 \n"
- " andi \\result, \\result, 0x400 \n"
-#elif defined(CONFIG_CPU_MIPSR2)
" di \\result \n"
" andi \\result, 1 \n"
-#else
- " mfc0 \\result, $12 \n"
- " ori $1, \\result, 0x1f \n"
- " xori $1, 0x1f \n"
- " .set noreorder \n"
- " mtc0 $1, $12 \n"
-#endif
" irq_disable_hazard \n"
" .set pop \n"
" .endm \n");
@@ -160,61 +58,37 @@ static inline unsigned long arch_local_irq_save(void)
return flags;
}
+
__asm__(
" .macro arch_local_irq_restore flags \n"
" .set push \n"
" .set noreorder \n"
" .set noat \n"
-#ifdef CONFIG_MIPS_MT_SMTC
- "mfc0 $1, $2, 1 \n"
- "andi \\flags, 0x400 \n"
- "ori $1, 0x400 \n"
- "xori $1, 0x400 \n"
- "or \\flags, $1 \n"
- "mtc0 \\flags, $2, 1 \n"
-#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
+#if defined(CONFIG_IRQ_CPU)
/*
* Slow, but doesn't suffer from a relatively unlikely race
* condition we're having since days 1.
*/
" beqz \\flags, 1f \n"
- " di \n"
+ " di \n"
" ei \n"
"1: \n"
-#elif defined(CONFIG_CPU_MIPSR2)
+#else
/*
* Fast, dangerous. Life is fun, life is good.
*/
" mfc0 $1, $12 \n"
" ins $1, \\flags, 0, 1 \n"
" mtc0 $1, $12 \n"
-#else
- " mfc0 $1, $12 \n"
- " andi \\flags, 1 \n"
- " ori $1, 0x1f \n"
- " xori $1, 0x1f \n"
- " or \\flags, $1 \n"
- " mtc0 \\flags, $12 \n"
#endif
" irq_disable_hazard \n"
" .set pop \n"
" .endm \n");
-
static inline void arch_local_irq_restore(unsigned long flags)
{
unsigned long __tmp1;
-#ifdef CONFIG_MIPS_MT_SMTC
- /*
- * SMTC kernel needs to do a software replay of queued
- * IPIs, at the cost of branch and call overhead on each
- * local_irq_restore()
- */
- if (unlikely(!(flags & 0x0400)))
- smtc_ipi_replay();
-#endif
-
__asm__ __volatile__(
"arch_local_irq_restore\t%0"
: "=r" (__tmp1)
@@ -232,6 +106,75 @@ static inline void __arch_local_irq_restore(unsigned long flags)
: "0" (flags)
: "memory");
}
+#else
+/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */
+void arch_local_irq_disable(void);
+unsigned long arch_local_irq_save(void);
+void arch_local_irq_restore(unsigned long flags);
+void __arch_local_irq_restore(unsigned long flags);
+#endif /* if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) */
+
+
+__asm__(
+ " .macro arch_local_irq_enable \n"
+ " .set push \n"
+ " .set reorder \n"
+ " .set noat \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n"
+ " ori $1, 0x400 \n"
+ " xori $1, 0x400 \n"
+ " mtc0 $1, $2, 1 \n"
+#elif defined(CONFIG_CPU_MIPSR2)
+ " ei \n"
+#else
+ " mfc0 $1,$12 \n"
+ " ori $1,0x1f \n"
+ " xori $1,0x1e \n"
+ " mtc0 $1,$12 \n"
+#endif
+ " irq_enable_hazard \n"
+ " .set pop \n"
+ " .endm");
+
+extern void smtc_ipi_replay(void);
+
+static inline void arch_local_irq_enable(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC kernel needs to do a software replay of queued
+ * IPIs, at the cost of call overhead on each local_irq_enable()
+ */
+ smtc_ipi_replay();
+#endif
+ __asm__ __volatile__(
+ "arch_local_irq_enable"
+ : /* no outputs */
+ : /* no inputs */
+ : "memory");
+}
+
+
+__asm__(
+ " .macro arch_local_save_flags flags \n"
+ " .set push \n"
+ " .set reorder \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ " mfc0 \\flags, $2, 1 \n"
+#else
+ " mfc0 \\flags, $12 \n"
+#endif
+ " .set pop \n"
+ " .endm \n");
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+ asm volatile("arch_local_save_flags %0" : "=r" (flags));
+ return flags;
+}
+
static inline int arch_irqs_disabled_flags(unsigned long flags)
{
@@ -245,7 +188,7 @@ static inline int arch_irqs_disabled_flags(unsigned long flags)
#endif
}
-#endif
+#endif /* #ifndef __ASSEMBLY__ */
/*
* Do the CPU's IRQ-state tracing from assembly code.
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index 8debe9e9175..18806a52061 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -112,12 +112,6 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define TIF_LOAD_WATCH 25 /* If set, load watch registers */
#define TIF_SYSCALL_TRACE 31 /* syscall trace active */
-#ifdef CONFIG_MIPS32_O32
-#define TIF_32BIT TIF_32BIT_REGS
-#elif defined(CONFIG_MIPS32_N32)
-#define TIF_32BIT _TIF_32BIT_ADDR
-#endif /* CONFIG_MIPS32_O32 */
-
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index c4a82e841c7..eeddc58802e 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -2,8 +2,9 @@
# Makefile for MIPS-specific library files..
#
-lib-y += csum_partial.o delay.o memcpy.o memset.o \
- strlen_user.o strncpy_user.o strnlen_user.o uncached.o
+lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \
+ mips-atomic.o strlen_user.o strncpy_user.o \
+ strnlen_user.o uncached.o
obj-y += iomap.o
obj-$(CONFIG_PCI) += iomap-pci.o
diff --git a/arch/mips/lib/bitops.c b/arch/mips/lib/bitops.c
new file mode 100644
index 00000000000..239a9c957b0
--- /dev/null
+++ b/arch/mips/lib/bitops.c
@@ -0,0 +1,179 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (c) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/bitops.h>
+#include <linux/irqflags.h>
+#include <linux/export.h>
+
+
+/**
+ * __mips_set_bit - Atomically set a bit in memory. This is called by
+ * set_bit() if it cannot find a faster solution.
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ */
+void __mips_set_bit(unsigned long nr, volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ *a |= mask;
+ raw_local_irq_restore(flags);
+}
+EXPORT_SYMBOL(__mips_set_bit);
+
+
+/**
+ * __mips_clear_bit - Clears a bit in memory. This is called by clear_bit() if
+ * it cannot find a faster solution.
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ */
+void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ *a &= ~mask;
+ raw_local_irq_restore(flags);
+}
+EXPORT_SYMBOL(__mips_clear_bit);
+
+
+/**
+ * __mips_change_bit - Toggle a bit in memory. This is called by change_bit()
+ * if it cannot find a faster solution.
+ * @nr: Bit to change
+ * @addr: Address to start counting from
+ */
+void __mips_change_bit(unsigned long nr, volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ *a ^= mask;
+ raw_local_irq_restore(flags);
+}
+EXPORT_SYMBOL(__mips_change_bit);
+
+
+/**
+ * __mips_test_and_set_bit - Set a bit and return its old value. This is
+ * called by test_and_set_bit() if it cannot find a faster solution.
+ * @nr: Bit to set
+ * @addr: Address to count from
+ */
+int __mips_test_and_set_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+ unsigned long res;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ res = (mask & *a);
+ *a |= mask;
+ raw_local_irq_restore(flags);
+ return res;
+}
+EXPORT_SYMBOL(__mips_test_and_set_bit);
+
+
+/**
+ * __mips_test_and_set_bit_lock - Set a bit and return its old value. This is
+ * called by test_and_set_bit_lock() if it cannot find a faster solution.
+ * @nr: Bit to set
+ * @addr: Address to count from
+ */
+int __mips_test_and_set_bit_lock(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+ unsigned long res;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ res = (mask & *a);
+ *a |= mask;
+ raw_local_irq_restore(flags);
+ return res;
+}
+EXPORT_SYMBOL(__mips_test_and_set_bit_lock);
+
+
+/**
+ * __mips_test_and_clear_bit - Clear a bit and return its old value. This is
+ * called by test_and_clear_bit() if it cannot find a faster solution.
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ */
+int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+ unsigned long res;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ res = (mask & *a);
+ *a &= ~mask;
+ raw_local_irq_restore(flags);
+ return res;
+}
+EXPORT_SYMBOL(__mips_test_and_clear_bit);
+
+
+/**
+ * __mips_test_and_change_bit - Change a bit and return its old value. This is
+ * called by test_and_change_bit() if it cannot find a faster solution.
+ * @nr: Bit to change
+ * @addr: Address to count from
+ */
+int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
+{
+ volatile unsigned long *a = addr;
+ unsigned bit = nr & SZLONG_MASK;
+ unsigned long mask;
+ unsigned long flags;
+ unsigned long res;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ res = (mask & *a);
+ *a ^= mask;
+ raw_local_irq_restore(flags);
+ return res;
+}
+EXPORT_SYMBOL(__mips_test_and_change_bit);
diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c
new file mode 100644
index 00000000000..e091430dbeb
--- /dev/null
+++ b/arch/mips/lib/mips-atomic.c
@@ -0,0 +1,176 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
+ * Copyright (C) 1996 by Paul M. Antoine
+ * Copyright (C) 1999 Silicon Graphics
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ */
+#include <asm/irqflags.h>
+#include <asm/hazards.h>
+#include <linux/compiler.h>
+#include <linux/preempt.h>
+#include <linux/export.h>
+
+#if !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC)
+
+/*
+ * For cli() we have to insert nops to make sure that the new value
+ * has actually arrived in the status register before the end of this
+ * macro.
+ * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
+ * no nops at all.
+ */
+/*
+ * For TX49, operating only IE bit is not enough.
+ *
+ * If mfc0 $12 follows store and the mfc0 is last instruction of a
+ * page and fetching the next instruction causes TLB miss, the result
+ * of the mfc0 might wrongly contain EXL bit.
+ *
+ * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
+ *
+ * Workaround: mask EXL bit of the result or place a nop before mfc0.
+ */
+__asm__(
+ " .macro arch_local_irq_disable\n"
+ " .set push \n"
+ " .set noat \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ " mfc0 $1, $2, 1 \n"
+ " ori $1, 0x400 \n"
+ " .set noreorder \n"
+ " mtc0 $1, $2, 1 \n"
+#elif defined(CONFIG_CPU_MIPSR2)
+ /* see irqflags.h for inline function */
+#else
+ " mfc0 $1,$12 \n"
+ " ori $1,0x1f \n"
+ " xori $1,0x1f \n"
+ " .set noreorder \n"
+ " mtc0 $1,$12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set pop \n"
+ " .endm \n");
+
+void arch_local_irq_disable(void)
+{
+ preempt_disable();
+ __asm__ __volatile__(
+ "arch_local_irq_disable"
+ : /* no outputs */
+ : /* no inputs */
+ : "memory");
+ preempt_enable();
+}
+EXPORT_SYMBOL(arch_local_irq_disable);
+
+
+__asm__(
+ " .macro arch_local_irq_save result \n"
+ " .set push \n"
+ " .set reorder \n"
+ " .set noat \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ " mfc0 \\result, $2, 1 \n"
+ " ori $1, \\result, 0x400 \n"
+ " .set noreorder \n"
+ " mtc0 $1, $2, 1 \n"
+ " andi \\result, \\result, 0x400 \n"
+#elif defined(CONFIG_CPU_MIPSR2)
+ /* see irqflags.h for inline function */
+#else
+ " mfc0 \\result, $12 \n"
+ " ori $1, \\result, 0x1f \n"
+ " xori $1, 0x1f \n"
+ " .set noreorder \n"
+ " mtc0 $1, $12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set pop \n"
+ " .endm \n");
+
+unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+ preempt_disable();
+ asm volatile("arch_local_irq_save\t%0"
+ : "=r" (flags)
+ : /* no inputs */
+ : "memory");
+ preempt_enable();
+ return flags;
+}
+EXPORT_SYMBOL(arch_local_irq_save);
+
+
+__asm__(
+ " .macro arch_local_irq_restore flags \n"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set noat \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ "mfc0 $1, $2, 1 \n"
+ "andi \\flags, 0x400 \n"
+ "ori $1, 0x400 \n"
+ "xori $1, 0x400 \n"
+ "or \\flags, $1 \n"
+ "mtc0 \\flags, $2, 1 \n"
+#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
+ /* see irqflags.h for inline function */
+#elif defined(CONFIG_CPU_MIPSR2)
+ /* see irqflags.h for inline function */
+#else
+ " mfc0 $1, $12 \n"
+ " andi \\flags, 1 \n"
+ " ori $1, 0x1f \n"
+ " xori $1, 0x1f \n"
+ " or \\flags, $1 \n"
+ " mtc0 \\flags, $12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set pop \n"
+ " .endm \n");
+
+void arch_local_irq_restore(unsigned long flags)
+{
+ unsigned long __tmp1;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC kernel needs to do a software replay of queued
+ * IPIs, at the cost of branch and call overhead on each
+ * local_irq_restore()
+ */
+ if (unlikely(!(flags & 0x0400)))
+ smtc_ipi_replay();
+#endif
+ preempt_disable();
+ __asm__ __volatile__(
+ "arch_local_irq_restore\t%0"
+ : "=r" (__tmp1)
+ : "0" (flags)
+ : "memory");
+ preempt_enable();
+}
+EXPORT_SYMBOL(arch_local_irq_restore);
+
+
+void __arch_local_irq_restore(unsigned long flags)
+{
+ unsigned long __tmp1;
+
+ preempt_disable();
+ __asm__ __volatile__(
+ "arch_local_irq_restore\t%0"
+ : "=r" (__tmp1)
+ : "0" (flags)
+ : "memory");
+ preempt_enable();
+}
+EXPORT_SYMBOL(__arch_local_irq_restore);
+
+#endif /* !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) */
diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c
index 80562b81f0f..74732177851 100644
--- a/arch/mips/mti-malta/malta-platform.c
+++ b/arch/mips/mti-malta/malta-platform.c
@@ -29,6 +29,7 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
+#include <asm/mips-boards/maltaint.h>
#include <mtd/mtd-abi.h>
#define SMC_PORT(base, int) \
@@ -48,7 +49,7 @@ static struct plat_serial8250_port uart8250_data[] = {
SMC_PORT(0x2F8, 3),
{
.mapbase = 0x1f000900, /* The CBUS UART */
- .irq = MIPS_CPU_IRQ_BASE + 2,
+ .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2,
.uartclk = 3686400, /* Twice the usual clk! */
.iotype = UPIO_MEM32,
.flags = CBUS_UART_FLAGS,
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
index fd49aeda9eb..5dede04f2f3 100644
--- a/arch/parisc/kernel/signal32.c
+++ b/arch/parisc/kernel/signal32.c
@@ -65,7 +65,8 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
{
compat_sigset_t s;
- if (sz != sizeof *set) panic("put_sigset32()");
+ if (sz != sizeof *set)
+ return -EINVAL;
sigset_64to32(&s, set);
return copy_to_user(up, &s, sizeof s);
@@ -77,7 +78,8 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
compat_sigset_t s;
int r;
- if (sz != sizeof *set) panic("put_sigset32()");
+ if (sz != sizeof *set)
+ return -EINVAL;
if ((r = copy_from_user(&s, up, sz)) == 0) {
sigset_32to64(set, &s);
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 7426e40699b..f76c10863c6 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -73,6 +73,8 @@ static unsigned long get_shared_area(struct address_space *mapping,
struct vm_area_struct *vma;
int offset = mapping ? get_offset(mapping) : 0;
+ offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000;
+
addr = DCACHE_ALIGN(addr - offset) + offset;
for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
diff --git a/arch/powerpc/boot/dts/mpc5200b.dtsi b/arch/powerpc/boot/dts/mpc5200b.dtsi
index 7ab286ab530..39ed65a44c5 100644
--- a/arch/powerpc/boot/dts/mpc5200b.dtsi
+++ b/arch/powerpc/boot/dts/mpc5200b.dtsi
@@ -231,6 +231,12 @@
interrupts = <2 7 0>;
};
+ sclpc@3c00 {
+ compatible = "fsl,mpc5200-lpbfifo";
+ reg = <0x3c00 0x60>;
+ interrupts = <2 23 0>;
+ };
+
i2c@3d00 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/powerpc/boot/dts/o2d.dtsi b/arch/powerpc/boot/dts/o2d.dtsi
index 3444eb8f0ad..24f66803929 100644
--- a/arch/powerpc/boot/dts/o2d.dtsi
+++ b/arch/powerpc/boot/dts/o2d.dtsi
@@ -86,12 +86,6 @@
reg = <0>;
};
};
-
- sclpc@3c00 {
- compatible = "fsl,mpc5200-lpbfifo";
- reg = <0x3c00 0x60>;
- interrupts = <3 23 0>;
- };
};
localbus {
diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts
index 9e354997eb7..96512c05803 100644
--- a/arch/powerpc/boot/dts/pcm030.dts
+++ b/arch/powerpc/boot/dts/pcm030.dts
@@ -59,7 +59,7 @@
#gpio-cells = <2>;
};
- psc@2000 { /* PSC1 in ac97 mode */
+ audioplatform: psc@2000 { /* PSC1 in ac97 mode */
compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97";
cell-index = <0>;
};
@@ -134,4 +134,9 @@
localbus {
status = "disabled";
};
+
+ sound {
+ compatible = "phytec,pcm030-audio-fabric";
+ asoc-platform = <&audioplatform>;
+ };
};
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 8520b58a5e9..b89ef65392d 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -372,10 +372,11 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break;
case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break;
case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break;
- default:
- pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n",
- __func__, virq, l1irq, l2irq);
- return -EINVAL;
+ case MPC52xx_IRQ_L1_CRIT:
+ pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n",
+ __func__, l2irq);
+ irq_set_chip(virq, &no_irq_chip);
+ return 0;
}
irq_set_chip_and_handler(virq, irqchip, handle_level_irq);
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 5dba755a43e..d385f396dfe 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -96,6 +96,7 @@ config S390
select HAVE_MEMBLOCK_NODE_MAP
select HAVE_CMPXCHG_LOCAL
select HAVE_CMPXCHG_DOUBLE
+ select HAVE_ALIGNED_STRUCT_PAGE if SLUB
select HAVE_VIRT_CPU_ACCOUNTING
select VIRT_CPU_ACCOUNTING
select ARCH_DISCARD_MEMBLOCK
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h
index 55bde603521..ad2b924167d 100644
--- a/arch/s390/include/asm/cio.h
+++ b/arch/s390/include/asm/cio.h
@@ -9,6 +9,8 @@
#define LPM_ANYPATH 0xff
#define __MAX_CSSID 0
+#define __MAX_SUBCHANNEL 65535
+#define __MAX_SSID 3
#include <asm/scsw.h>
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index a34a9d612fc..18cd6b59265 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -20,7 +20,7 @@
#define PSW32_MASK_CC 0x00003000UL
#define PSW32_MASK_PM 0x00000f00UL
-#define PSW32_MASK_USER 0x00003F00UL
+#define PSW32_MASK_USER 0x0000FF00UL
#define PSW32_ADDR_AMODE 0x80000000UL
#define PSW32_ADDR_INSN 0x7FFFFFFFUL
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index dd647c919a6..2d3b7cb2600 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -506,12 +506,15 @@ static inline int pud_bad(pud_t pud)
static inline int pmd_present(pmd_t pmd)
{
- return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL;
+ unsigned long mask = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO;
+ return (pmd_val(pmd) & mask) == _HPAGE_TYPE_NONE ||
+ !(pmd_val(pmd) & _SEGMENT_ENTRY_INV);
}
static inline int pmd_none(pmd_t pmd)
{
- return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL;
+ return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) &&
+ !(pmd_val(pmd) & _SEGMENT_ENTRY_RO);
}
static inline int pmd_large(pmd_t pmd)
@@ -1223,6 +1226,11 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp)
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+
+#define SEGMENT_NONE __pgprot(_HPAGE_TYPE_NONE)
+#define SEGMENT_RO __pgprot(_HPAGE_TYPE_RO)
+#define SEGMENT_RW __pgprot(_HPAGE_TYPE_RW)
+
#define __HAVE_ARCH_PGTABLE_DEPOSIT
extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable);
@@ -1242,16 +1250,15 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot)
{
- unsigned long pgprot_pmd = 0;
-
- if (pgprot_val(pgprot) & _PAGE_INVALID) {
- if (pgprot_val(pgprot) & _PAGE_SWT)
- pgprot_pmd |= _HPAGE_TYPE_NONE;
- pgprot_pmd |= _SEGMENT_ENTRY_INV;
- }
- if (pgprot_val(pgprot) & _PAGE_RO)
- pgprot_pmd |= _SEGMENT_ENTRY_RO;
- return pgprot_pmd;
+ /*
+ * pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx)
+ * Convert to segment table entry format.
+ */
+ if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE))
+ return pgprot_val(SEGMENT_NONE);
+ if (pgprot_val(pgprot) == pgprot_val(PAGE_RO))
+ return pgprot_val(SEGMENT_RO);
+ return pgprot_val(SEGMENT_RW);
}
static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
@@ -1269,7 +1276,9 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd)
static inline pmd_t pmd_mkwrite(pmd_t pmd)
{
- pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO;
+ /* Do not clobber _HPAGE_TYPE_NONE pages! */
+ if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV))
+ pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO;
return pmd;
}
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h
index 9ca30538376..9935cbd6a46 100644
--- a/arch/s390/include/asm/topology.h
+++ b/arch/s390/include/asm/topology.h
@@ -8,6 +8,9 @@ struct cpu;
#ifdef CONFIG_SCHED_BOOK
+extern unsigned char cpu_socket_id[NR_CPUS];
+#define topology_physical_package_id(cpu) (cpu_socket_id[cpu])
+
extern unsigned char cpu_core_id[NR_CPUS];
extern cpumask_t cpu_core_map[NR_CPUS];
diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h
index 705588a16d7..a5ca214b34f 100644
--- a/arch/s390/include/uapi/asm/ptrace.h
+++ b/arch/s390/include/uapi/asm/ptrace.h
@@ -239,7 +239,7 @@ typedef struct
#define PSW_MASK_EA 0x00000000UL
#define PSW_MASK_BA 0x00000000UL
-#define PSW_MASK_USER 0x00003F00UL
+#define PSW_MASK_USER 0x0000FF00UL
#define PSW_ADDR_AMODE 0x80000000UL
#define PSW_ADDR_INSN 0x7FFFFFFFUL
@@ -269,7 +269,7 @@ typedef struct
#define PSW_MASK_EA 0x0000000100000000UL
#define PSW_MASK_BA 0x0000000080000000UL
-#define PSW_MASK_USER 0x00003F8180000000UL
+#define PSW_MASK_USER 0x0000FF8180000000UL
#define PSW_ADDR_AMODE 0x0000000000000000UL
#define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index a1e8a8694bb..593fcc9253f 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -309,6 +309,10 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
(__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 |
(__u64)(regs32.psw.addr & PSW32_ADDR_AMODE);
+ /* Check for invalid user address space control. */
+ if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC))
+ regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) |
+ (regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
for (i = 0; i < NUM_GPRS; i++)
regs->gprs[i] = (__u64) regs32.gprs[i];
@@ -481,7 +485,10 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
/* Set up registers for signal handler */
regs->gprs[15] = (__force __u64) frame;
- regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */
+ /* Force 31 bit amode and default user address space control. */
+ regs->psw.mask = PSW_MASK_BA |
+ (psw_user_bits & PSW_MASK_ASC) |
+ (regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (__force __u64) ka->sa.sa_handler;
regs->gprs[2] = map_signal(sig);
@@ -549,7 +556,10 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up registers for signal handler */
regs->gprs[15] = (__force __u64) frame;
- regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */
+ /* Force 31 bit amode and default user address space control. */
+ regs->psw.mask = PSW_MASK_BA |
+ (psw_user_bits & PSW_MASK_ASC) |
+ (regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (__u64) ka->sa.sa_handler;
regs->gprs[2] = map_signal(sig);
diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S
index bf053898630..b6506ee32a3 100644
--- a/arch/s390/kernel/sclp.S
+++ b/arch/s390/kernel/sclp.S
@@ -44,6 +44,12 @@ _sclp_wait_int:
#endif
mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8)
mvc 0(16,%r8),0(%r9)
+#ifdef CONFIG_64BIT
+ epsw %r6,%r7 # set current addressing mode
+ nill %r6,0x1 # in new psw (31 or 64 bit mode)
+ nilh %r7,0x8000
+ stm %r6,%r7,0(%r8)
+#endif
lhi %r6,0x0200 # cr mask for ext int (cr0.54)
ltr %r2,%r2
jz .LsetctS1
@@ -87,7 +93,7 @@ _sclp_wait_int:
.long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int
#ifdef CONFIG_64BIT
.LextpswS1_64:
- .quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit
+ .quad 0, .LwaitS1 # PSW to handle ext int, 64 bit
#endif
.LwaitpswS1:
.long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index c13a2a37ef0..d1259d87507 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -136,6 +136,10 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
/* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
(user_sregs.regs.psw.mask & PSW_MASK_USER);
+ /* Check for invalid user address space control. */
+ if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC))
+ regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) |
+ (regs->psw.mask & ~PSW_MASK_ASC);
/* Check for invalid amode */
if (regs->psw.mask & PSW_MASK_EA)
regs->psw.mask |= PSW_MASK_BA;
@@ -273,7 +277,10 @@ static int setup_frame(int sig, struct k_sigaction *ka,
/* Set up registers for signal handler */
regs->gprs[15] = (unsigned long) frame;
- regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */
+ /* Force default amode and default user address space control. */
+ regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
+ (psw_user_bits & PSW_MASK_ASC) |
+ (regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
regs->gprs[2] = map_signal(sig);
@@ -346,7 +353,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up registers for signal handler */
regs->gprs[15] = (unsigned long) frame;
- regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */
+ /* Force default amode and default user address space control. */
+ regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
+ (psw_user_bits & PSW_MASK_ASC) |
+ (regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
regs->gprs[2] = map_signal(sig);
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 54d93f4b681..dd55f7c2010 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -40,6 +40,7 @@ static DEFINE_SPINLOCK(topology_lock);
static struct mask_info core_info;
cpumask_t cpu_core_map[NR_CPUS];
unsigned char cpu_core_id[NR_CPUS];
+unsigned char cpu_socket_id[NR_CPUS];
static struct mask_info book_info;
cpumask_t cpu_book_map[NR_CPUS];
@@ -83,11 +84,12 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
cpumask_set_cpu(lcpu, &book->mask);
cpu_book_id[lcpu] = book->id;
cpumask_set_cpu(lcpu, &core->mask);
+ cpu_core_id[lcpu] = rcpu;
if (one_core_per_cpu) {
- cpu_core_id[lcpu] = rcpu;
+ cpu_socket_id[lcpu] = rcpu;
core = core->next;
} else {
- cpu_core_id[lcpu] = core->id;
+ cpu_socket_id[lcpu] = core->id;
}
smp_cpu_set_polarization(lcpu, tl_cpu->pp);
}
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c
index 2d37bb861fa..9017a63dda3 100644
--- a/arch/s390/lib/uaccess_pt.c
+++ b/arch/s390/lib/uaccess_pt.c
@@ -39,7 +39,7 @@ static __always_inline unsigned long follow_table(struct mm_struct *mm,
pmd = pmd_offset(pud, addr);
if (pmd_none(*pmd))
return -0x10UL;
- if (pmd_huge(*pmd)) {
+ if (pmd_large(*pmd)) {
if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO))
return -0x04UL;
return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK);
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c
index 60acb93a468..1f5315d1215 100644
--- a/arch/s390/mm/gup.c
+++ b/arch/s390/mm/gup.c
@@ -126,7 +126,7 @@ static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr,
*/
if (pmd_none(pmd) || pmd_trans_splitting(pmd))
return 0;
- if (unlikely(pmd_huge(pmd))) {
+ if (unlikely(pmd_large(pmd))) {
if (!gup_huge_pmd(pmdp, pmd, addr, next,
write, pages, nr))
return 0;
@@ -180,8 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
addr = start;
len = (unsigned long) nr_pages << PAGE_SHIFT;
end = start + len;
- if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
- (void __user *)start, len)))
+ if ((end < start) || (end > TASK_SIZE))
return 0;
local_irq_save(flags);
@@ -229,7 +228,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
addr = start;
len = (unsigned long) nr_pages << PAGE_SHIFT;
end = start + len;
- if (end < start)
+ if ((end < start) || (end > TASK_SIZE))
goto slow_irqon;
/*
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index b6b442b0d79..9f2edb5c555 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -20,6 +20,7 @@ config SPARC
select HAVE_ARCH_TRACEHOOK
select SYSCTL_EXCEPTION_TRACE
select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select RTC_CLASS
select RTC_DRV_M48T59
select HAVE_IRQ_WORK
diff --git a/arch/sparc/crypto/Makefile b/arch/sparc/crypto/Makefile
index 6ae1ad5e502..5d469d81761 100644
--- a/arch/sparc/crypto/Makefile
+++ b/arch/sparc/crypto/Makefile
@@ -13,13 +13,13 @@ obj-$(CONFIG_CRYPTO_DES_SPARC64) += camellia-sparc64.o
obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o
-sha1-sparc64-y := sha1_asm.o sha1_glue.o crop_devid.o
-sha256-sparc64-y := sha256_asm.o sha256_glue.o crop_devid.o
-sha512-sparc64-y := sha512_asm.o sha512_glue.o crop_devid.o
-md5-sparc64-y := md5_asm.o md5_glue.o crop_devid.o
+sha1-sparc64-y := sha1_asm.o sha1_glue.o
+sha256-sparc64-y := sha256_asm.o sha256_glue.o
+sha512-sparc64-y := sha512_asm.o sha512_glue.o
+md5-sparc64-y := md5_asm.o md5_glue.o
-aes-sparc64-y := aes_asm.o aes_glue.o crop_devid.o
-des-sparc64-y := des_asm.o des_glue.o crop_devid.o
-camellia-sparc64-y := camellia_asm.o camellia_glue.o crop_devid.o
+aes-sparc64-y := aes_asm.o aes_glue.o
+des-sparc64-y := des_asm.o des_glue.o
+camellia-sparc64-y := camellia_asm.o camellia_glue.o
-crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o crop_devid.o
+crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o
diff --git a/arch/sparc/crypto/aes_glue.c b/arch/sparc/crypto/aes_glue.c
index 8f1c9980f63..3965d1d36df 100644
--- a/arch/sparc/crypto/aes_glue.c
+++ b/arch/sparc/crypto/aes_glue.c
@@ -475,3 +475,5 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated");
MODULE_ALIAS("aes");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/camellia_glue.c b/arch/sparc/crypto/camellia_glue.c
index 42905c08429..62c89af3fd3 100644
--- a/arch/sparc/crypto/camellia_glue.c
+++ b/arch/sparc/crypto/camellia_glue.c
@@ -320,3 +320,5 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated");
MODULE_ALIAS("aes");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/crc32c_glue.c b/arch/sparc/crypto/crc32c_glue.c
index 0bd89cea8d8..5162fad912c 100644
--- a/arch/sparc/crypto/crc32c_glue.c
+++ b/arch/sparc/crypto/crc32c_glue.c
@@ -177,3 +177,5 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated");
MODULE_ALIAS("crc32c");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/des_glue.c b/arch/sparc/crypto/des_glue.c
index c4940c2d307..41524cebcc4 100644
--- a/arch/sparc/crypto/des_glue.c
+++ b/arch/sparc/crypto/des_glue.c
@@ -527,3 +527,5 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated");
MODULE_ALIAS("des");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/md5_glue.c b/arch/sparc/crypto/md5_glue.c
index 603d723038c..09a9ea1dfb6 100644
--- a/arch/sparc/crypto/md5_glue.c
+++ b/arch/sparc/crypto/md5_glue.c
@@ -186,3 +186,5 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated");
MODULE_ALIAS("md5");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/sha1_glue.c b/arch/sparc/crypto/sha1_glue.c
index 2bbb20bee9f..6cd5f29e1e0 100644
--- a/arch/sparc/crypto/sha1_glue.c
+++ b/arch/sparc/crypto/sha1_glue.c
@@ -181,3 +181,5 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated");
MODULE_ALIAS("sha1");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/sha256_glue.c b/arch/sparc/crypto/sha256_glue.c
index 591e656bd89..04f555ab268 100644
--- a/arch/sparc/crypto/sha256_glue.c
+++ b/arch/sparc/crypto/sha256_glue.c
@@ -239,3 +239,5 @@ MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 op
MODULE_ALIAS("sha224");
MODULE_ALIAS("sha256");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/crypto/sha512_glue.c b/arch/sparc/crypto/sha512_glue.c
index 486f0a2b700..f04d1994d19 100644
--- a/arch/sparc/crypto/sha512_glue.c
+++ b/arch/sparc/crypto/sha512_glue.c
@@ -224,3 +224,5 @@ MODULE_DESCRIPTION("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 op
MODULE_ALIAS("sha384");
MODULE_ALIAS("sha512");
+
+#include "crop_devid.c"
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
index ce35a1cf1a2..be56a244c9c 100644
--- a/arch/sparc/include/asm/atomic_64.h
+++ b/arch/sparc/include/asm/atomic_64.h
@@ -1,7 +1,7 @@
/* atomic.h: Thankfully the V9 is at least reasonable for this
* stuff.
*
- * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com)
*/
#ifndef __ARCH_SPARC64_ATOMIC__
@@ -106,6 +106,8 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+extern long atomic64_dec_if_positive(atomic64_t *v);
+
/* Atomic operations are already serializing */
#define smp_mb__before_atomic_dec() barrier()
#define smp_mb__after_atomic_dec() barrier()
diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h
index db3af0d30fb..4e02086b839 100644
--- a/arch/sparc/include/asm/backoff.h
+++ b/arch/sparc/include/asm/backoff.h
@@ -1,6 +1,46 @@
#ifndef _SPARC64_BACKOFF_H
#define _SPARC64_BACKOFF_H
+/* The macros in this file implement an exponential backoff facility
+ * for atomic operations.
+ *
+ * When multiple threads compete on an atomic operation, it is
+ * possible for one thread to be continually denied a successful
+ * completion of the compare-and-swap instruction. Heavily
+ * threaded cpu implementations like Niagara can compound this
+ * problem even further.
+ *
+ * When an atomic operation fails and needs to be retried, we spin a
+ * certain number of times. At each subsequent failure of the same
+ * operation we double the spin count, realizing an exponential
+ * backoff.
+ *
+ * When we spin, we try to use an operation that will cause the
+ * current cpu strand to block, and therefore make the core fully
+ * available to any other other runnable strands. There are two
+ * options, based upon cpu capabilities.
+ *
+ * On all cpus prior to SPARC-T4 we do three dummy reads of the
+ * condition code register. Each read blocks the strand for something
+ * between 40 and 50 cpu cycles.
+ *
+ * For SPARC-T4 and later we have a special "pause" instruction
+ * available. This is implemented using writes to register %asr27.
+ * The cpu will block the number of cycles written into the register,
+ * unless a disrupting trap happens first. SPARC-T4 specifically
+ * implements pause with a granularity of 8 cycles. Each strand has
+ * an internal pause counter which decrements every 8 cycles. So the
+ * chip shifts the %asr27 value down by 3 bits, and writes the result
+ * into the pause counter. If a value smaller than 8 is written, the
+ * chip blocks for 1 cycle.
+ *
+ * To achieve the same amount of backoff as the three %ccr reads give
+ * on earlier chips, we shift the backoff value up by 7 bits. (Three
+ * %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the
+ * whole amount we want to block into the pause register, rather than
+ * loop writing 128 each time.
+ */
+
#define BACKOFF_LIMIT (4 * 1024)
#ifdef CONFIG_SMP
@@ -11,16 +51,25 @@
#define BACKOFF_LABEL(spin_label, continue_label) \
spin_label
-#define BACKOFF_SPIN(reg, tmp, label) \
- mov reg, tmp; \
-88: brnz,pt tmp, 88b; \
- sub tmp, 1, tmp; \
- set BACKOFF_LIMIT, tmp; \
- cmp reg, tmp; \
- bg,pn %xcc, label; \
- nop; \
- ba,pt %xcc, label; \
- sllx reg, 1, reg;
+#define BACKOFF_SPIN(reg, tmp, label) \
+ mov reg, tmp; \
+88: rd %ccr, %g0; \
+ rd %ccr, %g0; \
+ rd %ccr, %g0; \
+ .section .pause_3insn_patch,"ax";\
+ .word 88b; \
+ sllx tmp, 7, tmp; \
+ wr tmp, 0, %asr27; \
+ clr tmp; \
+ .previous; \
+ brnz,pt tmp, 88b; \
+ sub tmp, 1, tmp; \
+ set BACKOFF_LIMIT, tmp; \
+ cmp reg, tmp; \
+ bg,pn %xcc, label; \
+ nop; \
+ ba,pt %xcc, label; \
+ sllx reg, 1, reg;
#else
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index cef99fbc0a2..830502fe62b 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h
@@ -232,9 +232,10 @@ static inline void __user *arch_compat_alloc_user_space(long len)
struct pt_regs *regs = current_thread_info()->kregs;
unsigned long usp = regs->u_regs[UREG_I6];
- if (!(test_thread_flag(TIF_32BIT)))
+ if (test_thread_64bit_stack(usp))
usp += STACK_BIAS;
- else
+
+ if (test_thread_flag(TIF_32BIT))
usp &= 0xffffffffUL;
usp -= len;
diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h
index 4e5a483122a..721e25f0e2e 100644
--- a/arch/sparc/include/asm/processor_64.h
+++ b/arch/sparc/include/asm/processor_64.h
@@ -196,7 +196,22 @@ extern unsigned long get_wchan(struct task_struct *task);
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc)
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP])
-#define cpu_relax() barrier()
+/* Please see the commentary in asm/backoff.h for a description of
+ * what these instructions are doing and how they have been choosen.
+ * To make a long story short, we are trying to yield the current cpu
+ * strand during busy loops.
+ */
+#define cpu_relax() asm volatile("\n99:\n\t" \
+ "rd %%ccr, %%g0\n\t" \
+ "rd %%ccr, %%g0\n\t" \
+ "rd %%ccr, %%g0\n\t" \
+ ".section .pause_3insn_patch,\"ax\"\n\t"\
+ ".word 99b\n\t" \
+ "wr %%g0, 128, %%asr27\n\t" \
+ "nop\n\t" \
+ "nop\n\t" \
+ ".previous" \
+ ::: "memory")
/* Prefetch support. This is tuned for UltraSPARC-III and later.
* UltraSPARC-I will treat these as nops, and UltraSPARC-II has
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h
index c2876511070..67c62578d17 100644
--- a/arch/sparc/include/asm/prom.h
+++ b/arch/sparc/include/asm/prom.h
@@ -63,5 +63,13 @@ extern char *of_console_options;
extern void irq_trans_init(struct device_node *dp);
extern char *build_path_component(struct device_node *dp);
+/* SPARC has local implementations */
+extern int of_address_to_resource(struct device_node *dev, int index,
+ struct resource *r);
+#define of_address_to_resource of_address_to_resource
+
+void __iomem *of_iomap(struct device_node *node, int index);
+#define of_iomap of_iomap
+
#endif /* __KERNEL__ */
#endif /* _SPARC_PROM_H */
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index 4e227663108..a3fe4dcc0aa 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -259,6 +259,11 @@ static inline bool test_and_clear_restore_sigmask(void)
#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+#define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0)
+#define test_thread_64bit_stack(__SP) \
+ ((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \
+ false : true)
+
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
diff --git a/arch/sparc/include/asm/ttable.h b/arch/sparc/include/asm/ttable.h
index 48f2807d326..71b5a67522a 100644
--- a/arch/sparc/include/asm/ttable.h
+++ b/arch/sparc/include/asm/ttable.h
@@ -372,7 +372,9 @@ etrap_spill_fixup_64bit: \
/* Normal 32bit spill */
#define SPILL_2_GENERIC(ASI) \
- srl %sp, 0, %sp; \
+ and %sp, 1, %g3; \
+ brnz,pn %g3, (. - (128 + 4)); \
+ srl %sp, 0, %sp; \
stwa %l0, [%sp + %g0] ASI; \
mov 0x04, %g3; \
stwa %l1, [%sp + %g3] ASI; \
@@ -398,14 +400,16 @@ etrap_spill_fixup_64bit: \
stwa %i6, [%g1 + %g0] ASI; \
stwa %i7, [%g1 + %g3] ASI; \
saved; \
- retry; nop; nop; \
+ retry; \
b,a,pt %xcc, spill_fixup_dax; \
b,a,pt %xcc, spill_fixup_mna; \
b,a,pt %xcc, spill_fixup;
#define SPILL_2_GENERIC_ETRAP \
etrap_user_spill_32bit: \
- srl %sp, 0, %sp; \
+ and %sp, 1, %g3; \
+ brnz,pn %g3, etrap_user_spill_64bit; \
+ srl %sp, 0, %sp; \
stwa %l0, [%sp + 0x00] %asi; \
stwa %l1, [%sp + 0x04] %asi; \
stwa %l2, [%sp + 0x08] %asi; \
@@ -427,7 +431,7 @@ etrap_user_spill_32bit: \
ba,pt %xcc, etrap_save; \
wrpr %g1, %cwp; \
nop; nop; nop; nop; \
- nop; nop; nop; nop; \
+ nop; nop; \
ba,a,pt %xcc, etrap_spill_fixup_32bit; \
ba,a,pt %xcc, etrap_spill_fixup_32bit; \
ba,a,pt %xcc, etrap_spill_fixup_32bit;
@@ -592,7 +596,9 @@ user_rtt_fill_64bit: \
/* Normal 32bit fill */
#define FILL_2_GENERIC(ASI) \
- srl %sp, 0, %sp; \
+ and %sp, 1, %g3; \
+ brnz,pn %g3, (. - (128 + 4)); \
+ srl %sp, 0, %sp; \
lduwa [%sp + %g0] ASI, %l0; \
mov 0x04, %g2; \
mov 0x08, %g3; \
@@ -616,14 +622,16 @@ user_rtt_fill_64bit: \
lduwa [%g1 + %g3] ASI, %i6; \
lduwa [%g1 + %g5] ASI, %i7; \
restored; \
- retry; nop; nop; nop; nop; \
+ retry; nop; nop; \
b,a,pt %xcc, fill_fixup_dax; \
b,a,pt %xcc, fill_fixup_mna; \
b,a,pt %xcc, fill_fixup;
#define FILL_2_GENERIC_RTRAP \
user_rtt_fill_32bit: \
- srl %sp, 0, %sp; \
+ and %sp, 1, %g3; \
+ brnz,pn %g3, user_rtt_fill_64bit; \
+ srl %sp, 0, %sp; \
lduwa [%sp + 0x00] %asi, %l0; \
lduwa [%sp + 0x04] %asi, %l1; \
lduwa [%sp + 0x08] %asi, %l2; \
@@ -643,7 +651,7 @@ user_rtt_fill_32bit: \
ba,pt %xcc, user_rtt_pre_restore; \
restored; \
nop; nop; nop; nop; nop; \
- nop; nop; nop; nop; nop; \
+ nop; nop; nop; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup; \
ba,a,pt %xcc, user_rtt_fill_fixup;
diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h
index 8974ef7ae92..cac719d1bc5 100644
--- a/arch/sparc/include/uapi/asm/unistd.h
+++ b/arch/sparc/include/uapi/asm/unistd.h
@@ -405,8 +405,13 @@
#define __NR_setns 337
#define __NR_process_vm_readv 338
#define __NR_process_vm_writev 339
+#define __NR_kern_features 340
+#define __NR_kcmp 341
-#define NR_syscalls 340
+#define NR_syscalls 342
+
+/* Bitmask values returned from kern_features system call. */
+#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001
#ifdef __32bit_syscall_numbers__
/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h
index 0c218e4c088..cc3c5cb47cd 100644
--- a/arch/sparc/kernel/entry.h
+++ b/arch/sparc/kernel/entry.h
@@ -59,6 +59,13 @@ struct popc_6insn_patch_entry {
extern struct popc_6insn_patch_entry __popc_6insn_patch,
__popc_6insn_patch_end;
+struct pause_patch_entry {
+ unsigned int addr;
+ unsigned int insns[3];
+};
+extern struct pause_patch_entry __pause_3insn_patch,
+ __pause_3insn_patch_end;
+
extern void __init per_cpu_patch(void);
extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
struct sun4v_1insn_patch_entry *);
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index f8b6eee40bd..87f60ee6543 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -56,11 +56,13 @@ static inline unsigned int leon_eirq_get(int cpu)
static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc)
{
unsigned int eirq;
+ struct irq_bucket *p;
int cpu = sparc_leon3_cpuid();
eirq = leon_eirq_get(cpu);
- if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */
- generic_handle_irq(irq_map[eirq]->irq);
+ p = irq_map[eirq];
+ if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */
+ generic_handle_irq(p->irq);
}
/* The extended IRQ controller has been found, this function registers it */
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 885a8af7406..b5c38faa4ea 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -1762,15 +1762,25 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry,
ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
do {
- struct sparc_stackf32 *usf, sf;
unsigned long pc;
- usf = (struct sparc_stackf32 *) ufp;
- if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
- break;
+ if (thread32_stack_is_64bit(ufp)) {
+ struct sparc_stackf *usf, sf;
- pc = sf.callers_pc;
- ufp = (unsigned long)sf.fp;
+ ufp += STACK_BIAS;
+ usf = (struct sparc_stackf *) ufp;
+ if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
+ break;
+ pc = sf.callers_pc & 0xffffffff;
+ ufp = ((unsigned long) sf.fp) & 0xffffffff;
+ } else {
+ struct sparc_stackf32 *usf, sf;
+ usf = (struct sparc_stackf32 *) ufp;
+ if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
+ break;
+ pc = sf.callers_pc;
+ ufp = (unsigned long)sf.fp;
+ }
perf_callchain_store(entry, pc);
} while (entry->nr < PERF_MAX_STACK_DEPTH);
}
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index d778248ef3f..c6e0c291004 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -452,13 +452,16 @@ void flush_thread(void)
/* It's a bit more tricky when 64-bit tasks are involved... */
static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
{
+ bool stack_64bit = test_thread_64bit_stack(psp);
unsigned long fp, distance, rval;
- if (!(test_thread_flag(TIF_32BIT))) {
+ if (stack_64bit) {
csp += STACK_BIAS;
psp += STACK_BIAS;
__get_user(fp, &(((struct reg_window __user *)psp)->ins[6]));
fp += STACK_BIAS;
+ if (test_thread_flag(TIF_32BIT))
+ fp &= 0xffffffff;
} else
__get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6]));
@@ -472,7 +475,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
rval = (csp - distance);
if (copy_in_user((void __user *) rval, (void __user *) psp, distance))
rval = 0;
- else if (test_thread_flag(TIF_32BIT)) {
+ else if (!stack_64bit) {
if (put_user(((u32)csp),
&(((struct reg_window32 __user *)rval)->ins[6])))
rval = 0;
@@ -507,18 +510,18 @@ void synchronize_user_stack(void)
flush_user_windows();
if ((window = get_thread_wsaved()) != 0) {
- int winsize = sizeof(struct reg_window);
- int bias = 0;
-
- if (test_thread_flag(TIF_32BIT))
- winsize = sizeof(struct reg_window32);
- else
- bias = STACK_BIAS;
-
window -= 1;
do {
- unsigned long sp = (t->rwbuf_stkptrs[window] + bias);
struct reg_window *rwin = &t->reg_window[window];
+ int winsize = sizeof(struct reg_window);
+ unsigned long sp;
+
+ sp = t->rwbuf_stkptrs[window];
+
+ if (test_thread_64bit_stack(sp))
+ sp += STACK_BIAS;
+ else
+ winsize = sizeof(struct reg_window32);
if (!copy_to_user((char __user *)sp, rwin, winsize)) {
shift_window_buffer(window, get_thread_wsaved() - 1, t);
@@ -544,13 +547,6 @@ void fault_in_user_windows(void)
{
struct thread_info *t = current_thread_info();
unsigned long window;
- int winsize = sizeof(struct reg_window);
- int bias = 0;
-
- if (test_thread_flag(TIF_32BIT))
- winsize = sizeof(struct reg_window32);
- else
- bias = STACK_BIAS;
flush_user_windows();
window = get_thread_wsaved();
@@ -558,8 +554,16 @@ void fault_in_user_windows(void)
if (likely(window != 0)) {
window -= 1;
do {
- unsigned long sp = (t->rwbuf_stkptrs[window] + bias);
struct reg_window *rwin = &t->reg_window[window];
+ int winsize = sizeof(struct reg_window);
+ unsigned long sp;
+
+ sp = t->rwbuf_stkptrs[window];
+
+ if (test_thread_64bit_stack(sp))
+ sp += STACK_BIAS;
+ else
+ winsize = sizeof(struct reg_window32);
if (unlikely(sp & 0x7UL))
stack_unaligned(sp);
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c
index 484dabac704..7ff45e4ba68 100644
--- a/arch/sparc/kernel/ptrace_64.c
+++ b/arch/sparc/kernel/ptrace_64.c
@@ -151,7 +151,7 @@ static int regwindow64_get(struct task_struct *target,
{
unsigned long rw_addr = regs->u_regs[UREG_I6];
- if (test_tsk_thread_flag(current, TIF_32BIT)) {
+ if (!test_thread_64bit_stack(rw_addr)) {
struct reg_window32 win32;
int i;
@@ -176,7 +176,7 @@ static int regwindow64_set(struct task_struct *target,
{
unsigned long rw_addr = regs->u_regs[UREG_I6];
- if (test_tsk_thread_flag(current, TIF_32BIT)) {
+ if (!test_thread_64bit_stack(rw_addr)) {
struct reg_window32 win32;
int i;
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index 0800e71d8a8..0eaf0059aae 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -316,6 +316,25 @@ static void __init popc_patch(void)
}
}
+static void __init pause_patch(void)
+{
+ struct pause_patch_entry *p;
+
+ p = &__pause_3insn_patch;
+ while (p < &__pause_3insn_patch_end) {
+ unsigned long i, addr = p->addr;
+
+ for (i = 0; i < 3; i++) {
+ *(unsigned int *) (addr + (i * 4)) = p->insns[i];
+ wmb();
+ __asm__ __volatile__("flush %0"
+ : : "r" (addr + (i * 4)));
+ }
+
+ p++;
+ }
+}
+
#ifdef CONFIG_SMP
void __init boot_cpu_id_too_large(int cpu)
{
@@ -528,6 +547,8 @@ static void __init init_sparc64_elf_hwcap(void)
if (sparc64_elf_hwcap & AV_SPARC_POPC)
popc_patch();
+ if (sparc64_elf_hwcap & AV_SPARC_PAUSE)
+ pause_patch();
}
void __init setup_arch(char **cmdline_p)
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index 867de2f8189..689e1ba6280 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -295,9 +295,7 @@ void do_rt_sigreturn(struct pt_regs *regs)
err |= restore_fpu_state(regs, fpu_save);
err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
- err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf);
-
- if (err)
+ if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT)
goto segv;
err |= __get_user(rwin_save, &sf->rwin_save);
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 11c6c9603e7..878ef3d5fec 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -751,3 +751,8 @@ int kernel_execve(const char *filename,
: "cc");
return __res;
}
+
+asmlinkage long sys_kern_features(void)
+{
+ return KERN_FEATURE_MIXED_MODE_STACK;
+}
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S
index 63402f9e9f5..5147f574f12 100644
--- a/arch/sparc/kernel/systbls_32.S
+++ b/arch/sparc/kernel/systbls_32.S
@@ -85,3 +85,4 @@ sys_call_table:
/*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
/*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
/*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
+/*340*/ .long sys_ni_syscall, sys_kcmp
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index 3a58e0d66f5..1c9af9fa38e 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -86,6 +86,7 @@ sys_call_table32:
.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init
/*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime
.word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev
+/*340*/ .word sys_kern_features, sys_kcmp
#endif /* CONFIG_COMPAT */
@@ -163,3 +164,4 @@ sys_call_table:
.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
/*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
.word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
+/*340*/ .word sys_kern_features, sys_kcmp
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c
index f81d038f734..8201c25e766 100644
--- a/arch/sparc/kernel/unaligned_64.c
+++ b/arch/sparc/kernel/unaligned_64.c
@@ -113,21 +113,24 @@ static inline long sign_extend_imm13(long imm)
static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
{
- unsigned long value;
+ unsigned long value, fp;
if (reg < 16)
return (!reg ? 0 : regs->u_regs[reg]);
+
+ fp = regs->u_regs[UREG_FP];
+
if (regs->tstate & TSTATE_PRIV) {
struct reg_window *win;
- win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+ win = (struct reg_window *)(fp + STACK_BIAS);
value = win->locals[reg - 16];
- } else if (test_thread_flag(TIF_32BIT)) {
+ } else if (!test_thread_64bit_stack(fp)) {
struct reg_window32 __user *win32;
- win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
+ win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
get_user(value, &win32->locals[reg - 16]);
} else {
struct reg_window __user *win;
- win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+ win = (struct reg_window __user *)(fp + STACK_BIAS);
get_user(value, &win->locals[reg - 16]);
}
return value;
@@ -135,19 +138,24 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs)
{
+ unsigned long fp;
+
if (reg < 16)
return &regs->u_regs[reg];
+
+ fp = regs->u_regs[UREG_FP];
+
if (regs->tstate & TSTATE_PRIV) {
struct reg_window *win;
- win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+ win = (struct reg_window *)(fp + STACK_BIAS);
return &win->locals[reg - 16];
- } else if (test_thread_flag(TIF_32BIT)) {
+ } else if (!test_thread_64bit_stack(fp)) {
struct reg_window32 *win32;
- win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
+ win32 = (struct reg_window32 *)((unsigned long)((u32)fp));
return (unsigned long *)&win32->locals[reg - 16];
} else {
struct reg_window *win;
- win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+ win = (struct reg_window *)(fp + STACK_BIAS);
return &win->locals[reg - 16];
}
}
@@ -392,13 +400,15 @@ int handle_popc(u32 insn, struct pt_regs *regs)
if (rd)
regs->u_regs[rd] = ret;
} else {
- if (test_thread_flag(TIF_32BIT)) {
+ unsigned long fp = regs->u_regs[UREG_FP];
+
+ if (!test_thread_64bit_stack(fp)) {
struct reg_window32 __user *win32;
- win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
+ win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
put_user(ret, &win32->locals[rd - 16]);
} else {
struct reg_window __user *win;
- win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+ win = (struct reg_window __user *)(fp + STACK_BIAS);
put_user(ret, &win->locals[rd - 16]);
}
}
@@ -554,7 +564,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs)
reg[0] = 0;
if ((insn & 0x780000) == 0x180000)
reg[1] = 0;
- } else if (test_thread_flag(TIF_32BIT)) {
+ } else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) {
put_user(0, (int __user *) reg);
if ((insn & 0x780000) == 0x180000)
put_user(0, ((int __user *) reg) + 1);
diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c
index 08e074b7eb6..c096c624ac4 100644
--- a/arch/sparc/kernel/visemul.c
+++ b/arch/sparc/kernel/visemul.c
@@ -149,21 +149,24 @@ static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2,
static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
{
- unsigned long value;
+ unsigned long value, fp;
if (reg < 16)
return (!reg ? 0 : regs->u_regs[reg]);
+
+ fp = regs->u_regs[UREG_FP];
+
if (regs->tstate & TSTATE_PRIV) {
struct reg_window *win;
- win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+ win = (struct reg_window *)(fp + STACK_BIAS);
value = win->locals[reg - 16];
- } else if (test_thread_flag(TIF_32BIT)) {
+ } else if (!test_thread_64bit_stack(fp)) {
struct reg_window32 __user *win32;
- win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
+ win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
get_user(value, &win32->locals[reg - 16]);
} else {
struct reg_window __user *win;
- win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+ win = (struct reg_window __user *)(fp + STACK_BIAS);
get_user(value, &win->locals[reg - 16]);
}
return value;
@@ -172,16 +175,18 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg,
struct pt_regs *regs)
{
+ unsigned long fp = regs->u_regs[UREG_FP];
+
BUG_ON(reg < 16);
BUG_ON(regs->tstate & TSTATE_PRIV);
- if (test_thread_flag(TIF_32BIT)) {
+ if (!test_thread_64bit_stack(fp)) {
struct reg_window32 __user *win32;
- win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
+ win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
return (unsigned long __user *)&win32->locals[reg - 16];
} else {
struct reg_window __user *win;
- win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+ win = (struct reg_window __user *)(fp + STACK_BIAS);
return &win->locals[reg - 16];
}
}
@@ -204,7 +209,7 @@ static void store_reg(struct pt_regs *regs, unsigned long val, unsigned long rd)
} else {
unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs);
- if (test_thread_flag(TIF_32BIT))
+ if (!test_thread_64bit_stack(regs->u_regs[UREG_FP]))
__put_user((u32)val, (u32 __user *)rd_user);
else
__put_user(val, rd_user);
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 89c2c29f154..0bacceb1915 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -132,6 +132,11 @@ SECTIONS
*(.popc_6insn_patch)
__popc_6insn_patch_end = .;
}
+ .pause_3insn_patch : {
+ __pause_3insn_patch = .;
+ *(.pause_3insn_patch)
+ __pause_3insn_patch_end = .;
+ }
PERCPU_SECTION(SMP_CACHE_BYTES)
. = ALIGN(PAGE_SIZE);
diff --git a/arch/sparc/kernel/winfixup.S b/arch/sparc/kernel/winfixup.S
index a6b0863c27d..1e67ce95836 100644
--- a/arch/sparc/kernel/winfixup.S
+++ b/arch/sparc/kernel/winfixup.S
@@ -43,6 +43,8 @@ spill_fixup_mna:
spill_fixup_dax:
TRAP_LOAD_THREAD_REG(%g6, %g1)
ldx [%g6 + TI_FLAGS], %g1
+ andcc %sp, 0x1, %g0
+ movne %icc, 0, %g1
andcc %g1, _TIF_32BIT, %g0
ldub [%g6 + TI_WSAVED], %g1
sll %g1, 3, %g3
diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S
index 4d502da3de7..85c233d0a34 100644
--- a/arch/sparc/lib/atomic_64.S
+++ b/arch/sparc/lib/atomic_64.S
@@ -1,6 +1,6 @@
/* atomic.S: These things are too big to do inline.
*
- * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1999, 2007 2012 David S. Miller (davem@davemloft.net)
*/
#include <linux/linkage.h>
@@ -117,3 +117,17 @@ ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */
sub %g1, %o0, %o0
2: BACKOFF_SPIN(%o2, %o3, 1b)
ENDPROC(atomic64_sub_ret)
+
+ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */
+ BACKOFF_SETUP(%o2)
+1: ldx [%o0], %g1
+ brlez,pn %g1, 3f
+ sub %g1, 1, %g7
+ casx [%o0], %g1, %g7
+ cmp %g1, %g7
+ bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
+ nop
+3: retl
+ sub %g1, 1, %o0
+2: BACKOFF_SPIN(%o2, %o3, 1b)
+ENDPROC(atomic64_dec_if_positive)
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c
index ee31b884c61..0c4e35e522f 100644
--- a/arch/sparc/lib/ksyms.c
+++ b/arch/sparc/lib/ksyms.c
@@ -116,6 +116,7 @@ EXPORT_SYMBOL(atomic64_add);
EXPORT_SYMBOL(atomic64_add_ret);
EXPORT_SYMBOL(atomic64_sub);
EXPORT_SYMBOL(atomic64_sub_ret);
+EXPORT_SYMBOL(atomic64_dec_if_positive);
/* Atomic bit operations. */
EXPORT_SYMBOL(test_and_set_bit);
diff --git a/arch/sparc/math-emu/math_64.c b/arch/sparc/math-emu/math_64.c
index 1704068da92..034aadbff03 100644
--- a/arch/sparc/math-emu/math_64.c
+++ b/arch/sparc/math-emu/math_64.c
@@ -320,7 +320,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap)
XR = 0;
else if (freg < 16)
XR = regs->u_regs[freg];
- else if (test_thread_flag(TIF_32BIT)) {
+ else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) {
struct reg_window32 __user *win32;
flushw_user ();
win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index e5c5473e69c..c4fbb21e802 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -16,6 +16,8 @@ config UNICORE32
select ARCH_WANT_FRAME_POINTERS
select GENERIC_IOMAP
select MODULES_USE_ELF_REL
+ select GENERIC_KERNEL_THREAD
+ select GENERIC_KERNEL_EXECVE
help
UniCore-32 is 32-bit Instruction Set Architecture,
including a series of low-power-consumption RISC chip
@@ -64,6 +66,9 @@ config GENERIC_CALIBRATE_DELAY
config ARCH_MAY_HAVE_PC_FDC
bool
+config ZONE_DMA
+ def_bool y
+
config NEED_DMA_MAP_STATE
def_bool y
@@ -216,7 +221,7 @@ config PUV3_GPIO
bool
depends on !ARCH_FPGA
select GENERIC_GPIO
- select GPIO_SYSFS if EXPERIMENTAL
+ select GPIO_SYSFS
default y
if PUV3_NB0916
diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild
index c910c9857e1..601e92f18af 100644
--- a/arch/unicore32/include/asm/Kbuild
+++ b/arch/unicore32/include/asm/Kbuild
@@ -1,4 +1,3 @@
-include include/asm-generic/Kbuild.asm
generic-y += atomic.h
generic-y += auxvec.h
diff --git a/arch/unicore32/include/asm/bug.h b/arch/unicore32/include/asm/bug.h
index b1ff8cadb08..93a56f3e234 100644
--- a/arch/unicore32/include/asm/bug.h
+++ b/arch/unicore32/include/asm/bug.h
@@ -19,9 +19,4 @@ extern void die(const char *msg, struct pt_regs *regs, int err);
extern void uc32_notify_die(const char *str, struct pt_regs *regs,
struct siginfo *info, unsigned long err, unsigned long trap);
-extern asmlinkage void __backtrace(void);
-extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
-
-extern void __show_regs(struct pt_regs *);
-
#endif /* __UNICORE_BUG_H__ */
diff --git a/arch/unicore32/include/asm/cmpxchg.h b/arch/unicore32/include/asm/cmpxchg.h
index df4d5acfd19..8e797ad4fa2 100644
--- a/arch/unicore32/include/asm/cmpxchg.h
+++ b/arch/unicore32/include/asm/cmpxchg.h
@@ -35,7 +35,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
: "memory", "cc");
break;
default:
- ret = __xchg_bad_pointer();
+ __xchg_bad_pointer();
}
return ret;
diff --git a/arch/unicore32/include/asm/kvm_para.h b/arch/unicore32/include/asm/kvm_para.h
deleted file mode 100644
index 14fab8f0b95..00000000000
--- a/arch/unicore32/include/asm/kvm_para.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/kvm_para.h>
diff --git a/arch/unicore32/include/asm/processor.h b/arch/unicore32/include/asm/processor.h
index 14382cb0965..4eaa4216766 100644
--- a/arch/unicore32/include/asm/processor.h
+++ b/arch/unicore32/include/asm/processor.h
@@ -72,11 +72,6 @@ unsigned long get_wchan(struct task_struct *p);
#define cpu_relax() barrier()
-/*
- * Create a new kernel thread
- */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
#define task_pt_regs(p) \
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
diff --git a/arch/unicore32/include/asm/ptrace.h b/arch/unicore32/include/asm/ptrace.h
index b9caf9b0997..726749dab52 100644
--- a/arch/unicore32/include/asm/ptrace.h
+++ b/arch/unicore32/include/asm/ptrace.h
@@ -12,80 +12,10 @@
#ifndef __UNICORE_PTRACE_H__
#define __UNICORE_PTRACE_H__
-#define PTRACE_GET_THREAD_AREA 22
-
-/*
- * PSR bits
- */
-#define USER_MODE 0x00000010
-#define REAL_MODE 0x00000011
-#define INTR_MODE 0x00000012
-#define PRIV_MODE 0x00000013
-#define ABRT_MODE 0x00000017
-#define EXTN_MODE 0x0000001b
-#define SUSR_MODE 0x0000001f
-#define MODE_MASK 0x0000001f
-#define PSR_R_BIT 0x00000040
-#define PSR_I_BIT 0x00000080
-#define PSR_V_BIT 0x10000000
-#define PSR_C_BIT 0x20000000
-#define PSR_Z_BIT 0x40000000
-#define PSR_S_BIT 0x80000000
-
-/*
- * Groups of PSR bits
- */
-#define PSR_f 0xff000000 /* Flags */
-#define PSR_c 0x000000ff /* Control */
+#include <uapi/asm/ptrace.h>
#ifndef __ASSEMBLY__
-/*
- * This struct defines the way the registers are stored on the
- * stack during a system call. Note that sizeof(struct pt_regs)
- * has to be a multiple of 8.
- */
-struct pt_regs {
- unsigned long uregs[34];
-};
-
-#define UCreg_asr uregs[32]
-#define UCreg_pc uregs[31]
-#define UCreg_lr uregs[30]
-#define UCreg_sp uregs[29]
-#define UCreg_ip uregs[28]
-#define UCreg_fp uregs[27]
-#define UCreg_26 uregs[26]
-#define UCreg_25 uregs[25]
-#define UCreg_24 uregs[24]
-#define UCreg_23 uregs[23]
-#define UCreg_22 uregs[22]
-#define UCreg_21 uregs[21]
-#define UCreg_20 uregs[20]
-#define UCreg_19 uregs[19]
-#define UCreg_18 uregs[18]
-#define UCreg_17 uregs[17]
-#define UCreg_16 uregs[16]
-#define UCreg_15 uregs[15]
-#define UCreg_14 uregs[14]
-#define UCreg_13 uregs[13]
-#define UCreg_12 uregs[12]
-#define UCreg_11 uregs[11]
-#define UCreg_10 uregs[10]
-#define UCreg_09 uregs[9]
-#define UCreg_08 uregs[8]
-#define UCreg_07 uregs[7]
-#define UCreg_06 uregs[6]
-#define UCreg_05 uregs[5]
-#define UCreg_04 uregs[4]
-#define UCreg_03 uregs[3]
-#define UCreg_02 uregs[2]
-#define UCreg_01 uregs[1]
-#define UCreg_00 uregs[0]
-#define UCreg_ORIG_00 uregs[33]
-
-#ifdef __KERNEL__
-
#define user_mode(regs) \
(processor_mode(regs) == USER_MODE)
@@ -125,9 +55,5 @@ static inline int valid_user_regs(struct pt_regs *regs)
#define instruction_pointer(regs) ((regs)->UCreg_pc)
-#endif /* __KERNEL__ */
-
#endif /* __ASSEMBLY__ */
-
#endif
-
diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild
index baebb3da1d4..0514d7ad685 100644
--- a/arch/unicore32/include/uapi/asm/Kbuild
+++ b/arch/unicore32/include/uapi/asm/Kbuild
@@ -1,3 +1,10 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
+header-y += byteorder.h
+header-y += kvm_para.h
+header-y += ptrace.h
+header-y += sigcontext.h
+header-y += unistd.h
+
+generic-y += kvm_para.h
diff --git a/arch/unicore32/include/asm/byteorder.h b/arch/unicore32/include/uapi/asm/byteorder.h
index ebe1b3fef3e..ebe1b3fef3e 100644
--- a/arch/unicore32/include/asm/byteorder.h
+++ b/arch/unicore32/include/uapi/asm/byteorder.h
diff --git a/arch/unicore32/include/uapi/asm/ptrace.h b/arch/unicore32/include/uapi/asm/ptrace.h
new file mode 100644
index 00000000000..187aa2e98a5
--- /dev/null
+++ b/arch/unicore32/include/uapi/asm/ptrace.h
@@ -0,0 +1,90 @@
+/*
+ * linux/arch/unicore32/include/asm/ptrace.h
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _UAPI__UNICORE_PTRACE_H__
+#define _UAPI__UNICORE_PTRACE_H__
+
+#define PTRACE_GET_THREAD_AREA 22
+
+/*
+ * PSR bits
+ */
+#define USER_MODE 0x00000010
+#define REAL_MODE 0x00000011
+#define INTR_MODE 0x00000012
+#define PRIV_MODE 0x00000013
+#define ABRT_MODE 0x00000017
+#define EXTN_MODE 0x0000001b
+#define SUSR_MODE 0x0000001f
+#define MODE_MASK 0x0000001f
+#define PSR_R_BIT 0x00000040
+#define PSR_I_BIT 0x00000080
+#define PSR_V_BIT 0x10000000
+#define PSR_C_BIT 0x20000000
+#define PSR_Z_BIT 0x40000000
+#define PSR_S_BIT 0x80000000
+
+/*
+ * Groups of PSR bits
+ */
+#define PSR_f 0xff000000 /* Flags */
+#define PSR_c 0x000000ff /* Control */
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This struct defines the way the registers are stored on the
+ * stack during a system call. Note that sizeof(struct pt_regs)
+ * has to be a multiple of 8.
+ */
+struct pt_regs {
+ unsigned long uregs[34];
+};
+
+#define UCreg_asr uregs[32]
+#define UCreg_pc uregs[31]
+#define UCreg_lr uregs[30]
+#define UCreg_sp uregs[29]
+#define UCreg_ip uregs[28]
+#define UCreg_fp uregs[27]
+#define UCreg_26 uregs[26]
+#define UCreg_25 uregs[25]
+#define UCreg_24 uregs[24]
+#define UCreg_23 uregs[23]
+#define UCreg_22 uregs[22]
+#define UCreg_21 uregs[21]
+#define UCreg_20 uregs[20]
+#define UCreg_19 uregs[19]
+#define UCreg_18 uregs[18]
+#define UCreg_17 uregs[17]
+#define UCreg_16 uregs[16]
+#define UCreg_15 uregs[15]
+#define UCreg_14 uregs[14]
+#define UCreg_13 uregs[13]
+#define UCreg_12 uregs[12]
+#define UCreg_11 uregs[11]
+#define UCreg_10 uregs[10]
+#define UCreg_09 uregs[9]
+#define UCreg_08 uregs[8]
+#define UCreg_07 uregs[7]
+#define UCreg_06 uregs[6]
+#define UCreg_05 uregs[5]
+#define UCreg_04 uregs[4]
+#define UCreg_03 uregs[3]
+#define UCreg_02 uregs[2]
+#define UCreg_01 uregs[1]
+#define UCreg_00 uregs[0]
+#define UCreg_ORIG_00 uregs[33]
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI__UNICORE_PTRACE_H__ */
diff --git a/arch/unicore32/include/asm/sigcontext.h b/arch/unicore32/include/uapi/asm/sigcontext.h
index 6a2d7671c05..6a2d7671c05 100644
--- a/arch/unicore32/include/asm/sigcontext.h
+++ b/arch/unicore32/include/uapi/asm/sigcontext.h
diff --git a/arch/unicore32/include/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h
index 2abcf61c615..d18a3be89b3 100644
--- a/arch/unicore32/include/asm/unistd.h
+++ b/arch/unicore32/include/uapi/asm/unistd.h
@@ -12,3 +12,4 @@
/* Use the standard ABI for syscalls. */
#include <asm-generic/unistd.h>
+#define __ARCH_WANT_SYS_EXECVE
diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S
index dcb87ab19dd..7049350c790 100644
--- a/arch/unicore32/kernel/entry.S
+++ b/arch/unicore32/kernel/entry.S
@@ -573,17 +573,16 @@ ENDPROC(ret_to_user)
*/
ENTRY(ret_from_fork)
b.l schedule_tail
- get_thread_info tsk
- ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing
- mov why, #1
- cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
- beq ret_slow_syscall
- mov r1, sp
- mov r0, #1 @ trace exit [IP = 1]
- b.l syscall_trace
b ret_slow_syscall
ENDPROC(ret_from_fork)
+ENTRY(ret_from_kernel_thread)
+ b.l schedule_tail
+ mov r0, r5
+ adr lr, ret_slow_syscall
+ mov pc, r4
+ENDPROC(ret_from_kernel_thread)
+
/*=============================================================================
* SWI handler
*-----------------------------------------------------------------------------
@@ -669,11 +668,6 @@ __cr_alignment:
#endif
.ltorg
-ENTRY(sys_execve)
- add r3, sp, #S_OFF
- b __sys_execve
-ENDPROC(sys_execve)
-
ENTRY(sys_clone)
add ip, sp, #S_OFF
stw ip, [sp+], #4
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c
index b008586dad7..a8fe265ce2c 100644
--- a/arch/unicore32/kernel/process.c
+++ b/arch/unicore32/kernel/process.c
@@ -258,6 +258,7 @@ void release_thread(struct task_struct *dead_task)
}
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
int
copy_thread(unsigned long clone_flags, unsigned long stack_start,
@@ -266,17 +267,22 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
struct thread_info *thread = task_thread_info(p);
struct pt_regs *childregs = task_pt_regs(p);
- *childregs = *regs;
- childregs->UCreg_00 = 0;
- childregs->UCreg_sp = stack_start;
-
memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
thread->cpu_context.sp = (unsigned long)childregs;
- thread->cpu_context.pc = (unsigned long)ret_from_fork;
-
- if (clone_flags & CLONE_SETTLS)
- childregs->UCreg_16 = regs->UCreg_03;
+ if (unlikely(!regs)) {
+ thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread;
+ thread->cpu_context.r4 = stack_start;
+ thread->cpu_context.r5 = stk_sz;
+ memset(childregs, 0, sizeof(struct pt_regs));
+ } else {
+ thread->cpu_context.pc = (unsigned long)ret_from_fork;
+ *childregs = *regs;
+ childregs->UCreg_00 = 0;
+ childregs->UCreg_sp = stack_start;
+ if (clone_flags & CLONE_SETTLS)
+ childregs->UCreg_16 = regs->UCreg_03;
+ }
return 0;
}
@@ -305,42 +311,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp)
}
EXPORT_SYMBOL(dump_fpu);
-/*
- * Shuffle the argument into the correct register before calling the
- * thread function. r1 is the thread argument, r2 is the pointer to
- * the thread function, and r3 points to the exit function.
- */
-asm(".pushsection .text\n"
-" .align\n"
-" .type kernel_thread_helper, #function\n"
-"kernel_thread_helper:\n"
-" mov.a asr, r7\n"
-" mov r0, r4\n"
-" mov lr, r6\n"
-" mov pc, r5\n"
-" .size kernel_thread_helper, . - kernel_thread_helper\n"
-" .popsection");
-
-/*
- * Create a kernel thread.
- */
-pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
- struct pt_regs regs;
-
- memset(&regs, 0, sizeof(regs));
-
- regs.UCreg_04 = (unsigned long)arg;
- regs.UCreg_05 = (unsigned long)fn;
- regs.UCreg_06 = (unsigned long)do_exit;
- regs.UCreg_07 = PRIV_MODE;
- regs.UCreg_pc = (unsigned long)kernel_thread_helper;
- regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT;
-
- return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
unsigned long get_wchan(struct task_struct *p)
{
struct stackframe frame;
diff --git a/arch/unicore32/kernel/setup.h b/arch/unicore32/kernel/setup.h
index f23955028a1..30f749da8f7 100644
--- a/arch/unicore32/kernel/setup.h
+++ b/arch/unicore32/kernel/setup.h
@@ -30,4 +30,10 @@ extern char __vectors_start[], __vectors_end[];
extern void kernel_thread_helper(void);
extern void __init early_signal_init(void);
+
+extern asmlinkage void __backtrace(void);
+extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
+
+extern void __show_regs(struct pt_regs *);
+
#endif
diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c
index fabdee96110..9680134b31f 100644
--- a/arch/unicore32/kernel/sys.c
+++ b/arch/unicore32/kernel/sys.c
@@ -42,69 +42,6 @@ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp,
parent_tid, child_tid);
}
-/* sys_execve() executes a new program.
- * This is called indirectly via a small wrapper
- */
-asmlinkage long __sys_execve(const char __user *filename,
- const char __user *const __user *argv,
- const char __user *const __user *envp,
- struct pt_regs *regs)
-{
- int error;
- struct filename *fn;
-
- fn = getname(filename);
- error = PTR_ERR(fn);
- if (IS_ERR(fn))
- goto out;
- error = do_execve(fn->name, argv, envp, regs);
- putname(fn);
-out:
- return error;
-}
-
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
-{
- struct pt_regs regs;
- int ret;
-
- memset(&regs, 0, sizeof(struct pt_regs));
- ret = do_execve(filename,
- (const char __user *const __user *)argv,
- (const char __user *const __user *)envp, &regs);
- if (ret < 0)
- goto out;
-
- /*
- * Save argc to the register structure for userspace.
- */
- regs.UCreg_00 = ret;
-
- /*
- * We were successful. We won't be returning to our caller, but
- * instead to user space by manipulating the kernel stack.
- */
- asm("add r0, %0, %1\n\t"
- "mov r1, %2\n\t"
- "mov r2, %3\n\t"
- "mov r22, #0\n\t" /* not a syscall */
- "mov r23, %0\n\t" /* thread structure */
- "b.l memmove\n\t" /* copy regs to top of stack */
- "mov sp, r0\n\t" /* reposition stack pointer */
- "b ret_to_user"
- :
- : "r" (current_thread_info()),
- "Ir" (THREAD_START_SP - sizeof(regs)),
- "r" (&regs),
- "Ir" (sizeof(regs))
- : "r0", "r1", "r2", "r3", "ip", "lr", "memory");
-
- out:
- return ret;
-}
-
/* Note: used by the compat code even in 64-bit Linux. */
SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c
index 2eeb9c04cab..f9b5c10bcce 100644
--- a/arch/unicore32/mm/fault.c
+++ b/arch/unicore32/mm/fault.c
@@ -168,7 +168,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma)
}
static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
- struct task_struct *tsk)
+ unsigned int flags, struct task_struct *tsk)
{
struct vm_area_struct *vma;
int fault;
@@ -194,14 +194,7 @@ good_area:
* If for any reason at all we couldn't handle the fault, make
* sure we exit gracefully rather than endlessly redo the fault.
*/
- fault = handle_mm_fault(mm, vma, addr & PAGE_MASK,
- (!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0);
- if (unlikely(fault & VM_FAULT_ERROR))
- return fault;
- if (fault & VM_FAULT_MAJOR)
- tsk->maj_flt++;
- else
- tsk->min_flt++;
+ fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags);
return fault;
check_stack:
@@ -216,6 +209,8 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
struct task_struct *tsk;
struct mm_struct *mm;
int fault, sig, code;
+ unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
+ ((!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0);
tsk = current;
mm = tsk->mm;
@@ -236,6 +231,7 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (!user_mode(regs)
&& !search_exception_tables(regs->UCreg_pc))
goto no_context;
+retry:
down_read(&mm->mmap_sem);
} else {
/*
@@ -251,7 +247,28 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
#endif
}
- fault = __do_pf(mm, addr, fsr, tsk);
+ fault = __do_pf(mm, addr, fsr, flags, tsk);
+
+ /* If we need to retry but a fatal signal is pending, handle the
+ * signal first. We do not need to release the mmap_sem because
+ * it would already be released in __lock_page_or_retry in
+ * mm/filemap.c. */
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+ return 0;
+
+ if (!(fault & VM_FAULT_ERROR) && (flags & FAULT_FLAG_ALLOW_RETRY)) {
+ if (fault & VM_FAULT_MAJOR)
+ tsk->maj_flt++;
+ else
+ tsk->min_flt++;
+ if (fault & VM_FAULT_RETRY) {
+ /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
+ * of starvation. */
+ flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ goto retry;
+ }
+ }
+
up_read(&mm->mmap_sem);
/*
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 59c226d120c..c20d1ce62dc 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -359,18 +359,14 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val,
return _hypercall4(int, update_va_mapping, va,
new_val.pte, new_val.pte >> 32, flags);
}
+extern int __must_check xen_event_channel_op_compat(int, void *);
static inline int
HYPERVISOR_event_channel_op(int cmd, void *arg)
{
int rc = _hypercall2(int, event_channel_op, cmd, arg);
- if (unlikely(rc == -ENOSYS)) {
- struct evtchn_op op;
- op.cmd = cmd;
- memcpy(&op.u, arg, sizeof(op.u));
- rc = _hypercall1(int, event_channel_op_compat, &op);
- memcpy(arg, &op.u, sizeof(op.u));
- }
+ if (unlikely(rc == -ENOSYS))
+ rc = xen_event_channel_op_compat(cmd, arg);
return rc;
}
@@ -386,17 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str)
return _hypercall3(int, console_io, cmd, count, str);
}
+extern int __must_check HYPERVISOR_physdev_op_compat(int, void *);
+
static inline int
HYPERVISOR_physdev_op(int cmd, void *arg)
{
int rc = _hypercall2(int, physdev_op, cmd, arg);
- if (unlikely(rc == -ENOSYS)) {
- struct physdev_op op;
- op.cmd = cmd;
- memcpy(&op.u, arg, sizeof(op.u));
- rc = _hypercall1(int, physdev_op_compat, &op);
- memcpy(arg, &op.u, sizeof(op.u));
- }
+ if (unlikely(rc == -ENOSYS))
+ rc = HYPERVISOR_physdev_op_compat(cmd, arg);
return rc;
}
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index a10e4601685..58fc5148882 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -24,6 +24,9 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu)
{
struct kvm_cpuid_entry2 *best;
+ if (!static_cpu_has(X86_FEATURE_XSAVE))
+ return 0;
+
best = kvm_find_cpuid_entry(vcpu, 1, 0);
return best && (best->ecx & bit(X86_FEATURE_XSAVE));
}
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ad6b1dd06f8..f85815945fc 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -6549,19 +6549,22 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
}
}
- exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
/* Exposing INVPCID only when PCID is exposed */
best = kvm_find_cpuid_entry(vcpu, 0x7, 0);
if (vmx_invpcid_supported() &&
best && (best->ebx & bit(X86_FEATURE_INVPCID)) &&
guest_cpuid_has_pcid(vcpu)) {
+ exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
exec_control |= SECONDARY_EXEC_ENABLE_INVPCID;
vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
exec_control);
} else {
- exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID;
- vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
- exec_control);
+ if (cpu_has_secondary_exec_ctrls()) {
+ exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
+ exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID;
+ vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
+ exec_control);
+ }
if (best)
best->ebx &= ~bit(X86_FEATURE_INVPCID);
}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 224a7e78cb6..4f7641756be 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5781,6 +5781,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
int pending_vec, max_bits, idx;
struct desc_ptr dt;
+ if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE))
+ return -EINVAL;
+
dt.size = sregs->idt.limit;
dt.address = sregs->idt.base;
kvm_x86_ops->set_idt(vcpu, &dt);
diff --git a/block/blk-exec.c b/block/blk-exec.c
index 8b6dc5bd4dd..f71eac35c1b 100644
--- a/block/blk-exec.c
+++ b/block/blk-exec.c
@@ -52,11 +52,17 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
rq_end_io_fn *done)
{
int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
+ bool is_pm_resume;
WARN_ON(irqs_disabled());
rq->rq_disk = bd_disk;
rq->end_io = done;
+ /*
+ * need to check this before __blk_run_queue(), because rq can
+ * be freed before that returns.
+ */
+ is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME;
spin_lock_irq(q->queue_lock);
@@ -71,7 +77,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
__elv_add_request(q, rq, where);
__blk_run_queue(q);
/* the queue is stopped so it won't be run */
- if (rq->cmd_type == REQ_TYPE_PM_RESUME)
+ if (is_pm_resume)
q->request_fn(q);
spin_unlock_irq(q->queue_lock);
}
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index 671d4d6d14d..7bdd61b867c 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -137,13 +137,18 @@ static void cryptd_queue_worker(struct work_struct *work)
struct crypto_async_request *req, *backlog;
cpu_queue = container_of(work, struct cryptd_cpu_queue, work);
- /* Only handle one request at a time to avoid hogging crypto
- * workqueue. preempt_disable/enable is used to prevent
- * being preempted by cryptd_enqueue_request() */
+ /*
+ * Only handle one request at a time to avoid hogging crypto workqueue.
+ * preempt_disable/enable is used to prevent being preempted by
+ * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent
+ * cryptd_enqueue_request() being accessed from software interrupts.
+ */
+ local_bh_disable();
preempt_disable();
backlog = crypto_get_backlog(&cpu_queue->queue);
req = crypto_dequeue_request(&cpu_queue->queue);
preempt_enable();
+ local_bh_enable();
if (!req)
return;
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index b1ae48054dc..b7078afddb7 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -238,7 +238,7 @@ static int __devexit ahci_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int ahci_suspend(struct device *dev)
{
struct ahci_platform_data *pdata = dev_get_platdata(dev);
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index fd9ecf74e63..5b0ba3f20ed 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -1105,10 +1105,15 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev,
struct acpi_device *acpi_dev;
struct acpi_device_power_state *states;
- if (ap->flags & ATA_FLAG_ACPI_SATA)
- ata_dev = &ap->link.device[sdev->channel];
- else
+ if (ap->flags & ATA_FLAG_ACPI_SATA) {
+ if (!sata_pmp_attached(ap))
+ ata_dev = &ap->link.device[sdev->id];
+ else
+ ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id];
+ }
+ else {
ata_dev = &ap->link.device[sdev->id];
+ }
*handle = ata_dev_acpi_handle(ata_dev);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3cc7096cfda..f46fbd3bd3f 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2942,6 +2942,10 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode)
if (xfer_mode == t->mode)
return t;
+
+ WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n",
+ __func__, xfer_mode);
+
return NULL;
}
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index e3bda074fa1..a6df6a351d6 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1052,6 +1052,8 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
{
sdev->use_10_for_rw = 1;
sdev->use_10_for_ms = 1;
+ sdev->no_report_opcodes = 1;
+ sdev->no_write_same = 1;
/* Schedule policy is determined by ->qc_defer() callback and
* it needs to see every deferred qc. Set dev_blocked to 1 to
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c
index 26201ebef3c..371fd2c698b 100644
--- a/drivers/ata/pata_arasan_cf.c
+++ b/drivers/ata/pata_arasan_cf.c
@@ -317,6 +317,12 @@ static int cf_init(struct arasan_cf_dev *acdev)
return ret;
}
+ ret = clk_set_rate(acdev->clk, 166000000);
+ if (ret) {
+ dev_warn(acdev->host->dev, "clock set rate failed");
+ return ret;
+ }
+
spin_lock_irqsave(&acdev->host->lock, flags);
/* configure CF interface clock */
writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk :
@@ -908,7 +914,7 @@ static int __devexit arasan_cf_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int arasan_cf_suspend(struct device *dev)
{
struct ata_host *host = dev_get_drvdata(dev);
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
index 0d7c4c2cd26..400bf1c3e98 100644
--- a/drivers/ata/sata_highbank.c
+++ b/drivers/ata/sata_highbank.c
@@ -260,7 +260,7 @@ static const struct of_device_id ahci_of_match[] = {
};
MODULE_DEVICE_TABLE(of, ahci_of_match);
-static int __init ahci_highbank_probe(struct platform_device *pdev)
+static int __devinit ahci_highbank_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ahci_host_priv *hpriv;
@@ -378,7 +378,7 @@ static int __devexit ahci_highbank_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int ahci_highbank_suspend(struct device *dev)
{
struct ata_host *host = dev_get_drvdata(dev);
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index 44a4256533e..08608de87e4 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -142,6 +142,39 @@ static int k2_sata_scr_write(struct ata_link *link,
return 0;
}
+static int k2_sata_softreset(struct ata_link *link,
+ unsigned int *class, unsigned long deadline)
+{
+ u8 dmactl;
+ void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
+
+ dmactl = readb(mmio + ATA_DMA_CMD);
+
+ /* Clear the start bit */
+ if (dmactl & ATA_DMA_START) {
+ dmactl &= ~ATA_DMA_START;
+ writeb(dmactl, mmio + ATA_DMA_CMD);
+ }
+
+ return ata_sff_softreset(link, class, deadline);
+}
+
+static int k2_sata_hardreset(struct ata_link *link,
+ unsigned int *class, unsigned long deadline)
+{
+ u8 dmactl;
+ void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
+
+ dmactl = readb(mmio + ATA_DMA_CMD);
+
+ /* Clear the start bit */
+ if (dmactl & ATA_DMA_START) {
+ dmactl &= ~ATA_DMA_START;
+ writeb(dmactl, mmio + ATA_DMA_CMD);
+ }
+
+ return sata_sff_hardreset(link, class, deadline);
+}
static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
{
@@ -346,6 +379,8 @@ static struct scsi_host_template k2_sata_sht = {
static struct ata_port_operations k2_sata_ops = {
.inherits = &ata_bmdma_port_ops,
+ .softreset = k2_sata_softreset,
+ .hardreset = k2_sata_hardreset,
.sff_tf_load = k2_sata_tf_load,
.sff_tf_read = k2_sata_tf_read,
.sff_check_status = k2_stat_check_status,
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 8727e9c5eea..72c776f2a1f 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -83,9 +83,16 @@ EXPORT_SYMBOL_GPL(platform_get_resource);
*/
int platform_get_irq(struct platform_device *dev, unsigned int num)
{
+#ifdef CONFIG_SPARC
+ /* sparc does not have irqs represented as IORESOURCE_IRQ resources */
+ if (!dev || num >= dev->archdata.num_irqs)
+ return -ENXIO;
+ return dev->archdata.irqs[num];
+#else
struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
return r ? r->start : -ENXIO;
+#endif
}
EXPORT_SYMBOL_GPL(platform_get_irq);
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c
index 74a67e0019a..fbbd4ed2edf 100644
--- a/drivers/base/power/qos.c
+++ b/drivers/base/power/qos.c
@@ -451,7 +451,7 @@ int dev_pm_qos_add_ancestor_request(struct device *dev,
if (ancestor)
error = dev_pm_qos_add_request(ancestor, req, value);
- if (error)
+ if (error < 0)
req->dev = NULL;
return error;
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 3804a0af3ef..9fe4f186555 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -935,7 +935,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail)
/* cf. http://lkml.org/lkml/2006/10/31/28 */
if (!fastfail)
- q->request_fn(q);
+ __blk_run_queue(q);
}
static void
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 1c49d717396..2ddd64a9ffd 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4330,6 +4330,7 @@ out_unreg_region:
out_unreg_blkdev:
unregister_blkdev(FLOPPY_MAJOR, "fd");
out_put_disk:
+ destroy_workqueue(floppy_wq);
for (drive = 0; drive < N_DRIVE; drive++) {
if (!disks[drive])
break;
@@ -4340,7 +4341,6 @@ out_put_disk:
}
put_disk(disks[drive]);
}
- destroy_workqueue(floppy_wq);
return err;
}
@@ -4555,6 +4555,8 @@ static void __exit floppy_module_exit(void)
unregister_blkdev(FLOPPY_MAJOR, "fd");
platform_driver_unregister(&floppy_driver);
+ destroy_workqueue(floppy_wq);
+
for (drive = 0; drive < N_DRIVE; drive++) {
del_timer_sync(&motor_off_timer[drive]);
@@ -4578,7 +4580,6 @@ static void __exit floppy_module_exit(void)
cancel_delayed_work_sync(&fd_timeout);
cancel_delayed_work_sync(&fd_timer);
- destroy_workqueue(floppy_wq);
if (atomic_read(&usage_count))
floppy_release_irq_and_dma();
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index adc6f36564c..9694dd99bbb 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -559,7 +559,7 @@ static void mtip_timeout_function(unsigned long int data)
struct mtip_cmd *command;
int tag, cmdto_cnt = 0;
unsigned int bit, group;
- unsigned int num_command_slots = port->dd->slot_groups * 32;
+ unsigned int num_command_slots;
unsigned long to, tagaccum[SLOTBITS_IN_LONGS];
if (unlikely(!port))
@@ -572,6 +572,7 @@ static void mtip_timeout_function(unsigned long int data)
}
/* clear the tag accumulator */
memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
+ num_command_slots = port->dd->slot_groups * 32;
for (tag = 0; tag < num_command_slots; tag++) {
/*
@@ -2218,8 +2219,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
fis.device);
/* check for erase mode support during secure erase.*/
- if ((fis.command == ATA_CMD_SEC_ERASE_UNIT)
- && (outbuf[0] & MTIP_SEC_ERASE_MODE)) {
+ if ((fis.command == ATA_CMD_SEC_ERASE_UNIT) && outbuf &&
+ (outbuf[0] & MTIP_SEC_ERASE_MODE)) {
erasemode = 1;
}
@@ -2439,7 +2440,7 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd,
* return value
* None
*/
-static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
+static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector,
int nsect, int nents, int tag, void *callback,
void *data, int dir)
{
@@ -2447,6 +2448,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
struct mtip_port *port = dd->port;
struct mtip_cmd *command = &port->commands[tag];
int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+ u64 start = sector;
/* Map the scatter list for DMA access */
nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir);
@@ -2465,8 +2467,12 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
fis->opts = 1 << 7;
fis->command =
(dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE);
- *((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF);
- *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF);
+ fis->lba_low = start & 0xFF;
+ fis->lba_mid = (start >> 8) & 0xFF;
+ fis->lba_hi = (start >> 16) & 0xFF;
+ fis->lba_low_ex = (start >> 24) & 0xFF;
+ fis->lba_mid_ex = (start >> 32) & 0xFF;
+ fis->lba_hi_ex = (start >> 40) & 0xFF;
fis->device = 1 << 6;
fis->features = nsect & 0xFF;
fis->features_ex = (nsect >> 8) & 0xFF;
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h
index 5f4a917bd8b..b1742640556 100644
--- a/drivers/block/mtip32xx/mtip32xx.h
+++ b/drivers/block/mtip32xx/mtip32xx.h
@@ -34,7 +34,7 @@
#define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48
/* check for erase mode support during secure erase */
-#define MTIP_SEC_ERASE_MODE 0x3
+#define MTIP_SEC_ERASE_MODE 0x2
/* # of times to retry timed out/failed IOs */
#define MTIP_MAX_RETRIES 2
@@ -155,14 +155,14 @@ enum {
MTIP_DDF_REBUILD_FAILED_BIT = 8,
};
-__packed struct smart_attr{
+struct smart_attr {
u8 attr_id;
u16 flags;
u8 cur;
u8 worst;
u32 data;
u8 res[3];
-};
+} __packed;
/* Register Frame Information Structure (FIS), host to device. */
struct host_to_dev_fis {
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index fc2de5528dc..b00000e8aef 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -67,6 +67,7 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3304) },
{ USB_DEVICE(0x0930, 0x0215) },
{ USB_DEVICE(0x0489, 0xE03D) },
+ { USB_DEVICE(0x0489, 0xE027) },
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03F0, 0x311D) },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index debda27df9b..ee82f2fb65f 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -124,6 +124,7 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
+ { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE },
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
diff --git a/drivers/bus/omap-ocp2scp.c b/drivers/bus/omap-ocp2scp.c
index ff63560b846..0c48b0e05ed 100644
--- a/drivers/bus/omap-ocp2scp.c
+++ b/drivers/bus/omap-ocp2scp.c
@@ -22,6 +22,26 @@
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/platform_data/omap_ocp2scp.h>
+
+/**
+ * _count_resources - count for the number of resources
+ * @res: struct resource *
+ *
+ * Count and return the number of resources populated for the device that is
+ * connected to ocp2scp.
+ */
+static unsigned _count_resources(struct resource *res)
+{
+ int cnt = 0;
+
+ while (res->start != res->end) {
+ cnt++;
+ res++;
+ }
+
+ return cnt;
+}
static int ocp2scp_remove_devices(struct device *dev, void *c)
{
@@ -34,20 +54,62 @@ static int ocp2scp_remove_devices(struct device *dev, void *c)
static int __devinit omap_ocp2scp_probe(struct platform_device *pdev)
{
- int ret;
- struct device_node *np = pdev->dev.of_node;
+ int ret;
+ unsigned res_cnt, i;
+ struct device_node *np = pdev->dev.of_node;
+ struct platform_device *pdev_child;
+ struct omap_ocp2scp_platform_data *pdata = pdev->dev.platform_data;
+ struct omap_ocp2scp_dev *dev;
if (np) {
ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
if (ret) {
- dev_err(&pdev->dev, "failed to add resources for ocp2scp child\n");
+ dev_err(&pdev->dev,
+ "failed to add resources for ocp2scp child\n");
goto err0;
}
+ } else if (pdata) {
+ for (i = 0, dev = *pdata->devices; i < pdata->dev_cnt; i++,
+ dev++) {
+ res_cnt = _count_resources(dev->res);
+
+ pdev_child = platform_device_alloc(dev->drv_name,
+ PLATFORM_DEVID_AUTO);
+ if (!pdev_child) {
+ dev_err(&pdev->dev,
+ "failed to allocate mem for ocp2scp child\n");
+ goto err0;
+ }
+
+ ret = platform_device_add_resources(pdev_child,
+ dev->res, res_cnt);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to add resources for ocp2scp child\n");
+ goto err1;
+ }
+
+ pdev_child->dev.parent = &pdev->dev;
+
+ ret = platform_device_add(pdev_child);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to register ocp2scp child device\n");
+ goto err1;
+ }
+ }
+ } else {
+ dev_err(&pdev->dev, "OCP2SCP initialized without plat data\n");
+ return -EINVAL;
}
+
pm_runtime_enable(&pdev->dev);
return 0;
+err1:
+ platform_device_put(pdev_child);
+
err0:
device_for_each_child(&pdev->dev, NULL, ocp2scp_remove_devices);
diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c
index ca4a25ed844..e2c17d187d9 100644
--- a/drivers/clk/ux500/u8500_clk.c
+++ b/drivers/clk/ux500/u8500_clk.c
@@ -40,7 +40,7 @@ void u8500_clk_init(void)
CLK_IS_ROOT|CLK_IGNORE_UNUSED,
32768);
clk_register_clkdev(clk, "clk32k", NULL);
- clk_register_clkdev(clk, NULL, "rtc-pl031");
+ clk_register_clkdev(clk, "apb_pclk", "rtc-pl031");
/* PRCMU clocks */
fw_version = prcmu_get_fw_version();
@@ -228,10 +228,17 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE,
BIT(2), 0);
+ clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1");
+
clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE,
BIT(3), 0);
+ clk_register_clkdev(clk, "apb_pclk", "msp0");
+ clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.0");
+
clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE,
BIT(4), 0);
+ clk_register_clkdev(clk, "apb_pclk", "msp1");
+ clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.1");
clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE,
BIT(5), 0);
@@ -239,6 +246,7 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE,
BIT(6), 0);
+ clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2");
clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE,
BIT(7), 0);
@@ -246,6 +254,7 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE,
BIT(8), 0);
+ clk_register_clkdev(clk, "apb_pclk", "slimbus0");
clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE,
BIT(9), 0);
@@ -255,11 +264,16 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE,
BIT(10), 0);
+ clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4");
+
clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE,
BIT(11), 0);
+ clk_register_clkdev(clk, "apb_pclk", "msp3");
+ clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.3");
clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE,
BIT(0), 0);
+ clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3");
clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE,
BIT(1), 0);
@@ -279,12 +293,13 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE,
BIT(5), 0);
+ clk_register_clkdev(clk, "apb_pclk", "msp2");
+ clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.2");
clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE,
BIT(6), 0);
clk_register_clkdev(clk, "apb_pclk", "sdi1");
-
clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE,
BIT(7), 0);
clk_register_clkdev(clk, "apb_pclk", "sdi3");
@@ -316,10 +331,15 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE,
BIT(1), 0);
+ clk_register_clkdev(clk, "apb_pclk", "ssp0");
+
clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE,
BIT(2), 0);
+ clk_register_clkdev(clk, "apb_pclk", "ssp1");
+
clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE,
BIT(3), 0);
+ clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0");
clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE,
BIT(4), 0);
@@ -401,10 +421,17 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk",
U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "nmk-i2c.1");
+
clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk",
U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "msp0");
+ clk_register_clkdev(clk, NULL, "ux500-msp-i2s.0");
+
clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk",
U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "msp1");
+ clk_register_clkdev(clk, NULL, "ux500-msp-i2s.1");
clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk",
U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE);
@@ -412,17 +439,25 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk",
U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "nmk-i2c.2");
+
clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk",
- U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE);
- /* FIXME: Redefinition of BIT(3). */
+ U8500_CLKRST1_BASE, BIT(8), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "slimbus0");
+
clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk",
U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "nmk-i2c.4");
+
clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk",
U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "msp3");
+ clk_register_clkdev(clk, NULL, "ux500-msp-i2s.3");
/* Periph2 */
clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk",
U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "nmk-i2c.3");
clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk",
U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE);
@@ -430,6 +465,8 @@ void u8500_clk_init(void)
clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk",
U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "msp2");
+ clk_register_clkdev(clk, NULL, "ux500-msp-i2s.2");
clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk",
U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE);
@@ -450,10 +487,15 @@ void u8500_clk_init(void)
/* Periph3 */
clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk",
U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "ssp0");
+
clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk",
U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "ssp1");
+
clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk",
U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE);
+ clk_register_clkdev(clk, NULL, "nmk-i2c.0");
clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk",
U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE);
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 1162d6b3bf8..bb1b392f5cd 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -1546,6 +1546,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
struct sbp2_logical_unit *lu = sdev->hostdata;
sdev->use_10_for_rw = 1;
+ sdev->no_report_opcodes = 1;
+ sdev->no_write_same = 1;
if (sbp2_param_exclusive_login)
sdev->manage_start_stop = 1;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index d055cee3694..47150f5ded0 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -47,7 +47,7 @@ if GPIOLIB
config OF_GPIO
def_bool y
- depends on OF && !SPARC
+ depends on OF
config DEBUG_GPIO
bool "Debug GPIO calls"
@@ -466,7 +466,7 @@ config GPIO_ADP5588_IRQ
config GPIO_ADNP
tristate "Avionic Design N-bit GPIO expander"
- depends on I2C && OF
+ depends on I2C && OF_GPIO
help
This option enables support for N GPIOs found on Avionic Design
I2C GPIO expanders. The register space will be extended by powers
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c
index 0f425189de1..ce1c8476007 100644
--- a/drivers/gpio/gpio-mcp23s08.c
+++ b/drivers/gpio/gpio-mcp23s08.c
@@ -77,7 +77,7 @@ struct mcp23s08_driver_data {
/*----------------------------------------------------------------------*/
-#ifdef CONFIG_I2C
+#if IS_ENABLED(CONFIG_I2C)
static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg)
{
@@ -399,7 +399,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
break;
#endif /* CONFIG_SPI_MASTER */
-#ifdef CONFIG_I2C
+#if IS_ENABLED(CONFIG_I2C)
case MCP_TYPE_008:
mcp->ops = &mcp23008_ops;
mcp->chip.ngpio = 8;
@@ -473,7 +473,7 @@ fail:
/*----------------------------------------------------------------------*/
-#ifdef CONFIG_I2C
+#if IS_ENABLED(CONFIG_I2C)
static int __devinit mcp230xx_probe(struct i2c_client *client,
const struct i2c_device_id *id)
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index cf7afb9eb61..be65c0451ad 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -92,6 +92,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip)
return mvchip->membase + GPIO_OUT_OFF;
}
+static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip)
+{
+ return mvchip->membase + GPIO_BLINK_EN_OFF;
+}
+
static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip)
{
return mvchip->membase + GPIO_IO_CONF_OFF;
@@ -206,6 +211,23 @@ static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin)
return (u >> pin) & 1;
}
+static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value)
+{
+ struct mvebu_gpio_chip *mvchip =
+ container_of(chip, struct mvebu_gpio_chip, chip);
+ unsigned long flags;
+ u32 u;
+
+ spin_lock_irqsave(&mvchip->lock, flags);
+ u = readl_relaxed(mvebu_gpioreg_blink(mvchip));
+ if (value)
+ u |= 1 << pin;
+ else
+ u &= ~(1 << pin);
+ writel_relaxed(u, mvebu_gpioreg_blink(mvchip));
+ spin_unlock_irqrestore(&mvchip->lock, flags);
+}
+
static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
{
struct mvebu_gpio_chip *mvchip =
@@ -244,6 +266,7 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin,
if (ret)
return ret;
+ mvebu_gpio_blink(chip, pin, 0);
mvebu_gpio_set(chip, pin, value);
spin_lock_irqsave(&mvchip->lock, flags);
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 7ef1b673e1b..133b4132983 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -121,6 +121,8 @@ int drm_open(struct inode *inode, struct file *filp)
int minor_id = iminor(inode);
struct drm_minor *minor;
int retcode = 0;
+ int need_setup = 0;
+ struct address_space *old_mapping;
minor = idr_find(&drm_minors_idr, minor_id);
if (!minor)
@@ -132,23 +134,37 @@ int drm_open(struct inode *inode, struct file *filp)
if (drm_device_is_unplugged(dev))
return -ENODEV;
+ if (!dev->open_count++)
+ need_setup = 1;
+ mutex_lock(&dev->struct_mutex);
+ old_mapping = dev->dev_mapping;
+ if (old_mapping == NULL)
+ dev->dev_mapping = &inode->i_data;
+ /* ihold ensures nobody can remove inode with our i_data */
+ ihold(container_of(dev->dev_mapping, struct inode, i_data));
+ inode->i_mapping = dev->dev_mapping;
+ filp->f_mapping = dev->dev_mapping;
+ mutex_unlock(&dev->struct_mutex);
+
retcode = drm_open_helper(inode, filp, dev);
- if (!retcode) {
- atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
- if (!dev->open_count++)
- retcode = drm_setup(dev);
- }
- if (!retcode) {
- mutex_lock(&dev->struct_mutex);
- if (dev->dev_mapping == NULL)
- dev->dev_mapping = &inode->i_data;
- /* ihold ensures nobody can remove inode with our i_data */
- ihold(container_of(dev->dev_mapping, struct inode, i_data));
- inode->i_mapping = dev->dev_mapping;
- filp->f_mapping = dev->dev_mapping;
- mutex_unlock(&dev->struct_mutex);
+ if (retcode)
+ goto err_undo;
+ atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
+ if (need_setup) {
+ retcode = drm_setup(dev);
+ if (retcode)
+ goto err_undo;
}
+ return 0;
+err_undo:
+ mutex_lock(&dev->struct_mutex);
+ filp->f_mapping = old_mapping;
+ inode->i_mapping = old_mapping;
+ iput(container_of(dev->dev_mapping, struct inode, i_data));
+ dev->dev_mapping = old_mapping;
+ mutex_unlock(&dev->struct_mutex);
+ dev->open_count--;
return retcode;
}
EXPORT_SYMBOL(drm_open);
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index b726b478a4f..6345878ae1e 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -143,7 +143,7 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode)
int old_dpms;
/* PCH platforms and VLV only support on/off. */
- if (INTEL_INFO(dev)->gen < 5 && mode != DRM_MODE_DPMS_ON)
+ if (INTEL_INFO(dev)->gen >= 5 && mode != DRM_MODE_DPMS_ON)
mode = DRM_MODE_DPMS_OFF;
if (mode == connector->dpms)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 461a637f1ef..4154bcd7a07 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3841,6 +3841,17 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
}
}
+ if (intel_encoder->type == INTEL_OUTPUT_EDP) {
+ /* Use VBT settings if we have an eDP panel */
+ unsigned int edp_bpc = dev_priv->edp.bpp / 3;
+
+ if (edp_bpc < display_bpc) {
+ DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
+ display_bpc = edp_bpc;
+ }
+ continue;
+ }
+
/*
* HDMI is either 12 or 8, so if the display lets 10bpc sneak
* through, clamp it down. (Note: >12bpc will be caught below.)
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 79d308da29f..c600fb06e25 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2382,6 +2382,18 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags)
return true;
}
+static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo)
+{
+ struct drm_device *dev = intel_sdvo->base.base.dev;
+ struct drm_connector *connector, *tmp;
+
+ list_for_each_entry_safe(connector, tmp,
+ &dev->mode_config.connector_list, head) {
+ if (intel_attached_encoder(connector) == &intel_sdvo->base)
+ intel_sdvo_destroy(connector);
+ }
+}
+
static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
struct intel_sdvo_connector *intel_sdvo_connector,
int type)
@@ -2705,7 +2717,8 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
intel_sdvo->caps.output_flags) != true) {
DRM_DEBUG_KMS("SDVO output failed to setup on %s\n",
SDVO_NAME(intel_sdvo));
- goto err;
+ /* Output_setup can leave behind connectors! */
+ goto err_output;
}
/* Only enable the hotplug irq if we need it, to work around noisy
@@ -2718,12 +2731,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
/* Set the input timing to the screen. Assume always input 0. */
if (!intel_sdvo_set_target_input(intel_sdvo))
- goto err;
+ goto err_output;
if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo,
&intel_sdvo->pixel_clock_min,
&intel_sdvo->pixel_clock_max))
- goto err;
+ goto err_output;
DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
"clock range %dMHz - %dMHz, "
@@ -2743,6 +2756,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
(SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
return true;
+err_output:
+ intel_sdvo_output_cleanup(intel_sdvo);
+
err:
drm_encoder_cleanup(&intel_encoder->base);
i2c_del_adapter(&intel_sdvo->ddc);
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
index 16a9afb1060..15b182c84ce 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -22,6 +22,8 @@
* Authors: Ben Skeggs
*/
+#include <subdev/bar.h>
+
#include <engine/software.h>
#include <engine/disp.h>
@@ -37,6 +39,7 @@ nv50_disp_sclass[] = {
static void
nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
{
+ struct nouveau_bar *bar = nouveau_bar(priv);
struct nouveau_disp *disp = &priv->base;
struct nouveau_software_chan *chan, *temp;
unsigned long flags;
@@ -46,19 +49,25 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
if (chan->vblank.crtc != crtc)
continue;
- nv_wr32(priv, 0x001704, chan->vblank.channel);
- nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
-
- if (nv_device(priv)->chipset == 0x50) {
- nv_wr32(priv, 0x001570, chan->vblank.offset);
- nv_wr32(priv, 0x001574, chan->vblank.value);
+ if (nv_device(priv)->chipset >= 0xc0) {
+ nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel);
+ bar->flush(bar);
+ nv_wr32(priv, 0x06000c,
+ upper_32_bits(chan->vblank.offset));
+ nv_wr32(priv, 0x060010,
+ lower_32_bits(chan->vblank.offset));
+ nv_wr32(priv, 0x060014, chan->vblank.value);
} else {
- if (nv_device(priv)->chipset >= 0xc0) {
- nv_wr32(priv, 0x06000c,
- upper_32_bits(chan->vblank.offset));
+ nv_wr32(priv, 0x001704, chan->vblank.channel);
+ nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
+ bar->flush(bar);
+ if (nv_device(priv)->chipset == 0x50) {
+ nv_wr32(priv, 0x001570, chan->vblank.offset);
+ nv_wr32(priv, 0x001574, chan->vblank.value);
+ } else {
+ nv_wr32(priv, 0x060010, chan->vblank.offset);
+ nv_wr32(priv, 0x060014, chan->vblank.value);
}
- nv_wr32(priv, 0x060010, chan->vblank.offset);
- nv_wr32(priv, 0x060014, chan->vblank.value);
}
list_del(&chan->vblank.head);
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c
index e45035efb8c..7bbb1e1b7a8 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c
@@ -669,21 +669,27 @@ nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem)
});
}
-void
+int
nv40_grctx_init(struct nouveau_device *device, u32 *size)
{
- u32 ctxprog[256], i;
+ u32 *ctxprog = kmalloc(256 * 4, GFP_KERNEL), i;
struct nouveau_grctx ctx = {
.device = device,
.mode = NOUVEAU_GRCTX_PROG,
.data = ctxprog,
- .ctxprog_max = ARRAY_SIZE(ctxprog)
+ .ctxprog_max = 256,
};
+ if (!ctxprog)
+ return -ENOMEM;
+
nv40_grctx_generate(&ctx);
nv_wr32(device, 0x400324, 0);
for (i = 0; i < ctx.ctxprog_len; i++)
nv_wr32(device, 0x400328, ctxprog[i]);
*size = ctx.ctxvals_pos * 4;
+
+ kfree(ctxprog);
+ return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
index 8d0021049ec..cc6574eeb80 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
@@ -156,8 +156,8 @@ nv40_graph_context_ctor(struct nouveau_object *parent,
static int
nv40_graph_context_fini(struct nouveau_object *object, bool suspend)
{
- struct nv04_graph_priv *priv = (void *)object->engine;
- struct nv04_graph_chan *chan = (void *)object;
+ struct nv40_graph_priv *priv = (void *)object->engine;
+ struct nv40_graph_chan *chan = (void *)object;
u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4;
int ret = 0;
@@ -346,7 +346,9 @@ nv40_graph_init(struct nouveau_object *object)
return ret;
/* generate and upload context program */
- nv40_grctx_init(nv_device(priv), &priv->size);
+ ret = nv40_grctx_init(nv_device(priv), &priv->size);
+ if (ret)
+ return ret;
/* No context present currently */
nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h
index d2ac975afc2..7da35a4e797 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h
@@ -15,7 +15,7 @@ nv44_graph_class(void *priv)
return !(0x0baf & (1 << (device->chipset & 0x0f)));
}
-void nv40_grctx_init(struct nouveau_device *, u32 *size);
+int nv40_grctx_init(struct nouveau_device *, u32 *size);
void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
index 12418574efe..f7c581ad199 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
@@ -38,7 +38,7 @@ struct nv40_mpeg_priv {
};
struct nv40_mpeg_chan {
- struct nouveau_mpeg base;
+ struct nouveau_mpeg_chan base;
};
/*******************************************************************************
diff --git a/drivers/gpu/drm/nouveau/core/include/core/object.h b/drivers/gpu/drm/nouveau/core/include/core/object.h
index 818feabbf4a..486f1a9217f 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/object.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/object.h
@@ -175,14 +175,18 @@ nv_mo32(void *obj, u32 addr, u32 mask, u32 data)
return temp;
}
-static inline bool
-nv_strncmp(void *obj, u32 addr, u32 len, const char *str)
+static inline int
+nv_memcmp(void *obj, u32 addr, const char *str, u32 len)
{
+ unsigned char c1, c2;
+
while (len--) {
- if (nv_ro08(obj, addr++) != *(str++))
- return false;
+ c1 = nv_ro08(obj, addr++);
+ c2 = *(str++);
+ if (c1 != c2)
+ return c1 - c2;
}
- return true;
+ return 0;
}
#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
index 39e73b91d36..41b7a6a76f1 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
@@ -54,6 +54,7 @@ int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
int clk, struct nouveau_pll_vals *);
int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1,
struct nouveau_pll_vals *);
-
+int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
+ int clk, struct nouveau_pll_vals *);
#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
index 7d750382a83..c5119715774 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
@@ -64,7 +64,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
} else
if (*ver >= 0x15) {
- if (!nv_strncmp(bios, dcb - 7, 7, "DEV_REC")) {
+ if (!nv_memcmp(bios, dcb - 7, "DEV_REC", 7)) {
u16 i2c = nv_ro16(bios, dcb + 2);
*hdr = 4;
*cnt = (i2c - dcb) / 10;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
index cc8d7d162d7..9068c98b96f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
@@ -66,6 +66,24 @@ nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
return ret;
}
+int
+nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
+ int clk, struct nouveau_pll_vals *pv)
+{
+ int ret, N, M, P;
+
+ ret = nva3_pll_calc(clock, info, clk, &N, NULL, &M, &P);
+
+ if (ret > 0) {
+ pv->refclk = info->refclk;
+ pv->N1 = N;
+ pv->M1 = M;
+ pv->log2P = P;
+ }
+ return ret;
+}
+
+
static int
nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
@@ -80,6 +98,7 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
priv->base.pll_set = nva3_clock_pll_set;
+ priv->base.pll_calc = nva3_clock_pll_calc;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
index 5ccce0b17bf..f6962c9b6c3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
@@ -79,6 +79,7 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
priv->base.pll_set = nvc0_clock_pll_set;
+ priv->base.pll_calc = nva3_clock_pll_calc;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
index 49050d991e7..9474cfca6e4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
@@ -67,7 +67,7 @@ nv41_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
static void
nv41_vm_flush(struct nouveau_vm *vm)
{
- struct nv04_vm_priv *priv = (void *)vm->vmm;
+ struct nv04_vmmgr_priv *priv = (void *)vm->vmm;
mutex_lock(&nv_subdev(priv)->mutex);
nv_wr32(priv, 0x100810, 0x00000022);
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index cc79c796afe..cbf1fc60a38 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -241,6 +241,10 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
if (unlikely(!abi16))
return -ENOMEM;
+
+ if (!drm->channel)
+ return nouveau_abi16_put(abi16, -ENODEV);
+
client = nv_client(abi16->client);
if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 9a6e2cb282d..d3595b23434 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -355,7 +355,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
* valid - it's not (rh#613284)
*/
if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) {
- if (!(nv_connector->edid = nouveau_acpi_edid(dev, connector))) {
+ if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) {
status = connector_status_connected;
goto out;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 0910125cbbc..8503b2ea570 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -129,7 +129,8 @@ nouveau_accel_init(struct nouveau_drm *drm)
/* initialise synchronisation routines */
if (device->card_type < NV_10) ret = nv04_fence_create(drm);
- else if (device->chipset < 0x84) ret = nv10_fence_create(drm);
+ else if (device->card_type < NV_50) ret = nv10_fence_create(drm);
+ else if (device->chipset < 0x84) ret = nv50_fence_create(drm);
else if (device->card_type < NV_C0) ret = nv84_fence_create(drm);
else ret = nvc0_fence_create(drm);
if (ret) {
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 2e566e123e9..3bce0299f64 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1696,35 +1696,43 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
return ATOM_PPLL2;
DRM_ERROR("unable to allocate a PPLL\n");
return ATOM_PPLL_INVALID;
- } else {
- if (ASIC_IS_AVIVO(rdev)) {
- /* in DP mode, the DP ref clock can come from either PPLL
- * depending on the asic:
- * DCE3: PPLL1 or PPLL2
- */
- if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
- /* use the same PPLL for all DP monitors */
- pll = radeon_get_shared_dp_ppll(crtc);
- if (pll != ATOM_PPLL_INVALID)
- return pll;
- } else {
- /* use the same PPLL for all monitors with the same clock */
- pll = radeon_get_shared_nondp_ppll(crtc);
- if (pll != ATOM_PPLL_INVALID)
- return pll;
- }
- /* all other cases */
- pll_in_use = radeon_get_pll_use_mask(crtc);
+ } else if (ASIC_IS_AVIVO(rdev)) {
+ /* in DP mode, the DP ref clock can come from either PPLL
+ * depending on the asic:
+ * DCE3: PPLL1 or PPLL2
+ */
+ if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
+ /* use the same PPLL for all DP monitors */
+ pll = radeon_get_shared_dp_ppll(crtc);
+ if (pll != ATOM_PPLL_INVALID)
+ return pll;
+ } else {
+ /* use the same PPLL for all monitors with the same clock */
+ pll = radeon_get_shared_nondp_ppll(crtc);
+ if (pll != ATOM_PPLL_INVALID)
+ return pll;
+ }
+ /* all other cases */
+ pll_in_use = radeon_get_pll_use_mask(crtc);
+ /* the order shouldn't matter here, but we probably
+ * need this until we have atomic modeset
+ */
+ if (rdev->flags & RADEON_IS_IGP) {
if (!(pll_in_use & (1 << ATOM_PPLL1)))
return ATOM_PPLL1;
if (!(pll_in_use & (1 << ATOM_PPLL2)))
return ATOM_PPLL2;
- DRM_ERROR("unable to allocate a PPLL\n");
- return ATOM_PPLL_INVALID;
} else {
- /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */
- return radeon_crtc->crtc_id;
+ if (!(pll_in_use & (1 << ATOM_PPLL2)))
+ return ATOM_PPLL2;
+ if (!(pll_in_use & (1 << ATOM_PPLL1)))
+ return ATOM_PPLL1;
}
+ DRM_ERROR("unable to allocate a PPLL\n");
+ return ATOM_PPLL_INVALID;
+ } else {
+ /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */
+ return radeon_crtc->crtc_id;
}
}
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index ba498f8e47a..010bae19554 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -1625,7 +1625,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
/* some early dce3.2 boards have a bug in their transmitter control table */
- if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730))
+ if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730))
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
}
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 14313ad43b7..219942c660d 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1330,6 +1330,8 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
break;
udelay(1);
}
+ } else {
+ save->crtc_enabled[i] = false;
}
}
@@ -1372,7 +1374,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
for (i = 0; i < rdev->num_crtc; i++) {
- if (save->crtc_enabled) {
+ if (save->crtc_enabled[i]) {
if (ASIC_IS_DCE6(rdev)) {
tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index 95e6318b626..c042e497e45 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -2725,6 +2725,9 @@ static bool evergreen_vm_reg_valid(u32 reg)
/* check config regs */
switch (reg) {
case GRBM_GFX_INDEX:
+ case CP_STRMOUT_CNTL:
+ case CP_COHER_CNTL:
+ case CP_COHER_SIZE:
case VGT_VTX_VECT_EJECT_REG:
case VGT_CACHE_INVALIDATION:
case VGT_GS_VERTEX_REUSE:
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index df542f1a5df..2bc0f6a1b42 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -91,6 +91,10 @@
#define FB_READ_EN (1 << 0)
#define FB_WRITE_EN (1 << 1)
+#define CP_STRMOUT_CNTL 0x84FC
+
+#define CP_COHER_CNTL 0x85F0
+#define CP_COHER_SIZE 0x85F4
#define CP_COHER_BASE 0x85F8
#define CP_STALLED_STAT1 0x8674
#define CP_STALLED_STAT2 0x8678
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c
index 10ea17a6b2a..42433344cb1 100644
--- a/drivers/gpu/drm/radeon/radeon_agp.c
+++ b/drivers/gpu/drm/radeon/radeon_agp.c
@@ -69,9 +69,12 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = {
/* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/
{ PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59,
PCI_VENDOR_ID_DELL, 0x00e3, 2},
- /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */
+ /* Intel 82852/82855 host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 (lp #296617) */
{ PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66,
PCI_VENDOR_ID_DELL, 0x0149, 1},
+ /* Intel 82855PM host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 for suspend/resume */
+ { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66,
+ PCI_VENDOR_ID_IBM, 0x0531, 1},
/* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */
{ PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50,
0x1025, 0x0061, 1},
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index b0db712060f..4422d630b33 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -2474,6 +2474,7 @@ static bool si_vm_reg_valid(u32 reg)
/* check config regs */
switch (reg) {
case GRBM_GFX_INDEX:
+ case CP_STRMOUT_CNTL:
case VGT_VTX_VECT_EJECT_REG:
case VGT_CACHE_INVALIDATION:
case VGT_ESGS_RING_SIZE:
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
index 7d2a20e5657..a8871afc5b4 100644
--- a/drivers/gpu/drm/radeon/sid.h
+++ b/drivers/gpu/drm/radeon/sid.h
@@ -424,6 +424,7 @@
# define RDERR_INT_ENABLE (1 << 0)
# define GUI_IDLE_INT_ENABLE (1 << 19)
+#define CP_STRMOUT_CNTL 0x84FC
#define SCRATCH_REG0 0x8500
#define SCRATCH_REG1 0x8504
#define SCRATCH_REG2 0x8508
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
index 860dc4813e9..bd2a3b40cd1 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -749,7 +749,10 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags,
/* clear the pages coming from the pool if requested */
if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) {
list_for_each_entry(p, &plist, lru) {
- clear_page(page_address(p));
+ if (PageHighMem(p))
+ clear_highpage(p);
+ else
+ clear_page(page_address(p));
}
}
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index bf8260133ea..7d759a43029 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -308,9 +308,7 @@ int ttm_tt_swapin(struct ttm_tt *ttm)
if (unlikely(to_page == NULL))
goto out_err;
- preempt_disable();
copy_highpage(to_page, from_page);
- preempt_enable();
page_cache_release(from_page);
}
@@ -358,9 +356,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
ret = PTR_ERR(to_page);
goto out_err;
}
- preempt_disable();
copy_highpage(to_page, from_page);
- preempt_enable();
set_page_dirty(to_page);
mark_page_accessed(to_page);
page_cache_release(to_page);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
index 3ce68a2e312..d1498bfd787 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
@@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin)
BUG_ON(!atomic_read(&bo->reserved));
BUG_ON(old_mem_type != TTM_PL_VRAM &&
- old_mem_type != VMW_PL_FLAG_GMR);
+ old_mem_type != VMW_PL_GMR);
pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED;
if (pin)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index ed3c1e7ddde..2dd185e42f2 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1098,6 +1098,11 @@ static void vmw_pm_complete(struct device *kdev)
struct drm_device *dev = pci_get_drvdata(pdev);
struct vmw_private *dev_priv = vmw_priv(dev);
+ mutex_lock(&dev_priv->hw_mutex);
+ vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
+ (void) vmw_read(dev_priv, SVGA_REG_ID);
+ mutex_unlock(&dev_priv->hw_mutex);
+
/**
* Reclaim 3d reference held by fbdev and potentially
* start fifo.
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index b07ca2e4d04..7290811f89b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -110,6 +110,8 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data,
memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size);
ret = copy_to_user(buffer, bounce, size);
+ if (ret)
+ ret = -EFAULT;
vfree(bounce);
if (unlikely(ret != 0))
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index f676c01bb47..6fcd466d082 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -46,9 +46,9 @@ static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[559] = 0x45;
}
/* the same as above (s/usage/physical/) */
- if ((quirks & MS_RDESC_3K) && *rsize == 106 &&
- !memcmp((char []){ 0x19, 0x00, 0x29, 0xff },
- &rdesc[94], 4)) {
+ if ((quirks & MS_RDESC_3K) && *rsize == 106 && rdesc[94] == 0x19 &&
+ rdesc[95] == 0x00 && rdesc[96] == 0x29 &&
+ rdesc[97] == 0xff) {
rdesc[94] = 0x35;
rdesc[96] = 0x45;
}
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 17d15bb610d..7c47fc3f7b2 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -42,7 +42,6 @@ static struct cdev hidraw_cdev;
static struct class *hidraw_class;
static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES];
static DEFINE_MUTEX(minors_lock);
-static void drop_ref(struct hidraw *hid, int exists_bit);
static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
@@ -114,7 +113,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer,
__u8 *buf;
int ret = 0;
- if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
+ if (!hidraw_table[minor]) {
ret = -ENODEV;
goto out;
}
@@ -262,7 +261,7 @@ static int hidraw_open(struct inode *inode, struct file *file)
}
mutex_lock(&minors_lock);
- if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
+ if (!hidraw_table[minor]) {
err = -ENODEV;
goto out_unlock;
}
@@ -299,12 +298,36 @@ out:
static int hidraw_release(struct inode * inode, struct file * file)
{
unsigned int minor = iminor(inode);
+ struct hidraw *dev;
struct hidraw_list *list = file->private_data;
+ int ret;
+ int i;
+
+ mutex_lock(&minors_lock);
+ if (!hidraw_table[minor]) {
+ ret = -ENODEV;
+ goto unlock;
+ }
- drop_ref(hidraw_table[minor], 0);
list_del(&list->node);
+ dev = hidraw_table[minor];
+ if (!--dev->open) {
+ if (list->hidraw->exist) {
+ hid_hw_power(dev->hid, PM_HINT_NORMAL);
+ hid_hw_close(dev->hid);
+ } else {
+ kfree(list->hidraw);
+ }
+ }
+
+ for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i)
+ kfree(list->buffer[i].value);
kfree(list);
- return 0;
+ ret = 0;
+unlock:
+ mutex_unlock(&minors_lock);
+
+ return ret;
}
static long hidraw_ioctl(struct file *file, unsigned int cmd,
@@ -506,7 +529,21 @@ EXPORT_SYMBOL_GPL(hidraw_connect);
void hidraw_disconnect(struct hid_device *hid)
{
struct hidraw *hidraw = hid->hidraw;
- drop_ref(hidraw, 1);
+
+ mutex_lock(&minors_lock);
+ hidraw->exist = 0;
+
+ device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
+
+ hidraw_table[hidraw->minor] = NULL;
+
+ if (hidraw->open) {
+ hid_hw_close(hid);
+ wake_up_interruptible(&hidraw->wait);
+ } else {
+ kfree(hidraw);
+ }
+ mutex_unlock(&minors_lock);
}
EXPORT_SYMBOL_GPL(hidraw_disconnect);
@@ -555,23 +592,3 @@ void hidraw_exit(void)
unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES);
}
-
-static void drop_ref(struct hidraw *hidraw, int exists_bit)
-{
- mutex_lock(&minors_lock);
- if (exists_bit) {
- hid_hw_close(hidraw->hid);
- hidraw->exist = 0;
- if (hidraw->open)
- wake_up_interruptible(&hidraw->wait);
- } else {
- --hidraw->open;
- }
-
- if (!hidraw->open && !hidraw->exist) {
- device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
- hidraw_table[hidraw->minor] = NULL;
- kfree(hidraw);
- }
- mutex_unlock(&minors_lock);
-}
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
index a227be47149..520e5bf4f76 100644
--- a/drivers/hwmon/asb100.c
+++ b/drivers/hwmon/asb100.c
@@ -32,7 +32,7 @@
* ASB100-A supports pwm1, while plain ASB100 does not. There is no known
* way for the driver to tell which one is there.
*
- * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
+ * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
* asb100 7 3 1 4 0x31 0x0694 yes no
*/
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 1821b7423d5..de3c7e04c3b 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -2083,6 +2083,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
mutex_init(&data->lock);
mutex_init(&data->update_lock);
data->name = w83627ehf_device_names[sio_data->kind];
+ data->bank = 0xff; /* Force initial bank selection */
platform_set_drvdata(pdev, data);
/* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 5b1a6a66644..af158990870 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -25,7 +25,7 @@
/*
* Supports following chips:
*
- * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
+ * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
* w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC)
* w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC)
* w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC)
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 5a5046d94c3..20f11d31da4 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -24,7 +24,7 @@
/*
* Supports following chips:
*
- * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
+ * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
* as99127f 7 3 0 3 0x31 0x12c3 yes no
* as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no
* w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index 39ab7bcc616..ed397c64519 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -22,7 +22,7 @@
/*
* Supports following chips:
*
- * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
+ * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
* w83791d 10 5 5 3 0x71 0x5ca3 yes no
*
* The w83791d chip appears to be part way between the 83781d and the
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index 053645279f3..301942d0845 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -31,7 +31,7 @@
/*
* Supports following chips:
*
- * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
+ * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
* w83792d 9 7 7 3 0x7a 0x5ca3 yes no
*/
diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c
index f0e8286c3c7..79710bcac2f 100644
--- a/drivers/hwmon/w83l786ng.c
+++ b/drivers/hwmon/w83l786ng.c
@@ -20,7 +20,7 @@
/*
* Supports following chips:
*
- * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
+ * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
* w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no
*/
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index aa59a254be2..c02bf208084 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -39,6 +39,7 @@
#define AT91_TWI_STOP 0x0002 /* Send a Stop Condition */
#define AT91_TWI_MSEN 0x0004 /* Master Transfer Enable */
#define AT91_TWI_SVDIS 0x0020 /* Slave Transfer Disable */
+#define AT91_TWI_QUICK 0x0040 /* SMBus quick command */
#define AT91_TWI_SWRST 0x0080 /* Software Reset */
#define AT91_TWI_MMR 0x0004 /* Master Mode Register */
@@ -212,7 +213,11 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
INIT_COMPLETION(dev->cmd_complete);
dev->transfer_status = 0;
- if (dev->msg->flags & I2C_M_RD) {
+
+ if (!dev->buf_len) {
+ at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK);
+ at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP);
+ } else if (dev->msg->flags & I2C_M_RD) {
unsigned start_flags = AT91_TWI_START;
if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) {
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index 286ca191782..0670da79ee5 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -287,12 +287,14 @@ read_init_dma_fail:
select_init_dma_fail:
dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE);
select_init_pio_fail:
+ dmaengine_terminate_all(i2c->dmach);
return -EINVAL;
/* Write failpath. */
write_init_dma_fail:
dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
write_init_pio_fail:
+ dmaengine_terminate_all(i2c->dmach);
return -EINVAL;
}
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index db31eaed6ea..3525c9e62cb 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,7 +43,6 @@
#include <linux/slab.h>
#include <linux/i2c-omap.h>
#include <linux/pm_runtime.h>
-#include <linux/pm_qos.h>
/* I2C controller revisions */
#define OMAP_I2C_OMAP1_REV_2 0x20
@@ -187,8 +186,9 @@ struct omap_i2c_dev {
int reg_shift; /* bit shift for I2C register addresses */
struct completion cmd_complete;
struct resource *ioarea;
- u32 latency; /* maximum MPU wkup latency */
- struct pm_qos_request pm_qos_request;
+ u32 latency; /* maximum mpu wkup latency */
+ void (*set_mpu_wkup_lat)(struct device *dev,
+ long latency);
u32 speed; /* Speed of bus in kHz */
u32 dtrev; /* extra revision from DT */
u32 flags;
@@ -494,7 +494,9 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
dev->b_hw = 1; /* Enable hardware fixes */
/* calculate wakeup latency constraint for MPU */
- dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8);
+ if (dev->set_mpu_wkup_lat != NULL)
+ dev->latency = (1000000 * dev->threshold) /
+ (1000 * dev->speed / 8);
}
/*
@@ -522,6 +524,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
dev->buf = msg->buf;
dev->buf_len = msg->len;
+ /* make sure writes to dev->buf_len are ordered */
+ barrier();
+
omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len);
/* Clear the FIFO Buffers */
@@ -579,7 +584,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
*/
timeout = wait_for_completion_timeout(&dev->cmd_complete,
OMAP_I2C_TIMEOUT);
- dev->buf_len = 0;
if (timeout == 0) {
dev_err(dev->dev, "controller timed out\n");
omap_i2c_init(dev);
@@ -629,16 +633,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
if (r < 0)
goto out;
- /*
- * When waiting for completion of a i2c transfer, we need to
- * set a wake up latency constraint for the MPU. This is to
- * ensure quick enough wakeup from idle, when transfer
- * completes.
- */
- if (dev->latency)
- pm_qos_add_request(&dev->pm_qos_request,
- PM_QOS_CPU_DMA_LATENCY,
- dev->latency);
+ if (dev->set_mpu_wkup_lat != NULL)
+ dev->set_mpu_wkup_lat(dev->dev, dev->latency);
for (i = 0; i < num; i++) {
r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
@@ -646,8 +642,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
break;
}
- if (dev->latency)
- pm_qos_remove_request(&dev->pm_qos_request);
+ if (dev->set_mpu_wkup_lat != NULL)
+ dev->set_mpu_wkup_lat(dev->dev, -1);
if (r == 0)
r = num;
@@ -1104,6 +1100,7 @@ omap_i2c_probe(struct platform_device *pdev)
} else if (pdata != NULL) {
dev->speed = pdata->clkrate;
dev->flags = pdata->flags;
+ dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
dev->dtrev = pdata->rev;
}
@@ -1159,8 +1156,9 @@ omap_i2c_probe(struct platform_device *pdev)
dev->b_hw = 1; /* Enable hardware fixes */
/* calculate wakeup latency constraint for MPU */
- dev->latency = (1000000 * dev->fifo_size) /
- (1000 * dev->speed / 8);
+ if (dev->set_mpu_wkup_lat != NULL)
+ dev->latency = (1000000 * dev->fifo_size) /
+ (1000 * dev->speed / 8);
}
/* reset ASAP, clearing any IRQs */
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 3e0335f1fc6..9d902725bac 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -806,6 +806,7 @@ static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c)
dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio);
goto free_gpio;
}
+ i2c->gpios[idx] = gpio;
ret = gpio_request(gpio, "i2c-bus");
if (ret) {
diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c
index 5f097f309b9..7fa5b24b16d 100644
--- a/drivers/i2c/muxes/i2c-mux-pinctrl.c
+++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c
@@ -169,7 +169,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev)
mux->busses = devm_kzalloc(&pdev->dev,
sizeof(mux->busses) * mux->pdata->bus_count,
GFP_KERNEL);
- if (!mux->states) {
+ if (!mux->busses) {
dev_err(&pdev->dev, "Cannot allocate busses\n");
ret = -ENOMEM;
goto err;
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index c0ec7d42c3b..1abbc170d8b 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -26,10 +26,14 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src)
* input_mt_init_slots() - initialize MT input slots
* @dev: input device supporting MT events and finger tracking
* @num_slots: number of slots used by the device
+ * @flags: mt tasks to handle in core
*
* This function allocates all necessary memory for MT slot handling
* in the input device, prepares the ABS_MT_SLOT and
* ABS_MT_TRACKING_ID events for use and sets up appropriate buffers.
+ * Depending on the flags set, it also performs pointer emulation and
+ * frame synchronization.
+ *
* May be called repeatedly. Returns -EINVAL if attempting to
* reinitialize with a different number of slots.
*/
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 8f02e3d0e71..4c842c320c2 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -12,8 +12,8 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#define MOUSEDEV_MINOR_BASE 32
-#define MOUSEDEV_MINORS 32
-#define MOUSEDEV_MIX 31
+#define MOUSEDEV_MINORS 31
+#define MOUSEDEV_MIX 63
#include <linux/sched.h>
#include <linux/slab.h>
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index f02028ec3db..78e5d9ab0ba 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -955,7 +955,8 @@ static int ads7846_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume);
-static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts)
+static int __devinit ads7846_setup_pendown(struct spi_device *spi,
+ struct ads7846 *ts)
{
struct ads7846_platform_data *pdata = spi->dev.platform_data;
int err;
@@ -981,6 +982,9 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784
ts->gpio_pendown = pdata->gpio_pendown;
+ if (pdata->gpio_pendown_debounce)
+ gpio_set_debounce(pdata->gpio_pendown,
+ pdata->gpio_pendown_debounce);
} else {
dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n");
return -EINVAL;
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index d4a4cd445ca..0badfa48b32 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4108,7 +4108,7 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
static int intel_iommu_add_device(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
- struct pci_dev *bridge, *dma_pdev;
+ struct pci_dev *bridge, *dma_pdev = NULL;
struct iommu_group *group;
int ret;
@@ -4122,7 +4122,7 @@ static int intel_iommu_add_device(struct device *dev)
dma_pdev = pci_get_domain_bus_and_slot(
pci_domain_nr(pdev->bus),
bridge->subordinate->number, 0);
- else
+ if (!dma_pdev)
dma_pdev = pci_dev_get(bridge);
} else
dma_pdev = pci_dev_get(pdev);
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index a649f146d17..c0f7a426626 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -1054,6 +1054,7 @@ static int smmu_debugfs_stats_show(struct seq_file *s, void *v)
stats[i], val, offs);
}
seq_printf(s, "\n");
+ dput(dent);
return 0;
}
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c
index dc670ccc697..16c78f1c5ef 100644
--- a/drivers/irqchip/irq-bcm2835.c
+++ b/drivers/irqchip/irq-bcm2835.c
@@ -168,7 +168,8 @@ static int __init armctrl_of_init(struct device_node *node,
}
static struct of_device_id irq_of_match[] __initconst = {
- { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init }
+ { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init },
+ { }
};
void __init bcm2835_init_irq(void)
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig
index a233ed53913..86cd75a0e84 100644
--- a/drivers/isdn/Kconfig
+++ b/drivers/isdn/Kconfig
@@ -4,7 +4,7 @@
menuconfig ISDN
bool "ISDN support"
- depends on NET
+ depends on NET && NETDEVICES
depends on !S390 && !UML
---help---
ISDN ("Integrated Services Digital Network", called RNIS in France)
diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig
index 2302fbe70ac..9c6650ea848 100644
--- a/drivers/isdn/i4l/Kconfig
+++ b/drivers/isdn/i4l/Kconfig
@@ -6,7 +6,7 @@ if ISDN_I4L
config ISDN_PPP
bool "Support synchronous PPP"
- depends on INET && NETDEVICES
+ depends on INET
select SLHC
help
Over digital connections such as ISDN, there is no need to
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 8c610fa6782..e2a945ee9f0 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -1312,7 +1312,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
} else
return -EINVAL;
break;
-#ifdef CONFIG_NETDEVICES
case IIOCNETGPN:
/* Get peer phone number of a connected
* isdn network interface */
@@ -1322,7 +1321,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
return isdn_net_getpeer(&phone, argp);
} else
return -EINVAL;
-#endif
default:
return -EINVAL;
}
@@ -1352,7 +1350,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
case IIOCNETLCR:
printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n");
return -ENODEV;
-#ifdef CONFIG_NETDEVICES
case IIOCNETAIF:
/* Add a network-interface */
if (arg) {
@@ -1491,7 +1488,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
return -EFAULT;
return isdn_net_force_hangup(name);
break;
-#endif /* CONFIG_NETDEVICES */
case IIOCSETVER:
dev->net_verbose = arg;
printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose);
diff --git a/drivers/leds/ledtrig-cpu.c b/drivers/leds/ledtrig-cpu.c
index b312056da14..4239b3955ff 100644
--- a/drivers/leds/ledtrig-cpu.c
+++ b/drivers/leds/ledtrig-cpu.c
@@ -33,8 +33,6 @@
struct led_trigger_cpu {
char name[MAX_NAME_LEN];
struct led_trigger *_trig;
- struct mutex lock;
- int lock_is_inited;
};
static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig);
@@ -50,12 +48,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt)
{
struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig);
- /* mutex lock should be initialized before calling mutex_call() */
- if (!trig->lock_is_inited)
- return;
-
- mutex_lock(&trig->lock);
-
/* Locate the correct CPU LED */
switch (ledevt) {
case CPU_LED_IDLE_END:
@@ -75,8 +67,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt)
/* Will leave the LED as it is */
break;
}
-
- mutex_unlock(&trig->lock);
}
EXPORT_SYMBOL(ledtrig_cpu);
@@ -117,14 +107,9 @@ static int __init ledtrig_cpu_init(void)
for_each_possible_cpu(cpu) {
struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);
- mutex_init(&trig->lock);
-
snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu);
- mutex_lock(&trig->lock);
led_trigger_register_simple(trig->name, &trig->_trig);
- trig->lock_is_inited = 1;
- mutex_unlock(&trig->lock);
}
register_syscore_ops(&ledtrig_cpu_syscore_ops);
@@ -142,15 +127,9 @@ static void __exit ledtrig_cpu_exit(void)
for_each_possible_cpu(cpu) {
struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);
- mutex_lock(&trig->lock);
-
led_trigger_unregister_simple(trig->_trig);
trig->_trig = NULL;
memset(trig->name, 0, MAX_NAME_LEN);
- trig->lock_is_inited = 0;
-
- mutex_unlock(&trig->lock);
- mutex_destroy(&trig->lock);
}
unregister_syscore_ops(&ledtrig_cpu_syscore_ops);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 02db9183ca0..77e6eff41ca 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -740,8 +740,14 @@ static void rq_completed(struct mapped_device *md, int rw, int run_queue)
if (!md_in_flight(md))
wake_up(&md->wait);
+ /*
+ * Run this off this callpath, as drivers could invoke end_io while
+ * inside their request_fn (and holding the queue lock). Calling
+ * back into ->request_fn() could deadlock attempting to grab the
+ * queue lock again.
+ */
if (run_queue)
- blk_run_queue(md->queue);
+ blk_run_queue_async(md->queue);
/*
* dm_put() must be at the end of this function. See the comment above
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9ab768acfb6..61200717687 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1817,10 +1817,10 @@ retry:
memset(bbp, 0xff, PAGE_SIZE);
for (i = 0 ; i < bb->count ; i++) {
- u64 internal_bb = *p++;
+ u64 internal_bb = p[i];
u64 store_bb = ((BB_OFFSET(internal_bb) << 10)
| BB_LEN(internal_bb));
- *bbp++ = cpu_to_le64(store_bb);
+ bbp[i] = cpu_to_le64(store_bb);
}
bb->changed = 0;
if (read_seqretry(&bb->lock, seq))
@@ -5294,7 +5294,7 @@ void md_stop_writes(struct mddev *mddev)
}
EXPORT_SYMBOL_GPL(md_stop_writes);
-void md_stop(struct mddev *mddev)
+static void __md_stop(struct mddev *mddev)
{
mddev->ready = 0;
mddev->pers->stop(mddev);
@@ -5304,6 +5304,18 @@ void md_stop(struct mddev *mddev)
mddev->pers = NULL;
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
}
+
+void md_stop(struct mddev *mddev)
+{
+ /* stop the array and free an attached data structures.
+ * This is called from dm-raid
+ */
+ __md_stop(mddev);
+ bitmap_destroy(mddev);
+ if (mddev->bio_set)
+ bioset_free(mddev->bio_set);
+}
+
EXPORT_SYMBOL_GPL(md_stop);
static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
@@ -5364,7 +5376,7 @@ static int do_md_stop(struct mddev * mddev, int mode,
set_disk_ro(disk, 0);
__md_stop_writes(mddev);
- md_stop(mddev);
+ __md_stop(mddev);
mddev->queue->merge_bvec_fn = NULL;
mddev->queue->backing_dev_info.congested_fn = NULL;
@@ -7936,9 +7948,9 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors,
sector_t *first_bad, int *bad_sectors)
{
int hi;
- int lo = 0;
+ int lo;
u64 *p = bb->page;
- int rv = 0;
+ int rv;
sector_t target = s + sectors;
unsigned seq;
@@ -7953,7 +7965,8 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors,
retry:
seq = read_seqbegin(&bb->lock);
-
+ lo = 0;
+ rv = 0;
hi = bb->count;
/* Binary search between lo and hi for 'target'
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index d1295aff417..0d5d0ff2c0f 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -499,7 +499,7 @@ static void raid10_end_write_request(struct bio *bio, int error)
*/
one_write_done(r10_bio);
if (dec_rdev)
- rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev);
+ rdev_dec_pending(rdev, conf->mddev);
}
/*
@@ -1334,18 +1334,21 @@ retry_write:
blocked_rdev = rrdev;
break;
}
+ if (rdev && (test_bit(Faulty, &rdev->flags)
+ || test_bit(Unmerged, &rdev->flags)))
+ rdev = NULL;
if (rrdev && (test_bit(Faulty, &rrdev->flags)
|| test_bit(Unmerged, &rrdev->flags)))
rrdev = NULL;
r10_bio->devs[i].bio = NULL;
r10_bio->devs[i].repl_bio = NULL;
- if (!rdev || test_bit(Faulty, &rdev->flags) ||
- test_bit(Unmerged, &rdev->flags)) {
+
+ if (!rdev && !rrdev) {
set_bit(R10BIO_Degraded, &r10_bio->state);
continue;
}
- if (test_bit(WriteErrorSeen, &rdev->flags)) {
+ if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) {
sector_t first_bad;
sector_t dev_sector = r10_bio->devs[i].addr;
int bad_sectors;
@@ -1387,8 +1390,10 @@ retry_write:
max_sectors = good_sectors;
}
}
- r10_bio->devs[i].bio = bio;
- atomic_inc(&rdev->nr_pending);
+ if (rdev) {
+ r10_bio->devs[i].bio = bio;
+ atomic_inc(&rdev->nr_pending);
+ }
if (rrdev) {
r10_bio->devs[i].repl_bio = bio;
atomic_inc(&rrdev->nr_pending);
@@ -1444,69 +1449,71 @@ retry_write:
for (i = 0; i < conf->copies; i++) {
struct bio *mbio;
int d = r10_bio->devs[i].devnum;
- if (!r10_bio->devs[i].bio)
- continue;
+ if (r10_bio->devs[i].bio) {
+ struct md_rdev *rdev = conf->mirrors[d].rdev;
+ mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+ md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
+ max_sectors);
+ r10_bio->devs[i].bio = mbio;
+
+ mbio->bi_sector = (r10_bio->devs[i].addr+
+ choose_data_offset(r10_bio,
+ rdev));
+ mbio->bi_bdev = rdev->bdev;
+ mbio->bi_end_io = raid10_end_write_request;
+ mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
+ mbio->bi_private = r10_bio;
- mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
- md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
- max_sectors);
- r10_bio->devs[i].bio = mbio;
+ atomic_inc(&r10_bio->remaining);
- mbio->bi_sector = (r10_bio->devs[i].addr+
- choose_data_offset(r10_bio,
- conf->mirrors[d].rdev));
- mbio->bi_bdev = conf->mirrors[d].rdev->bdev;
- mbio->bi_end_io = raid10_end_write_request;
- mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
- mbio->bi_private = r10_bio;
+ cb = blk_check_plugged(raid10_unplug, mddev,
+ sizeof(*plug));
+ if (cb)
+ plug = container_of(cb, struct raid10_plug_cb,
+ cb);
+ else
+ plug = NULL;
+ spin_lock_irqsave(&conf->device_lock, flags);
+ if (plug) {
+ bio_list_add(&plug->pending, mbio);
+ plug->pending_cnt++;
+ } else {
+ bio_list_add(&conf->pending_bio_list, mbio);
+ conf->pending_count++;
+ }
+ spin_unlock_irqrestore(&conf->device_lock, flags);
+ if (!plug)
+ md_wakeup_thread(mddev->thread);
+ }
- atomic_inc(&r10_bio->remaining);
+ if (r10_bio->devs[i].repl_bio) {
+ struct md_rdev *rdev = conf->mirrors[d].replacement;
+ if (rdev == NULL) {
+ /* Replacement just got moved to main 'rdev' */
+ smp_mb();
+ rdev = conf->mirrors[d].rdev;
+ }
+ mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+ md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
+ max_sectors);
+ r10_bio->devs[i].repl_bio = mbio;
+
+ mbio->bi_sector = (r10_bio->devs[i].addr +
+ choose_data_offset(
+ r10_bio, rdev));
+ mbio->bi_bdev = rdev->bdev;
+ mbio->bi_end_io = raid10_end_write_request;
+ mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
+ mbio->bi_private = r10_bio;
- cb = blk_check_plugged(raid10_unplug, mddev, sizeof(*plug));
- if (cb)
- plug = container_of(cb, struct raid10_plug_cb, cb);
- else
- plug = NULL;
- spin_lock_irqsave(&conf->device_lock, flags);
- if (plug) {
- bio_list_add(&plug->pending, mbio);
- plug->pending_cnt++;
- } else {
+ atomic_inc(&r10_bio->remaining);
+ spin_lock_irqsave(&conf->device_lock, flags);
bio_list_add(&conf->pending_bio_list, mbio);
conf->pending_count++;
+ spin_unlock_irqrestore(&conf->device_lock, flags);
+ if (!mddev_check_plugged(mddev))
+ md_wakeup_thread(mddev->thread);
}
- spin_unlock_irqrestore(&conf->device_lock, flags);
- if (!plug)
- md_wakeup_thread(mddev->thread);
-
- if (!r10_bio->devs[i].repl_bio)
- continue;
-
- mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
- md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
- max_sectors);
- r10_bio->devs[i].repl_bio = mbio;
-
- /* We are actively writing to the original device
- * so it cannot disappear, so the replacement cannot
- * become NULL here
- */
- mbio->bi_sector = (r10_bio->devs[i].addr +
- choose_data_offset(
- r10_bio,
- conf->mirrors[d].replacement));
- mbio->bi_bdev = conf->mirrors[d].replacement->bdev;
- mbio->bi_end_io = raid10_end_write_request;
- mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
- mbio->bi_private = r10_bio;
-
- atomic_inc(&r10_bio->remaining);
- spin_lock_irqsave(&conf->device_lock, flags);
- bio_list_add(&conf->pending_bio_list, mbio);
- conf->pending_count++;
- spin_unlock_irqrestore(&conf->device_lock, flags);
- if (!mddev_check_plugged(mddev))
- md_wakeup_thread(mddev->thread);
}
/* Don't remove the bias on 'remaining' (one_write_done) until
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index c5439dce029..a4502686e7a 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2774,10 +2774,12 @@ static void handle_stripe_clean_event(struct r5conf *conf,
dev = &sh->dev[i];
if (!test_bit(R5_LOCKED, &dev->flags) &&
(test_bit(R5_UPTODATE, &dev->flags) ||
- test_and_clear_bit(R5_Discard, &dev->flags))) {
+ test_bit(R5_Discard, &dev->flags))) {
/* We can return any write requests */
struct bio *wbi, *wbi2;
pr_debug("Return write for disc %d\n", i);
+ if (test_and_clear_bit(R5_Discard, &dev->flags))
+ clear_bit(R5_UPTODATE, &dev->flags);
wbi = dev->written;
dev->written = NULL;
while (wbi && wbi->bi_sector <
@@ -2795,7 +2797,8 @@ static void handle_stripe_clean_event(struct r5conf *conf,
!test_bit(STRIPE_DEGRADED, &sh->state),
0);
}
- }
+ } else if (test_bit(R5_Discard, &sh->dev[i].flags))
+ clear_bit(R5_Discard, &sh->dev[i].flags);
if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state))
if (atomic_dec_and_test(&conf->pending_full_writes))
@@ -3490,40 +3493,6 @@ static void handle_stripe(struct stripe_head *sh)
handle_failed_sync(conf, sh, &s);
}
- /*
- * might be able to return some write requests if the parity blocks
- * are safe, or on a failed drive
- */
- pdev = &sh->dev[sh->pd_idx];
- s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx)
- || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx);
- qdev = &sh->dev[sh->qd_idx];
- s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx)
- || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx)
- || conf->level < 6;
-
- if (s.written &&
- (s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
- && !test_bit(R5_LOCKED, &pdev->flags)
- && (test_bit(R5_UPTODATE, &pdev->flags) ||
- test_bit(R5_Discard, &pdev->flags))))) &&
- (s.q_failed || ((test_bit(R5_Insync, &qdev->flags)
- && !test_bit(R5_LOCKED, &qdev->flags)
- && (test_bit(R5_UPTODATE, &qdev->flags) ||
- test_bit(R5_Discard, &qdev->flags))))))
- handle_stripe_clean_event(conf, sh, disks, &s.return_bi);
-
- /* Now we might consider reading some blocks, either to check/generate
- * parity, or to satisfy requests
- * or to load a block that is being partially written.
- */
- if (s.to_read || s.non_overwrite
- || (conf->level == 6 && s.to_write && s.failed)
- || (s.syncing && (s.uptodate + s.compute < disks))
- || s.replacing
- || s.expanding)
- handle_stripe_fill(sh, &s, disks);
-
/* Now we check to see if any write operations have recently
* completed
*/
@@ -3561,6 +3530,40 @@ static void handle_stripe(struct stripe_head *sh)
s.dec_preread_active = 1;
}
+ /*
+ * might be able to return some write requests if the parity blocks
+ * are safe, or on a failed drive
+ */
+ pdev = &sh->dev[sh->pd_idx];
+ s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx)
+ || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx);
+ qdev = &sh->dev[sh->qd_idx];
+ s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx)
+ || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx)
+ || conf->level < 6;
+
+ if (s.written &&
+ (s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
+ && !test_bit(R5_LOCKED, &pdev->flags)
+ && (test_bit(R5_UPTODATE, &pdev->flags) ||
+ test_bit(R5_Discard, &pdev->flags))))) &&
+ (s.q_failed || ((test_bit(R5_Insync, &qdev->flags)
+ && !test_bit(R5_LOCKED, &qdev->flags)
+ && (test_bit(R5_UPTODATE, &qdev->flags) ||
+ test_bit(R5_Discard, &qdev->flags))))))
+ handle_stripe_clean_event(conf, sh, disks, &s.return_bi);
+
+ /* Now we might consider reading some blocks, either to check/generate
+ * parity, or to satisfy requests
+ * or to load a block that is being partially written.
+ */
+ if (s.to_read || s.non_overwrite
+ || (conf->level == 6 && s.to_write && s.failed)
+ || (s.syncing && (s.uptodate + s.compute < disks))
+ || s.replacing
+ || s.expanding)
+ handle_stripe_fill(sh, &s, disks);
+
/* Now to consider new write requests and what else, if anything
* should be read. We do not handle new writes when:
* 1/ A 'write' operation (copy+xor) is already in flight.
@@ -5529,6 +5532,10 @@ static int run(struct mddev *mddev)
* discard data disk but write parity disk
*/
stripe = stripe * PAGE_SIZE;
+ /* Round up to power of 2, as discard handling
+ * currently assumes that */
+ while ((stripe-1) & stripe)
+ stripe = (stripe | (stripe-1)) + 1;
mddev->queue->limits.discard_alignment = stripe;
mddev->queue->limits.discard_granularity = stripe;
/*
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 660bbc52886..4d50da61816 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -208,7 +208,7 @@ static unsigned long exynos5250_dwmmc_caps[4] = {
MMC_CAP_CMD23,
};
-static struct dw_mci_drv_data exynos5250_drv_data = {
+static const struct dw_mci_drv_data exynos5250_drv_data = {
.caps = exynos5250_dwmmc_caps,
.init = dw_mci_exynos_priv_init,
.setup_clock = dw_mci_exynos_setup_clock,
@@ -220,14 +220,14 @@ static struct dw_mci_drv_data exynos5250_drv_data = {
static const struct of_device_id dw_mci_exynos_match[] = {
{ .compatible = "samsung,exynos5250-dw-mshc",
- .data = (void *)&exynos5250_drv_data, },
+ .data = &exynos5250_drv_data, },
{},
};
-MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match);
+MODULE_DEVICE_TABLE(of, dw_mci_exynos_match);
int dw_mci_exynos_probe(struct platform_device *pdev)
{
- struct dw_mci_drv_data *drv_data;
+ const struct dw_mci_drv_data *drv_data;
const struct of_device_id *match;
match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node);
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index c960ca7ffbe..917936bee5d 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -24,7 +24,7 @@
#include "dw_mmc.h"
int dw_mci_pltfm_register(struct platform_device *pdev,
- struct dw_mci_drv_data *drv_data)
+ const struct dw_mci_drv_data *drv_data)
{
struct dw_mci *host;
struct resource *regs;
@@ -50,8 +50,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
if (!host->regs)
return -ENOMEM;
- if (host->drv_data->init) {
- ret = host->drv_data->init(host);
+ if (drv_data && drv_data->init) {
+ ret = drv_data->init(host);
if (ret)
return ret;
}
diff --git a/drivers/mmc/host/dw_mmc-pltfm.h b/drivers/mmc/host/dw_mmc-pltfm.h
index 301f24541fc..2ac37b81de4 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.h
+++ b/drivers/mmc/host/dw_mmc-pltfm.h
@@ -13,7 +13,7 @@
#define _DW_MMC_PLTFM_H_
extern int dw_mci_pltfm_register(struct platform_device *pdev,
- struct dw_mci_drv_data *drv_data);
+ const struct dw_mci_drv_data *drv_data);
extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev);
extern const struct dev_pm_ops dw_mci_pltfm_pmops;
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index c2828f35c3b..c0667c8af2b 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -232,6 +232,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
{
struct mmc_data *data;
struct dw_mci_slot *slot = mmc_priv(mmc);
+ struct dw_mci_drv_data *drv_data = slot->host->drv_data;
u32 cmdr;
cmd->error = -EINPROGRESS;
@@ -261,8 +262,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
cmdr |= SDMMC_CMD_DAT_WR;
}
- if (slot->host->drv_data->prepare_command)
- slot->host->drv_data->prepare_command(slot->host, &cmdr);
+ if (drv_data && drv_data->prepare_command)
+ drv_data->prepare_command(slot->host, &cmdr);
return cmdr;
}
@@ -434,7 +435,7 @@ static int dw_mci_idmac_init(struct dw_mci *host)
return 0;
}
-static struct dw_mci_dma_ops dw_mci_idmac_ops = {
+static const struct dw_mci_dma_ops dw_mci_idmac_ops = {
.init = dw_mci_idmac_init,
.start = dw_mci_idmac_start_dma,
.stop = dw_mci_idmac_stop_dma,
@@ -772,6 +773,7 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct dw_mci_slot *slot = mmc_priv(mmc);
+ struct dw_mci_drv_data *drv_data = slot->host->drv_data;
u32 regs;
/* set default 1 bit mode */
@@ -807,8 +809,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
slot->clock = ios->clock;
}
- if (slot->host->drv_data->set_ios)
- slot->host->drv_data->set_ios(slot->host, ios);
+ if (drv_data && drv_data->set_ios)
+ drv_data->set_ios(slot->host, ios);
switch (ios->power_mode) {
case MMC_POWER_UP:
@@ -1815,6 +1817,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
{
struct mmc_host *mmc;
struct dw_mci_slot *slot;
+ struct dw_mci_drv_data *drv_data = host->drv_data;
int ctrl_id, ret;
u8 bus_width;
@@ -1854,8 +1857,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
} else {
ctrl_id = to_platform_device(host->dev)->id;
}
- if (host->drv_data && host->drv_data->caps)
- mmc->caps |= host->drv_data->caps[ctrl_id];
+ if (drv_data && drv_data->caps)
+ mmc->caps |= drv_data->caps[ctrl_id];
if (host->pdata->caps2)
mmc->caps2 = host->pdata->caps2;
@@ -1867,10 +1870,10 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
else
bus_width = 1;
- if (host->drv_data->setup_bus) {
+ if (drv_data && drv_data->setup_bus) {
struct device_node *slot_np;
slot_np = dw_mci_of_find_slot_node(host->dev, slot->id);
- ret = host->drv_data->setup_bus(host, slot_np, bus_width);
+ ret = drv_data->setup_bus(host, slot_np, bus_width);
if (ret)
goto err_setup_bus;
}
@@ -1968,7 +1971,7 @@ static void dw_mci_init_dma(struct dw_mci *host)
/* Determine which DMA interface to use */
#ifdef CONFIG_MMC_DW_IDMAC
host->dma_ops = &dw_mci_idmac_ops;
- dev_info(&host->dev, "Using internal DMA controller.\n");
+ dev_info(host->dev, "Using internal DMA controller.\n");
#endif
if (!host->dma_ops)
@@ -2035,6 +2038,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
struct dw_mci_board *pdata;
struct device *dev = host->dev;
struct device_node *np = dev->of_node;
+ struct dw_mci_drv_data *drv_data = host->drv_data;
int idx, ret;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
@@ -2062,8 +2066,8 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms);
- if (host->drv_data->parse_dt) {
- ret = host->drv_data->parse_dt(host);
+ if (drv_data && drv_data->parse_dt) {
+ ret = drv_data->parse_dt(host);
if (ret)
return ERR_PTR(ret);
}
@@ -2080,6 +2084,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
int dw_mci_probe(struct dw_mci *host)
{
+ struct dw_mci_drv_data *drv_data = host->drv_data;
int width, i, ret = 0;
u32 fifo_size;
int init_slots = 0;
@@ -2127,8 +2132,8 @@ int dw_mci_probe(struct dw_mci *host)
else
host->bus_hz = clk_get_rate(host->ciu_clk);
- if (host->drv_data->setup_clock) {
- ret = host->drv_data->setup_clock(host);
+ if (drv_data && drv_data->setup_clock) {
+ ret = drv_data->setup_clock(host);
if (ret) {
dev_err(host->dev,
"implementation specific clock setup failed\n");
@@ -2228,6 +2233,21 @@ int dw_mci_probe(struct dw_mci *host)
else
host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1;
+ /*
+ * Enable interrupts for command done, data over, data empty, card det,
+ * receive ready and error such as transmit, receive timeout, crc error
+ */
+ mci_writel(host, RINTSTS, 0xFFFFFFFF);
+ mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
+ SDMMC_INT_TXDR | SDMMC_INT_RXDR |
+ DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
+ mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */
+
+ dev_info(host->dev, "DW MMC controller at irq %d, "
+ "%d bit host data width, "
+ "%u deep fifo\n",
+ host->irq, width, fifo_size);
+
/* We need at least one slot to succeed */
for (i = 0; i < host->num_slots; i++) {
ret = dw_mci_init_slot(host, i);
@@ -2257,20 +2277,6 @@ int dw_mci_probe(struct dw_mci *host)
else
host->data_offset = DATA_240A_OFFSET;
- /*
- * Enable interrupts for command done, data over, data empty, card det,
- * receive ready and error such as transmit, receive timeout, crc error
- */
- mci_writel(host, RINTSTS, 0xFFFFFFFF);
- mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
- SDMMC_INT_TXDR | SDMMC_INT_RXDR |
- DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
- mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */
-
- dev_info(host->dev, "DW MMC controller at irq %d, "
- "%d bit host data width, "
- "%u deep fifo\n",
- host->irq, width, fifo_size);
if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO)
dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n");
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 565c2e4fac7..6290b7f1ccf 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -1134,4 +1134,4 @@ module_platform_driver(mxcmci_driver);
MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
MODULE_AUTHOR("Sascha Hauer, Pengutronix");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-mmc");
+MODULE_ALIAS("platform:mxc-mmc");
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 54bfd0cc106..fedd258cc4e 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -178,7 +178,8 @@ struct omap_hsmmc_host {
static int omap_hsmmc_card_detect(struct device *dev, int slot)
{
- struct omap_mmc_platform_data *mmc = dev->platform_data;
+ struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+ struct omap_mmc_platform_data *mmc = host->pdata;
/* NOTE: assumes card detect signal is active-low */
return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
@@ -186,7 +187,8 @@ static int omap_hsmmc_card_detect(struct device *dev, int slot)
static int omap_hsmmc_get_wp(struct device *dev, int slot)
{
- struct omap_mmc_platform_data *mmc = dev->platform_data;
+ struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+ struct omap_mmc_platform_data *mmc = host->pdata;
/* NOTE: assumes write protect signal is active-high */
return gpio_get_value_cansleep(mmc->slots[0].gpio_wp);
@@ -194,7 +196,8 @@ static int omap_hsmmc_get_wp(struct device *dev, int slot)
static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
{
- struct omap_mmc_platform_data *mmc = dev->platform_data;
+ struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+ struct omap_mmc_platform_data *mmc = host->pdata;
/* NOTE: assumes card detect signal is active-low */
return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
@@ -204,7 +207,8 @@ static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot)
{
- struct omap_mmc_platform_data *mmc = dev->platform_data;
+ struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+ struct omap_mmc_platform_data *mmc = host->pdata;
disable_irq(mmc->slots[0].card_detect_irq);
return 0;
@@ -212,7 +216,8 @@ static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot)
static int omap_hsmmc_resume_cdirq(struct device *dev, int slot)
{
- struct omap_mmc_platform_data *mmc = dev->platform_data;
+ struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+ struct omap_mmc_platform_data *mmc = host->pdata;
enable_irq(mmc->slots[0].card_detect_irq);
return 0;
@@ -2009,9 +2014,9 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev)
clk_put(host->dbclk);
}
- mmc_free_host(host->mmc);
+ omap_hsmmc_gpio_free(host->pdata);
iounmap(host->base);
- omap_hsmmc_gpio_free(pdev->dev.platform_data);
+ mmc_free_host(host->mmc);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res)
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 90140eb03e3..8fd50a21103 100644
--- a/drivers/mmc/host/sdhci-dove.c
+++ b/drivers/mmc/host/sdhci-dove.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/err.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
@@ -84,30 +85,32 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev)
struct sdhci_dove_priv *priv;
int ret;
- ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata);
- if (ret)
- goto sdhci_dove_register_fail;
-
priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv),
GFP_KERNEL);
if (!priv) {
dev_err(&pdev->dev, "unable to allocate private data");
- ret = -ENOMEM;
- goto sdhci_dove_allocate_fail;
+ return -ENOMEM;
}
+ priv->clk = clk_get(&pdev->dev, NULL);
+ if (!IS_ERR(priv->clk))
+ clk_prepare_enable(priv->clk);
+
+ ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata);
+ if (ret)
+ goto sdhci_dove_register_fail;
+
host = platform_get_drvdata(pdev);
pltfm_host = sdhci_priv(host);
pltfm_host->priv = priv;
- priv->clk = clk_get(&pdev->dev, NULL);
- if (!IS_ERR(priv->clk))
- clk_prepare_enable(priv->clk);
return 0;
-sdhci_dove_allocate_fail:
- sdhci_pltfm_unregister(pdev);
sdhci_dove_register_fail:
+ if (!IS_ERR(priv->clk)) {
+ clk_disable_unprepare(priv->clk);
+ clk_put(priv->clk);
+ }
return ret;
}
@@ -117,14 +120,13 @@ static int __devexit sdhci_dove_remove(struct platform_device *pdev)
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_dove_priv *priv = pltfm_host->priv;
- if (priv->clk) {
- if (!IS_ERR(priv->clk)) {
- clk_disable_unprepare(priv->clk);
- clk_put(priv->clk);
- }
- devm_kfree(&pdev->dev, priv->clk);
+ sdhci_pltfm_unregister(pdev);
+
+ if (!IS_ERR(priv->clk)) {
+ clk_disable_unprepare(priv->clk);
+ clk_put(priv->clk);
}
- return sdhci_pltfm_unregister(pdev);
+ return 0;
}
static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = {
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index ae5fcbfa1ee..63d219f57ca 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -169,6 +169,16 @@ static void esdhc_of_resume(struct sdhci_host *host)
}
#endif
+static void esdhc_of_platform_init(struct sdhci_host *host)
+{
+ u32 vvn;
+
+ vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
+ vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
+ if (vvn == VENDOR_V_22)
+ host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
+}
+
static struct sdhci_ops sdhci_esdhc_ops = {
.read_l = esdhc_readl,
.read_w = esdhc_readw,
@@ -180,6 +190,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
.enable_dma = esdhc_of_enable_dma,
.get_max_clock = esdhc_of_get_max_clock,
.get_min_clock = esdhc_of_get_min_clock,
+ .platform_init = esdhc_of_platform_init,
#ifdef CONFIG_PM
.platform_suspend = esdhc_of_suspend,
.platform_resume = esdhc_of_resume,
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 4bb74b042a0..04936f353ce 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -1196,7 +1196,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
return ERR_PTR(-ENODEV);
}
- if (pci_resource_len(pdev, bar) != 0x100) {
+ if (pci_resource_len(pdev, bar) < 0x100) {
dev_err(&pdev->dev, "Invalid iomem size. You may "
"experience problems.\n");
}
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 65551a9709c..27164457f86 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -150,6 +150,13 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
goto err_remap;
}
+ /*
+ * Some platforms need to probe the controller to be able to
+ * determine which caps should be used.
+ */
+ if (host->ops && host->ops->platform_init)
+ host->ops->platform_init(host);
+
platform_set_drvdata(pdev, host);
return host;
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 2903949594c..a54dd5d7a5f 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -211,8 +211,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
if (ourhost->cur_clk != best_src) {
struct clk *clk = ourhost->clk_bus[best_src];
- clk_enable(clk);
- clk_disable(ourhost->clk_bus[ourhost->cur_clk]);
+ clk_prepare_enable(clk);
+ clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
/* turn clock off to card before changing clock source */
writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
@@ -607,7 +607,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
}
/* enable the local io clock and keep it running for the moment. */
- clk_enable(sc->clk_io);
+ clk_prepare_enable(sc->clk_io);
for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
struct clk *clk;
@@ -638,7 +638,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
}
#ifndef CONFIG_PM_RUNTIME
- clk_enable(sc->clk_bus[sc->cur_clk]);
+ clk_prepare_enable(sc->clk_bus[sc->cur_clk]);
#endif
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -747,13 +747,14 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
sdhci_s3c_setup_card_detect_gpio(sc);
#ifdef CONFIG_PM_RUNTIME
- clk_disable(sc->clk_io);
+ if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
+ clk_disable_unprepare(sc->clk_io);
#endif
return 0;
err_req_regs:
#ifndef CONFIG_PM_RUNTIME
- clk_disable(sc->clk_bus[sc->cur_clk]);
+ clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
#endif
for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
if (sc->clk_bus[ptr]) {
@@ -762,7 +763,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
}
err_no_busclks:
- clk_disable(sc->clk_io);
+ clk_disable_unprepare(sc->clk_io);
clk_put(sc->clk_io);
err_io_clk:
@@ -794,7 +795,8 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
gpio_free(sc->ext_cd_gpio);
#ifdef CONFIG_PM_RUNTIME
- clk_enable(sc->clk_io);
+ if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
+ clk_prepare_enable(sc->clk_io);
#endif
sdhci_remove_host(host, 1);
@@ -802,14 +804,14 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
#ifndef CONFIG_PM_RUNTIME
- clk_disable(sc->clk_bus[sc->cur_clk]);
+ clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
#endif
for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
if (sc->clk_bus[ptr]) {
clk_put(sc->clk_bus[ptr]);
}
}
- clk_disable(sc->clk_io);
+ clk_disable_unprepare(sc->clk_io);
clk_put(sc->clk_io);
if (pdev->dev.of_node) {
@@ -849,8 +851,8 @@ static int sdhci_s3c_runtime_suspend(struct device *dev)
ret = sdhci_runtime_suspend_host(host);
- clk_disable(ourhost->clk_bus[ourhost->cur_clk]);
- clk_disable(busclk);
+ clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
+ clk_disable_unprepare(busclk);
return ret;
}
@@ -861,8 +863,8 @@ static int sdhci_s3c_runtime_resume(struct device *dev)
struct clk *busclk = ourhost->clk_io;
int ret;
- clk_enable(busclk);
- clk_enable(ourhost->clk_bus[ourhost->cur_clk]);
+ clk_prepare_enable(busclk);
+ clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]);
ret = sdhci_runtime_resume_host(host);
return ret;
}
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 7922adb4238..c7851c0aabc 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1315,16 +1315,19 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
*/
if ((host->flags & SDHCI_NEEDS_RETUNING) &&
!(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) {
- /* eMMC uses cmd21 while sd and sdio use cmd19 */
- tuning_opcode = mmc->card->type == MMC_TYPE_MMC ?
- MMC_SEND_TUNING_BLOCK_HS200 :
- MMC_SEND_TUNING_BLOCK;
- spin_unlock_irqrestore(&host->lock, flags);
- sdhci_execute_tuning(mmc, tuning_opcode);
- spin_lock_irqsave(&host->lock, flags);
-
- /* Restore original mmc_request structure */
- host->mrq = mrq;
+ if (mmc->card) {
+ /* eMMC uses cmd21 but sd and sdio use cmd19 */
+ tuning_opcode =
+ mmc->card->type == MMC_TYPE_MMC ?
+ MMC_SEND_TUNING_BLOCK_HS200 :
+ MMC_SEND_TUNING_BLOCK;
+ spin_unlock_irqrestore(&host->lock, flags);
+ sdhci_execute_tuning(mmc, tuning_opcode);
+ spin_lock_irqsave(&host->lock, flags);
+
+ /* Restore original mmc_request structure */
+ host->mrq = mrq;
+ }
}
if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23))
@@ -2837,6 +2840,9 @@ int sdhci_add_host(struct sdhci_host *host)
if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
mmc->caps |= MMC_CAP_4_BIT_DATA;
+ if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23)
+ mmc->caps &= ~MMC_CAP_CMD23;
+
if (caps[0] & SDHCI_CAN_DO_HISPD)
mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
@@ -2846,9 +2852,12 @@ int sdhci_add_host(struct sdhci_host *host)
/* If vqmmc regulator and no 1.8V signalling, then there's no UHS */
host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc");
- if (IS_ERR(host->vqmmc)) {
- pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc));
- host->vqmmc = NULL;
+ if (IS_ERR_OR_NULL(host->vqmmc)) {
+ if (PTR_ERR(host->vqmmc) < 0) {
+ pr_info("%s: no vqmmc regulator found\n",
+ mmc_hostname(mmc));
+ host->vqmmc = NULL;
+ }
}
else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000))
regulator_enable(host->vqmmc);
@@ -2904,9 +2913,12 @@ int sdhci_add_host(struct sdhci_host *host)
ocr_avail = 0;
host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
- if (IS_ERR(host->vmmc)) {
- pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
- host->vmmc = NULL;
+ if (IS_ERR_OR_NULL(host->vmmc)) {
+ if (PTR_ERR(host->vmmc) < 0) {
+ pr_info("%s: no vmmc regulator found\n",
+ mmc_hostname(mmc));
+ host->vmmc = NULL;
+ }
} else
regulator_enable(host->vmmc);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 97653ea8942..71a4a7ed46c 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -278,6 +278,7 @@ struct sdhci_ops {
void (*hw_reset)(struct sdhci_host *host);
void (*platform_suspend)(struct sdhci_host *host);
void (*platform_resume)(struct sdhci_host *host);
+ void (*platform_init)(struct sdhci_host *host);
};
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 11d2bc3b51d..d25bc97dc5c 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1466,9 +1466,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
+ clk_disable(host->hclk);
mmc_free_host(host->mmc);
pm_runtime_put_sync(&pdev->dev);
- clk_disable(host->hclk);
pm_runtime_disable(&pdev->dev);
return 0;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index b2530b00212..5f5b69f37d2 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1379,6 +1379,8 @@ static void bond_compute_features(struct bonding *bond)
struct net_device *bond_dev = bond->dev;
netdev_features_t vlan_features = BOND_VLAN_FEATURES;
unsigned short max_hard_header_len = ETH_HLEN;
+ unsigned int gso_max_size = GSO_MAX_SIZE;
+ u16 gso_max_segs = GSO_MAX_SEGS;
int i;
unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE;
@@ -1394,11 +1396,16 @@ static void bond_compute_features(struct bonding *bond)
dst_release_flag &= slave->dev->priv_flags;
if (slave->dev->hard_header_len > max_hard_header_len)
max_hard_header_len = slave->dev->hard_header_len;
+
+ gso_max_size = min(gso_max_size, slave->dev->gso_max_size);
+ gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs);
}
done:
bond_dev->vlan_features = vlan_features;
bond_dev->hard_header_len = max_hard_header_len;
+ bond_dev->gso_max_segs = gso_max_segs;
+ netif_set_gso_max_size(bond_dev, gso_max_size);
flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE;
bond_dev->priv_flags = flags | dst_release_flag;
diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c
index d04911d33b6..47618e50535 100644
--- a/drivers/net/ethernet/8390/ne.c
+++ b/drivers/net/ethernet/8390/ne.c
@@ -813,6 +813,7 @@ static int __init ne_drv_probe(struct platform_device *pdev)
dev->irq = irq[this_dev];
dev->mem_end = bad[this_dev];
}
+ SET_NETDEV_DEV(dev, &pdev->dev);
err = do_ne_probe(dev);
if (err) {
free_netdev(dev);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index c65295dded3..6e5bdd1a31d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -1702,7 +1702,7 @@ static int bnx2x_set_eee(struct net_device *dev, struct ethtool_eee *edata)
SHMEM_EEE_ADV_STATUS_SHIFT);
if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) {
DP(BNX2X_MSG_ETHTOOL,
- "Direct manipulation of EEE advertisment is not supported\n");
+ "Direct manipulation of EEE advertisement is not supported\n");
return -EINVAL;
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 6dd0dd076cc..f6cfdc6cf20 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -9941,7 +9941,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
else
rc = bnx2x_8483x_disable_eee(phy, params, vars);
if (rc) {
- DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n");
+ DP(NETIF_MSG_LINK, "Failed to set EEE advertisement\n");
return rc;
}
} else {
@@ -12987,7 +12987,7 @@ static u8 bnx2x_analyze_link_error(struct link_params *params,
DP(NETIF_MSG_LINK, "Analyze TX Fault\n");
break;
default:
- DP(NETIF_MSG_LINK, "Analyze UNKOWN\n");
+ DP(NETIF_MSG_LINK, "Analyze UNKNOWN\n");
}
DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up,
old_status, status);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index bd1fd3d87c2..01611b33a93 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -9545,10 +9545,13 @@ static int __devinit bnx2x_prev_unload_common(struct bnx2x *bp)
*/
static void __devinit bnx2x_prev_interrupted_dmae(struct bnx2x *bp)
{
- u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS);
- if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) {
- BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing");
- REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, 1 << BP_FUNC(bp));
+ if (!CHIP_IS_E1x(bp)) {
+ u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS);
+ if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) {
+ BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing");
+ REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR,
+ 1 << BP_FUNC(bp));
+ }
}
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 32eec15fe4c..730ae2cfa49 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -2519,6 +2519,7 @@ int t4_fw_bye(struct adapter *adap, unsigned int mbox)
{
struct fw_bye_cmd c;
+ memset(&c, 0, sizeof(c));
INIT_CMD(c, BYE, WRITE);
return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
}
@@ -2535,6 +2536,7 @@ int t4_early_init(struct adapter *adap, unsigned int mbox)
{
struct fw_initialize_cmd c;
+ memset(&c, 0, sizeof(c));
INIT_CMD(c, INITIALIZE, WRITE);
return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
}
@@ -2551,6 +2553,7 @@ int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset)
{
struct fw_reset_cmd c;
+ memset(&c, 0, sizeof(c));
INIT_CMD(c, RESET, WRITE);
c.val = htonl(reset);
return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
@@ -2828,7 +2831,7 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size,
HOSTPAGESIZEPF7(sge_hps));
t4_set_reg_field(adap, SGE_CONTROL,
- INGPADBOUNDARY(INGPADBOUNDARY_MASK) |
+ INGPADBOUNDARY_MASK |
EGRSTATUSPAGESIZE_MASK,
INGPADBOUNDARY(fl_align_log - 5) |
EGRSTATUSPAGESIZE(stat_len != 64));
@@ -3278,6 +3281,7 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
{
struct fw_vi_enable_cmd c;
+ memset(&c, 0, sizeof(c));
c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST |
FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid));
c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c));
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 1d03dcdd5e5..19ac096cb07 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -1353,8 +1353,11 @@ static int gfar_restore(struct device *dev)
struct gfar_private *priv = dev_get_drvdata(dev);
struct net_device *ndev = priv->ndev;
- if (!netif_running(ndev))
+ if (!netif_running(ndev)) {
+ netif_device_attach(ndev);
+
return 0;
+ }
gfar_init_bds(ndev);
init_registers(ndev);
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index f8064df10cc..60ac46f4ac0 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -1860,10 +1860,14 @@ jme_open(struct net_device *netdev)
jme_clear_pm(jme);
JME_NAPI_ENABLE(jme);
- tasklet_enable(&jme->linkch_task);
- tasklet_enable(&jme->txclean_task);
- tasklet_hi_enable(&jme->rxclean_task);
- tasklet_hi_enable(&jme->rxempty_task);
+ tasklet_init(&jme->linkch_task, jme_link_change_tasklet,
+ (unsigned long) jme);
+ tasklet_init(&jme->txclean_task, jme_tx_clean_tasklet,
+ (unsigned long) jme);
+ tasklet_init(&jme->rxclean_task, jme_rx_clean_tasklet,
+ (unsigned long) jme);
+ tasklet_init(&jme->rxempty_task, jme_rx_empty_tasklet,
+ (unsigned long) jme);
rc = jme_request_irq(jme);
if (rc)
@@ -1948,10 +1952,10 @@ jme_close(struct net_device *netdev)
JME_NAPI_DISABLE(jme);
- tasklet_disable(&jme->linkch_task);
- tasklet_disable(&jme->txclean_task);
- tasklet_disable(&jme->rxclean_task);
- tasklet_disable(&jme->rxempty_task);
+ tasklet_kill(&jme->linkch_task);
+ tasklet_kill(&jme->txclean_task);
+ tasklet_kill(&jme->rxclean_task);
+ tasklet_kill(&jme->rxempty_task);
jme_disable_rx_engine(jme);
jme_disable_tx_engine(jme);
@@ -3079,22 +3083,6 @@ jme_init_one(struct pci_dev *pdev,
tasklet_init(&jme->pcc_task,
jme_pcc_tasklet,
(unsigned long) jme);
- tasklet_init(&jme->linkch_task,
- jme_link_change_tasklet,
- (unsigned long) jme);
- tasklet_init(&jme->txclean_task,
- jme_tx_clean_tasklet,
- (unsigned long) jme);
- tasklet_init(&jme->rxclean_task,
- jme_rx_clean_tasklet,
- (unsigned long) jme);
- tasklet_init(&jme->rxempty_task,
- jme_rx_empty_tasklet,
- (unsigned long) jme);
- tasklet_disable_nosync(&jme->linkch_task);
- tasklet_disable_nosync(&jme->txclean_task);
- tasklet_disable_nosync(&jme->rxclean_task);
- tasklet_disable_nosync(&jme->rxempty_task);
jme->dpi.cur = PCC_P1;
jme->reg_ghc = 0;
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index 9b9c2ac5c4c..d19a143aa5a 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -4026,7 +4026,7 @@ static void __devexit skge_remove(struct pci_dev *pdev)
dev0 = hw->dev[0];
unregister_netdev(dev0);
- tasklet_disable(&hw->phy_task);
+ tasklet_kill(&hw->phy_task);
spin_lock_irq(&hw->hw_lock);
hw->intr_mask = 0;
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
index 318fee91c79..69e01977a1d 100644
--- a/drivers/net/ethernet/micrel/ksz884x.c
+++ b/drivers/net/ethernet/micrel/ksz884x.c
@@ -5407,8 +5407,8 @@ static int netdev_close(struct net_device *dev)
/* Delay for receive task to stop scheduling itself. */
msleep(2000 / HZ);
- tasklet_disable(&hw_priv->rx_tasklet);
- tasklet_disable(&hw_priv->tx_tasklet);
+ tasklet_kill(&hw_priv->rx_tasklet);
+ tasklet_kill(&hw_priv->tx_tasklet);
free_irq(dev->irq, hw_priv->dev);
transmit_cleanup(hw_priv, 0);
@@ -5459,8 +5459,10 @@ static int prepare_hardware(struct net_device *dev)
rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev);
if (rc)
return rc;
- tasklet_enable(&hw_priv->rx_tasklet);
- tasklet_enable(&hw_priv->tx_tasklet);
+ tasklet_init(&hw_priv->rx_tasklet, rx_proc_task,
+ (unsigned long) hw_priv);
+ tasklet_init(&hw_priv->tx_tasklet, tx_proc_task,
+ (unsigned long) hw_priv);
hw->promiscuous = 0;
hw->all_multi = 0;
@@ -7033,16 +7035,6 @@ static int __devinit pcidev_init(struct pci_dev *pdev,
spin_lock_init(&hw_priv->hwlock);
mutex_init(&hw_priv->lock);
- /* tasklet is enabled. */
- tasklet_init(&hw_priv->rx_tasklet, rx_proc_task,
- (unsigned long) hw_priv);
- tasklet_init(&hw_priv->tx_tasklet, tx_proc_task,
- (unsigned long) hw_priv);
-
- /* tasklet_enable will decrement the atomic counter. */
- tasklet_disable(&hw_priv->rx_tasklet);
- tasklet_disable(&hw_priv->tx_tasklet);
-
for (i = 0; i < TOTAL_PORT_NUM; i++)
init_waitqueue_head(&hw_priv->counter[i].counter);
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index 1c818254b7b..b01f83a044c 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -979,17 +979,6 @@ static void cp_init_hw (struct cp_private *cp)
cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
- cpw32_f(HiTxRingAddr, 0);
- cpw32_f(HiTxRingAddr + 4, 0);
-
- ring_dma = cp->ring_dma;
- cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
- cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
-
- ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
- cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
- cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
-
cp_start_hw(cp);
cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */
@@ -1003,6 +992,17 @@ static void cp_init_hw (struct cp_private *cp)
cpw8(Config5, cpr8(Config5) & PMEStatus);
+ cpw32_f(HiTxRingAddr, 0);
+ cpw32_f(HiTxRingAddr + 4, 0);
+
+ ring_dma = cp->ring_dma;
+ cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
+ cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
+
+ ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
+ cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
+ cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
+
cpw16(MultiIntr, 0);
cpw8_f(Cfg9346, Cfg9346_Lock);
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index e7ff886e804..927aa33d434 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -3827,6 +3827,8 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
void __iomem *ioaddr = tp->mmio_addr;
switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_25:
+ case RTL_GIGA_MAC_VER_26:
case RTL_GIGA_MAC_VER_29:
case RTL_GIGA_MAC_VER_30:
case RTL_GIGA_MAC_VER_32:
@@ -4519,6 +4521,9 @@ static void rtl_set_rx_mode(struct net_device *dev)
mc_filter[1] = swab32(data);
}
+ if (tp->mac_version == RTL_GIGA_MAC_VER_35)
+ mc_filter[1] = mc_filter[0] = 0xffffffff;
+
RTL_W32(MAR0 + 4, mc_filter[1]);
RTL_W32(MAR0 + 0, mc_filter[0]);
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
index fb9f6b38511..edf5edb1314 100644
--- a/drivers/net/ethernet/sis/sis900.c
+++ b/drivers/net/ethernet/sis/sis900.c
@@ -2479,7 +2479,7 @@ static int sis900_resume(struct pci_dev *pci_dev)
netif_start_queue(net_dev);
/* Workaround for EDB */
- sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
+ sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
/* Enable all known interrupts by setting the interrupt mask. */
sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 62d1baf111e..c53c0f4e2ce 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -2110,7 +2110,7 @@ static void __devinit smsc911x_read_mac_address(struct net_device *dev)
static int __devinit smsc911x_init(struct net_device *dev)
{
struct smsc911x_data *pdata = netdev_priv(dev);
- unsigned int byte_test;
+ unsigned int byte_test, mask;
unsigned int to = 100;
SMSC_TRACE(pdata, probe, "Driver Parameters:");
@@ -2130,9 +2130,22 @@ static int __devinit smsc911x_init(struct net_device *dev)
/*
* poll the READY bit in PMT_CTRL. Any other access to the device is
* forbidden while this bit isn't set. Try for 100ms
+ *
+ * Note that this test is done before the WORD_SWAP register is
+ * programmed. So in some configurations the READY bit is at 16 before
+ * WORD_SWAP is written to. This issue is worked around by waiting
+ * until either bit 0 or bit 16 gets set in PMT_CTRL.
+ *
+ * SMSC has confirmed that checking bit 16 (marked as reserved in
+ * the datasheet) is fine since these bits "will either never be set
+ * or can only go high after READY does (so also indicate the device
+ * is ready)".
*/
- while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to)
+
+ mask = PMT_CTRL_READY_ | swahw32(PMT_CTRL_READY_);
+ while (!(smsc911x_reg_read(pdata, PMT_CTRL) & mask) && --to)
udelay(1000);
+
if (to == 0) {
pr_err("Device not READY in 100ms aborting\n");
return -ENODEV;
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c
index 4e981001385..66e025ad5df 100644
--- a/drivers/net/ethernet/tile/tilegx.c
+++ b/drivers/net/ethernet/tile/tilegx.c
@@ -917,7 +917,7 @@ static int tile_net_setup_interrupts(struct net_device *dev)
ingress_irq = rc;
tile_irq_activate(ingress_irq, TILE_IRQ_PERCPU);
rc = request_irq(ingress_irq, tile_net_handle_ingress_irq,
- 0, NULL, NULL);
+ 0, "tile_net", NULL);
if (rc != 0) {
netdev_err(dev, "request_irq failed: %d\n", rc);
destroy_irq(ingress_irq);
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 0793299bd39..a788501e978 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -894,6 +894,8 @@ out:
return IRQ_HANDLED;
}
+static void axienet_dma_err_handler(unsigned long data);
+
/**
* axienet_open - Driver open routine.
* @ndev: Pointer to net_device structure
@@ -942,6 +944,10 @@ static int axienet_open(struct net_device *ndev)
phy_start(lp->phy_dev);
}
+ /* Enable tasklets for Axi DMA error handling */
+ tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler,
+ (unsigned long) lp);
+
/* Enable interrupts for Axi DMA Tx */
ret = request_irq(lp->tx_irq, axienet_tx_irq, 0, ndev->name, ndev);
if (ret)
@@ -950,8 +956,7 @@ static int axienet_open(struct net_device *ndev)
ret = request_irq(lp->rx_irq, axienet_rx_irq, 0, ndev->name, ndev);
if (ret)
goto err_rx_irq;
- /* Enable tasklets for Axi DMA error handling */
- tasklet_enable(&lp->dma_err_tasklet);
+
return 0;
err_rx_irq:
@@ -960,6 +965,7 @@ err_tx_irq:
if (lp->phy_dev)
phy_disconnect(lp->phy_dev);
lp->phy_dev = NULL;
+ tasklet_kill(&lp->dma_err_tasklet);
dev_err(lp->dev, "request_irq() failed\n");
return ret;
}
@@ -990,7 +996,7 @@ static int axienet_stop(struct net_device *ndev)
axienet_setoptions(ndev, lp->options &
~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
- tasklet_disable(&lp->dma_err_tasklet);
+ tasklet_kill(&lp->dma_err_tasklet);
free_irq(lp->tx_irq, ndev);
free_irq(lp->rx_irq, ndev);
@@ -1613,10 +1619,6 @@ static int __devinit axienet_of_probe(struct platform_device *op)
goto err_iounmap_2;
}
- tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler,
- (unsigned long) lp);
- tasklet_disable(&lp->dma_err_tasklet);
-
return 0;
err_iounmap_2:
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index 98934bdf6ac..477d6729b17 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -1102,10 +1102,12 @@ static int init_queues(struct port *port)
{
int i;
- if (!ports_open)
- if (!(dma_pool = dma_pool_create(DRV_NAME, NULL,
- POOL_ALLOC_SIZE, 32, 0)))
+ if (!ports_open) {
+ dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev,
+ POOL_ALLOC_SIZE, 32, 0);
+ if (!dma_pool)
return -ENOMEM;
+ }
if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL,
&port->desc_tab_phys)))
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index 5039f08f5a5..43e9ab4f4d7 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -222,7 +222,7 @@ static void sirdev_config_fsm(struct work_struct *work)
break;
case SIRDEV_STATE_DONGLE_SPEED:
- if (dev->dongle_drv->reset) {
+ if (dev->dongle_drv->set_speed) {
ret = dev->dongle_drv->set_speed(dev, fsm->param);
if (ret < 0) {
fsm->result = ret;
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
index 6428fcbbdd4..daec9b05d16 100644
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -234,7 +234,6 @@ void free_mdio_bitbang(struct mii_bus *bus)
struct mdiobb_ctrl *ctrl = bus->priv;
module_put(ctrl->ops->owner);
- mdiobus_unregister(bus);
mdiobus_free(bus);
}
EXPORT_SYMBOL(free_mdio_bitbang);
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index 899274f2f9b..2ed1140df3e 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -185,17 +185,20 @@ static int __devinit mdio_gpio_probe(struct platform_device *pdev)
{
struct mdio_gpio_platform_data *pdata;
struct mii_bus *new_bus;
- int ret;
+ int ret, bus_id;
- if (pdev->dev.of_node)
+ if (pdev->dev.of_node) {
pdata = mdio_gpio_of_get_data(pdev);
- else
+ bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio");
+ } else {
pdata = pdev->dev.platform_data;
+ bus_id = pdev->id;
+ }
if (!pdata)
return -ENODEV;
- new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id);
+ new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, bus_id);
if (!new_bus)
return -ENODEV;
diff --git a/drivers/net/team/team_mode_broadcast.c b/drivers/net/team/team_mode_broadcast.c
index 9db0171e936..c5db428e73f 100644
--- a/drivers/net/team/team_mode_broadcast.c
+++ b/drivers/net/team/team_mode_broadcast.c
@@ -29,8 +29,8 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb)
if (last) {
skb2 = skb_clone(skb, GFP_ATOMIC);
if (skb2) {
- ret = team_dev_queue_xmit(team, last,
- skb2);
+ ret = !team_dev_queue_xmit(team, last,
+ skb2);
if (!sum_ret)
sum_ret = ret;
}
@@ -39,7 +39,7 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb)
}
}
if (last) {
- ret = team_dev_queue_xmit(team, last, skb);
+ ret = !team_dev_queue_xmit(team, last, skb);
if (!sum_ret)
sum_ret = ret;
}
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c
index c81e278629f..08d55b6bf27 100644
--- a/drivers/net/usb/cdc_eem.c
+++ b/drivers/net/usb/cdc_eem.c
@@ -31,6 +31,7 @@
#include <linux/usb/cdc.h>
#include <linux/usb/usbnet.h>
#include <linux/gfp.h>
+#include <linux/if_vlan.h>
/*
@@ -92,7 +93,7 @@ static int eem_bind(struct usbnet *dev, struct usb_interface *intf)
/* no jumbogram (16K) support for now */
- dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN;
+ dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN + VLAN_HLEN;
dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
return 0;
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 4cd582a4f62..74fab1a4015 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -540,10 +540,12 @@ advance:
(ctx->ether_desc == NULL) || (ctx->control != intf))
goto error;
- /* claim interfaces, if any */
- temp = usb_driver_claim_interface(driver, ctx->data, dev);
- if (temp)
- goto error;
+ /* claim data interface, if different from control */
+ if (ctx->data != ctx->control) {
+ temp = usb_driver_claim_interface(driver, ctx->data, dev);
+ if (temp)
+ goto error;
+ }
iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
@@ -623,6 +625,10 @@ static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
tasklet_kill(&ctx->bh);
+ /* handle devices with combined control and data interface */
+ if (ctx->control == ctx->data)
+ ctx->data = NULL;
+
/* disconnect master --> disconnect slave */
if (intf == ctx->control && ctx->data) {
usb_set_intfdata(ctx->data, NULL);
@@ -1245,6 +1251,14 @@ static const struct usb_device_id cdc_devs[] = {
.driver_info = (unsigned long) &wwan_info,
},
+ /* Huawei NCM devices disguised as vendor specific */
+ { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16),
+ .driver_info = (unsigned long)&wwan_info,
+ },
+ { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46),
+ .driver_info = (unsigned long)&wwan_info,
+ },
+
/* Generic CDC-NCM devices */
{ USB_INTERFACE_INFO(USB_CLASS_COMM,
USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 7479a5761d0..362cb8cfeb9 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -184,7 +184,7 @@ static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
/* set the address, index & direction (read from PHY) */
phy_id &= dev->mii.phy_id_mask;
idx &= dev->mii.reg_num_mask;
- addr = (phy_id << 11) | (idx << 6) | MII_READ_;
+ addr = (phy_id << 11) | (idx << 6) | MII_READ_ | MII_BUSY_;
ret = smsc95xx_write_reg(dev, MII_ADDR, addr);
check_warn_goto_done(ret, "Error writing MII_ADDR");
@@ -221,7 +221,7 @@ static void smsc95xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
/* set the address, index & direction (write to PHY) */
phy_id &= dev->mii.phy_id_mask;
idx &= dev->mii.reg_num_mask;
- addr = (phy_id << 11) | (idx << 6) | MII_WRITE_;
+ addr = (phy_id << 11) | (idx << 6) | MII_WRITE_ | MII_BUSY_;
ret = smsc95xx_write_reg(dev, MII_ADDR, addr);
check_warn_goto_done(ret, "Error writing MII_ADDR");
@@ -1344,6 +1344,7 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
} else {
u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
skb_push(skb, 4);
+ cpu_to_le32s(&csum_preamble);
memcpy(skb->data, &csum_preamble, 4);
}
}
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index cb04f900cc4..edb81ed0695 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -359,10 +359,12 @@ static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb,
void usbnet_defer_kevent (struct usbnet *dev, int work)
{
set_bit (work, &dev->flags);
- if (!schedule_work (&dev->kevent))
- netdev_err(dev->net, "kevent %d may have been dropped\n", work);
- else
+ if (!schedule_work (&dev->kevent)) {
+ if (net_ratelimit())
+ netdev_err(dev->net, "kevent %d may have been dropped\n", work);
+ } else {
netdev_dbg(dev->net, "kevent %d scheduled\n", work);
+ }
}
EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 7b4adde93c0..8b5c6191707 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1,5 +1,5 @@
/*
- * VXLAN: Virtual eXtensiable Local Area Network
+ * VXLAN: Virtual eXtensible Local Area Network
*
* Copyright (c) 2012 Vyatta Inc.
*
@@ -50,8 +50,8 @@
#define VXLAN_N_VID (1u << 24)
#define VXLAN_VID_MASK (VXLAN_N_VID - 1)
-/* VLAN + IP header + UDP + VXLAN */
-#define VXLAN_HEADROOM (4 + 20 + 8 + 8)
+/* IP header + UDP + VXLAN + Ethernet header */
+#define VXLAN_HEADROOM (20 + 8 + 8 + 14)
#define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */
@@ -1102,6 +1102,10 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
if (!tb[IFLA_MTU])
dev->mtu = lowerdev->mtu - VXLAN_HEADROOM;
+
+ /* update header length based on lower device */
+ dev->hard_header_len = lowerdev->hard_header_len +
+ VXLAN_HEADROOM;
}
if (data[IFLA_VXLAN_TOS])
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index 3f575afd8cf..e9a3da588e9 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -969,10 +969,12 @@ static int init_hdlc_queues(struct port *port)
{
int i;
- if (!ports_open)
- if (!(dma_pool = dma_pool_create(DRV_NAME, NULL,
- POOL_ALLOC_SIZE, 32, 0)))
+ if (!ports_open) {
+ dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev,
+ POOL_ALLOC_SIZE, 32, 0);
+ if (!dma_pool)
return -ENOMEM;
+ }
if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL,
&port->desc_tab_phys)))
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8e1559aba49..1829b445d0b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1456,7 +1456,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
switch (type) {
case ATH9K_RESET_POWER_ON:
ret = ath9k_hw_set_reset_power_on(ah);
- if (!ret)
+ if (ret)
ah->reset_power_on = true;
break;
case ATH9K_RESET_WARM:
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c
index 192251adf98..282eedec675 100644
--- a/drivers/net/wireless/b43legacy/pio.c
+++ b/drivers/net/wireless/b43legacy/pio.c
@@ -382,7 +382,7 @@ static void cancel_transfers(struct b43legacy_pioqueue *queue)
{
struct b43legacy_pio_txpacket *packet, *tmp_packet;
- tasklet_disable(&queue->txtask);
+ tasklet_kill(&queue->txtask);
list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list)
free_txpacket(packet, 0);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index a6f1e816600..481345c23de 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -4401,7 +4401,7 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
{
-#ifndef CONFIG_BRCMFISCAN
+#ifndef CONFIG_BRCMISCAN
/* scheduled scan settings */
wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index ff8162d4c45..2d9eee93c74 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -521,7 +521,7 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw,
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
if (iwlagn_tx_skb(priv, control->sta, skb))
- dev_kfree_skb_any(skb);
+ ieee80211_free_txskb(hw, skb);
}
static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
@@ -1354,6 +1354,20 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
vif_priv->ctx = ctx;
ctx->vif = vif;
+ /*
+ * In SNIFFER device type, the firmware reports the FCS to
+ * the host, rather than snipping it off. Unfortunately,
+ * mac80211 doesn't (yet) provide a per-packet flag for
+ * this, so that we have to set the hardware flag based
+ * on the interfaces added. As the monitor interface can
+ * only be present by itself, and will be removed before
+ * other interfaces are added, this is safe.
+ */
+ if (vif->type == NL80211_IFTYPE_MONITOR)
+ priv->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS;
+ else
+ priv->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
+
err = iwl_setup_interface(priv, ctx);
if (!err || reset)
goto out;
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 7ff3f143067..408132cf83c 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -2114,7 +2114,7 @@ static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
info = IEEE80211_SKB_CB(skb);
iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]);
- dev_kfree_skb_any(skb);
+ ieee80211_free_txskb(priv->hw, skb);
}
static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 17c8e5d8268..bb69f8f90b3 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -321,6 +321,14 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority)
dma_map_page(trans->dev, page, 0,
PAGE_SIZE << trans_pcie->rx_page_order,
DMA_FROM_DEVICE);
+ if (dma_mapping_error(trans->dev, rxb->page_dma)) {
+ rxb->page = NULL;
+ spin_lock_irqsave(&rxq->lock, flags);
+ list_add(&rxb->list, &rxq->rx_used);
+ spin_unlock_irqrestore(&rxq->lock, flags);
+ __free_pages(page, trans_pcie->rx_page_order);
+ return;
+ }
/* dma address must be no more than 36 bits */
BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
/* and also 256 byte aligned! */
@@ -488,8 +496,19 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
dma_map_page(trans->dev, rxb->page, 0,
PAGE_SIZE << trans_pcie->rx_page_order,
DMA_FROM_DEVICE);
- list_add_tail(&rxb->list, &rxq->rx_free);
- rxq->free_count++;
+ if (dma_mapping_error(trans->dev, rxb->page_dma)) {
+ /*
+ * free the page(s) as well to not break
+ * the invariant that the items on the used
+ * list have no page(s)
+ */
+ __free_pages(rxb->page, trans_pcie->rx_page_order);
+ rxb->page = NULL;
+ list_add_tail(&rxb->list, &rxq->rx_used);
+ } else {
+ list_add_tail(&rxb->list, &rxq->rx_free);
+ rxq->free_count++;
+ }
} else
list_add_tail(&rxb->list, &rxq->rx_used);
spin_unlock_irqrestore(&rxq->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 105e3af3c62..79a4ddc002d 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -480,20 +480,12 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- u16 rd_ptr, wr_ptr;
- int n_bd = trans_pcie->txq[txq_id].q.n_bd;
if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) {
WARN_ONCE(1, "queue %d not used", txq_id);
return;
}
- rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1);
- wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id));
-
- WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]",
- txq_id, rd_ptr, wr_ptr);
-
iwl_txq_set_inactive(trans, txq_id);
IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
}
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 8d465107f52..ae9010ed58d 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -890,9 +890,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
return;
}
cmd_node = adapter->curr_cmd;
- if (cmd_node->wait_q_enabled)
- adapter->cmd_wait_q.status = -ETIMEDOUT;
-
if (cmd_node) {
adapter->dbg.timeout_cmd_id =
adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index];
@@ -938,6 +935,14 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n",
adapter->ps_mode, adapter->ps_state);
+
+ if (cmd_node->wait_q_enabled) {
+ adapter->cmd_wait_q.status = -ETIMEDOUT;
+ wake_up_interruptible(&adapter->cmd_wait_q.wait);
+ mwifiex_cancel_pending_ioctl(adapter);
+ /* reset cmd_sent flag to unblock new commands */
+ adapter->cmd_sent = false;
+ }
}
if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
mwifiex_init_fw_complete(adapter);
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index fc8a9bfa124..82cf0fa2d9f 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -161,7 +161,6 @@ static int mwifiex_sdio_suspend(struct device *dev)
struct sdio_mmc_card *card;
struct mwifiex_adapter *adapter;
mmc_pm_flag_t pm_flag = 0;
- int hs_actived = 0;
int i;
int ret = 0;
@@ -188,12 +187,14 @@ static int mwifiex_sdio_suspend(struct device *dev)
adapter = card->adapter;
/* Enable the Host Sleep */
- hs_actived = mwifiex_enable_hs(adapter);
- if (hs_actived) {
- pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n");
- ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+ if (!mwifiex_enable_hs(adapter)) {
+ dev_err(adapter->dev, "cmd: failed to suspend\n");
+ return -EFAULT;
}
+ dev_dbg(adapter->dev, "cmd: suspend with MMC_PM_KEEP_POWER\n");
+ ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+
/* Indicate device suspended */
adapter->is_suspended = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 9970c2b1b19..b7e6607e6b6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -297,6 +297,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
/*=== Customer ID ===*/
/****** 8188CU ********/
{RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/
+ {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/
{RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/
{RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/
{RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index caa011008cd..fc24eb9b394 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -452,29 +452,85 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev,
/* Grant backend access to each skb fragment page. */
for (i = 0; i < frags; i++) {
skb_frag_t *frag = skb_shinfo(skb)->frags + i;
+ struct page *page = skb_frag_page(frag);
- tx->flags |= XEN_NETTXF_more_data;
+ len = skb_frag_size(frag);
+ offset = frag->page_offset;
- id = get_id_from_freelist(&np->tx_skb_freelist, np->tx_skbs);
- np->tx_skbs[id].skb = skb_get(skb);
- tx = RING_GET_REQUEST(&np->tx, prod++);
- tx->id = id;
- ref = gnttab_claim_grant_reference(&np->gref_tx_head);
- BUG_ON((signed short)ref < 0);
+ /* Data must not cross a page boundary. */
+ BUG_ON(len + offset > PAGE_SIZE<<compound_order(page));
- mfn = pfn_to_mfn(page_to_pfn(skb_frag_page(frag)));
- gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
- mfn, GNTMAP_readonly);
+ /* Skip unused frames from start of page */
+ page += offset >> PAGE_SHIFT;
+ offset &= ~PAGE_MASK;
- tx->gref = np->grant_tx_ref[id] = ref;
- tx->offset = frag->page_offset;
- tx->size = skb_frag_size(frag);
- tx->flags = 0;
+ while (len > 0) {
+ unsigned long bytes;
+
+ BUG_ON(offset >= PAGE_SIZE);
+
+ bytes = PAGE_SIZE - offset;
+ if (bytes > len)
+ bytes = len;
+
+ tx->flags |= XEN_NETTXF_more_data;
+
+ id = get_id_from_freelist(&np->tx_skb_freelist,
+ np->tx_skbs);
+ np->tx_skbs[id].skb = skb_get(skb);
+ tx = RING_GET_REQUEST(&np->tx, prod++);
+ tx->id = id;
+ ref = gnttab_claim_grant_reference(&np->gref_tx_head);
+ BUG_ON((signed short)ref < 0);
+
+ mfn = pfn_to_mfn(page_to_pfn(page));
+ gnttab_grant_foreign_access_ref(ref,
+ np->xbdev->otherend_id,
+ mfn, GNTMAP_readonly);
+
+ tx->gref = np->grant_tx_ref[id] = ref;
+ tx->offset = offset;
+ tx->size = bytes;
+ tx->flags = 0;
+
+ offset += bytes;
+ len -= bytes;
+
+ /* Next frame */
+ if (offset == PAGE_SIZE && len) {
+ BUG_ON(!PageCompound(page));
+ page++;
+ offset = 0;
+ }
+ }
}
np->tx.req_prod_pvt = prod;
}
+/*
+ * Count how many ring slots are required to send the frags of this
+ * skb. Each frag might be a compound page.
+ */
+static int xennet_count_skb_frag_slots(struct sk_buff *skb)
+{
+ int i, frags = skb_shinfo(skb)->nr_frags;
+ int pages = 0;
+
+ for (i = 0; i < frags; i++) {
+ skb_frag_t *frag = skb_shinfo(skb)->frags + i;
+ unsigned long size = skb_frag_size(frag);
+ unsigned long offset = frag->page_offset;
+
+ /* Skip unused frames from start of page */
+ offset &= ~PAGE_MASK;
+
+ pages += PFN_UP(offset + size);
+ }
+
+ return pages;
+}
+
static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
unsigned short id;
@@ -487,23 +543,23 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
grant_ref_t ref;
unsigned long mfn;
int notify;
- int frags = skb_shinfo(skb)->nr_frags;
+ int slots;
unsigned int offset = offset_in_page(data);
unsigned int len = skb_headlen(skb);
unsigned long flags;
- frags += DIV_ROUND_UP(offset + len, PAGE_SIZE);
- if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
- printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
- frags);
- dump_stack();
+ slots = DIV_ROUND_UP(offset + len, PAGE_SIZE) +
+ xennet_count_skb_frag_slots(skb);
+ if (unlikely(slots > MAX_SKB_FRAGS + 1)) {
+ net_alert_ratelimited(
+ "xennet: skb rides the rocket: %d slots\n", slots);
goto drop;
}
spin_lock_irqsave(&np->tx_lock, flags);
if (unlikely(!netif_carrier_ok(dev) ||
- (frags > 1 && !xennet_can_sg(dev)) ||
+ (slots > 1 && !xennet_can_sg(dev)) ||
netif_needs_gso(skb, netif_skb_features(skb)))) {
spin_unlock_irqrestore(&np->tx_lock, flags);
goto drop;
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c
index 97c440a8cd6..30ae18a03a9 100644
--- a/drivers/nfc/pn533.c
+++ b/drivers/nfc/pn533.c
@@ -698,13 +698,14 @@ static void pn533_wq_cmd(struct work_struct *work)
cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue);
+ list_del(&cmd->queue);
+
mutex_unlock(&dev->cmd_lock);
__pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame,
cmd->in_frame_len, cmd->cmd_complete,
cmd->arg, cmd->flags);
- list_del(&cmd->queue);
kfree(cmd);
}
@@ -1678,11 +1679,14 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev,
static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
u8 *params, int params_len)
{
- struct pn533_cmd_jump_dep *cmd;
struct pn533_cmd_jump_dep_response *resp;
struct nfc_target nfc_target;
u8 target_gt_len;
int rc;
+ struct pn533_cmd_jump_dep *cmd = (struct pn533_cmd_jump_dep *)arg;
+ u8 active = cmd->active;
+
+ kfree(arg);
if (params_len == -ENOENT) {
nfc_dev_dbg(&dev->interface->dev, "");
@@ -1704,7 +1708,6 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
}
resp = (struct pn533_cmd_jump_dep_response *) params;
- cmd = (struct pn533_cmd_jump_dep *) arg;
rc = resp->status & PN533_CMD_RET_MASK;
if (rc != PN533_CMD_RET_SUCCESS) {
nfc_dev_err(&dev->interface->dev,
@@ -1734,7 +1737,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
if (rc == 0)
rc = nfc_dep_link_is_up(dev->nfc_dev,
dev->nfc_dev->targets[0].idx,
- !cmd->active, NFC_RF_INITIATOR);
+ !active, NFC_RF_INITIATOR);
return 0;
}
@@ -1819,12 +1822,8 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target,
rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame,
dev->in_maxlen, pn533_in_dep_link_up_complete,
cmd, GFP_KERNEL);
- if (rc)
- goto out;
-
-
-out:
- kfree(cmd);
+ if (rc < 0)
+ kfree(cmd);
return rc;
}
@@ -2078,8 +2077,12 @@ error:
static int pn533_tm_send_complete(struct pn533 *dev, void *arg,
u8 *params, int params_len)
{
+ struct sk_buff *skb_out = arg;
+
nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
+ dev_kfree_skb(skb_out);
+
if (params_len < 0) {
nfc_dev_err(&dev->interface->dev,
"Error %d when sending data",
@@ -2117,7 +2120,7 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame,
dev->in_maxlen, pn533_tm_send_complete,
- NULL, GFP_KERNEL);
+ skb, GFP_KERNEL);
if (rc) {
nfc_dev_err(&dev->interface->dev,
"Error %d when trying to send data", rc);
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 6241fd05bd4..a543746fb35 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -320,10 +320,7 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
} else
next = dev->bus_list.next;
- /* Run device routines with the device locked */
- device_lock(&dev->dev);
retval = cb(dev, userdata);
- device_unlock(&dev->dev);
if (retval)
break;
}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 94c6e2aa03d..6c94fc9489e 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -398,6 +398,8 @@ static void pci_device_shutdown(struct device *dev)
struct pci_dev *pci_dev = to_pci_dev(dev);
struct pci_driver *drv = pci_dev->driver;
+ pm_runtime_resume(dev);
+
if (drv && drv->shutdown)
drv->shutdown(pci_dev);
pci_msi_shutdown(pci_dev);
@@ -408,16 +410,6 @@ static void pci_device_shutdown(struct device *dev)
* continue to do DMA
*/
pci_disable_device(pci_dev);
-
- /*
- * Devices may be enabled to wake up by runtime PM, but they need not
- * be supposed to wake up the system from its "power off" state (e.g.
- * ACPI S5). Therefore disable wakeup for all devices that aren't
- * supposed to wake up the system at this point. The state argument
- * will be ignored by pci_enable_wake().
- */
- if (!device_may_wakeup(dev))
- pci_enable_wake(pci_dev, PCI_UNKNOWN, false);
}
#ifdef CONFIG_PM
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 02d107b1528..f39378d9da1 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -458,40 +458,6 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf)
}
struct device_attribute vga_attr = __ATTR_RO(boot_vga);
-static void
-pci_config_pm_runtime_get(struct pci_dev *pdev)
-{
- struct device *dev = &pdev->dev;
- struct device *parent = dev->parent;
-
- if (parent)
- pm_runtime_get_sync(parent);
- pm_runtime_get_noresume(dev);
- /*
- * pdev->current_state is set to PCI_D3cold during suspending,
- * so wait until suspending completes
- */
- pm_runtime_barrier(dev);
- /*
- * Only need to resume devices in D3cold, because config
- * registers are still accessible for devices suspended but
- * not in D3cold.
- */
- if (pdev->current_state == PCI_D3cold)
- pm_runtime_resume(dev);
-}
-
-static void
-pci_config_pm_runtime_put(struct pci_dev *pdev)
-{
- struct device *dev = &pdev->dev;
- struct device *parent = dev->parent;
-
- pm_runtime_put(dev);
- if (parent)
- pm_runtime_put_sync(parent);
-}
-
static ssize_t
pci_read_config(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 54858838f09..aabf64798bd 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1858,6 +1858,38 @@ bool pci_dev_run_wake(struct pci_dev *dev)
}
EXPORT_SYMBOL_GPL(pci_dev_run_wake);
+void pci_config_pm_runtime_get(struct pci_dev *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device *parent = dev->parent;
+
+ if (parent)
+ pm_runtime_get_sync(parent);
+ pm_runtime_get_noresume(dev);
+ /*
+ * pdev->current_state is set to PCI_D3cold during suspending,
+ * so wait until suspending completes
+ */
+ pm_runtime_barrier(dev);
+ /*
+ * Only need to resume devices in D3cold, because config
+ * registers are still accessible for devices suspended but
+ * not in D3cold.
+ */
+ if (pdev->current_state == PCI_D3cold)
+ pm_runtime_resume(dev);
+}
+
+void pci_config_pm_runtime_put(struct pci_dev *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device *parent = dev->parent;
+
+ pm_runtime_put(dev);
+ if (parent)
+ pm_runtime_put_sync(parent);
+}
+
/**
* pci_pm_init - Initialize PM functions of given PCI device
* @dev: PCI device to handle.
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index bacbcba69cf..fd92aab9904 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -72,6 +72,8 @@ extern void pci_disable_enabled_device(struct pci_dev *dev);
extern int pci_finish_runtime_suspend(struct pci_dev *dev);
extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign);
extern void pci_wakeup_bus(struct pci_bus *bus);
+extern void pci_config_pm_runtime_get(struct pci_dev *dev);
+extern void pci_config_pm_runtime_put(struct pci_dev *dev);
extern void pci_pm_init(struct pci_dev *dev);
extern void platform_pci_wakeup_init(struct pci_dev *dev);
extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 06bad96af41..af4e31cd3a3 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -213,6 +213,7 @@ static int report_error_detected(struct pci_dev *dev, void *data)
struct aer_broadcast_data *result_data;
result_data = (struct aer_broadcast_data *) data;
+ device_lock(&dev->dev);
dev->error_state = result_data->state;
if (!dev->driver ||
@@ -231,12 +232,14 @@ static int report_error_detected(struct pci_dev *dev, void *data)
dev->driver ?
"no AER-aware driver" : "no driver");
}
- return 0;
+ goto out;
}
err_handler = dev->driver->err_handler;
vote = err_handler->error_detected(dev, result_data->state);
result_data->result = merge_result(result_data->result, vote);
+out:
+ device_unlock(&dev->dev);
return 0;
}
@@ -247,14 +250,17 @@ static int report_mmio_enabled(struct pci_dev *dev, void *data)
struct aer_broadcast_data *result_data;
result_data = (struct aer_broadcast_data *) data;
+ device_lock(&dev->dev);
if (!dev->driver ||
!dev->driver->err_handler ||
!dev->driver->err_handler->mmio_enabled)
- return 0;
+ goto out;
err_handler = dev->driver->err_handler;
vote = err_handler->mmio_enabled(dev);
result_data->result = merge_result(result_data->result, vote);
+out:
+ device_unlock(&dev->dev);
return 0;
}
@@ -265,14 +271,17 @@ static int report_slot_reset(struct pci_dev *dev, void *data)
struct aer_broadcast_data *result_data;
result_data = (struct aer_broadcast_data *) data;
+ device_lock(&dev->dev);
if (!dev->driver ||
!dev->driver->err_handler ||
!dev->driver->err_handler->slot_reset)
- return 0;
+ goto out;
err_handler = dev->driver->err_handler;
vote = err_handler->slot_reset(dev);
result_data->result = merge_result(result_data->result, vote);
+out:
+ device_unlock(&dev->dev);
return 0;
}
@@ -280,15 +289,18 @@ static int report_resume(struct pci_dev *dev, void *data)
{
const struct pci_error_handlers *err_handler;
+ device_lock(&dev->dev);
dev->error_state = pci_channel_io_normal;
if (!dev->driver ||
!dev->driver->err_handler ||
!dev->driver->err_handler->resume)
- return 0;
+ goto out;
err_handler = dev->driver->err_handler;
err_handler->resume(dev);
+out:
+ device_unlock(&dev->dev);
return 0;
}
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index d03a7a39b2d..ed129b41462 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -272,7 +272,8 @@ static int get_port_device_capability(struct pci_dev *dev)
}
/* Hot-Plug Capable */
- if (cap_mask & PCIE_PORT_SERVICE_HP) {
+ if ((cap_mask & PCIE_PORT_SERVICE_HP) &&
+ dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT) {
pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, &reg32);
if (reg32 & PCI_EXP_SLTCAP_HPC) {
services |= PCIE_PORT_SERVICE_HP;
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index eb907a8faf2..9b8505ccc56 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -76,6 +76,8 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
if (!access_ok(VERIFY_WRITE, buf, cnt))
return -EINVAL;
+ pci_config_pm_runtime_get(dev);
+
if ((pos & 1) && cnt) {
unsigned char val;
pci_user_read_config_byte(dev, pos, &val);
@@ -121,6 +123,8 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
cnt--;
}
+ pci_config_pm_runtime_put(dev);
+
*ppos = pos;
return nbytes;
}
@@ -146,6 +150,8 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
if (!access_ok(VERIFY_READ, buf, cnt))
return -EINVAL;
+ pci_config_pm_runtime_get(dev);
+
if ((pos & 1) && cnt) {
unsigned char val;
__get_user(val, buf);
@@ -191,6 +197,8 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
cnt--;
}
+ pci_config_pm_runtime_put(dev);
+
*ppos = pos;
i_size_write(ino, dp->size);
return nbytes;
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 7bf914df6e9..aeecf0f72ca 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -178,12 +178,14 @@ config PINCTRL_COH901
ports of 8 GPIO pins each.
config PINCTRL_SAMSUNG
- bool "Samsung pinctrl driver"
+ bool
+ depends on OF && GPIOLIB
select PINMUX
select PINCONF
config PINCTRL_EXYNOS4
bool "Pinctrl driver data for Exynos4 SoC"
+ depends on OF && GPIOLIB
select PINCTRL_SAMSUNG
config PINCTRL_MVEBU
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c
index 5d4f44f462f..b1fd6ee33c6 100644
--- a/drivers/pinctrl/spear/pinctrl-spear.c
+++ b/drivers/pinctrl/spear/pinctrl-spear.c
@@ -244,7 +244,7 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
else
temp = ~muxreg->val;
- val |= temp;
+ val |= muxreg->mask & temp;
pmx_writel(pmx, val, muxreg->reg);
}
}
diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c
index d6cca8c81b9..0436fc7895d 100644
--- a/drivers/pinctrl/spear/pinctrl-spear1310.c
+++ b/drivers/pinctrl/spear/pinctrl-spear1310.c
@@ -25,8 +25,8 @@ static const struct pinctrl_pin_desc spear1310_pins[] = {
};
/* registers */
-#define PERIP_CFG 0x32C
- #define MCIF_SEL_SHIFT 3
+#define PERIP_CFG 0x3B0
+ #define MCIF_SEL_SHIFT 5
#define MCIF_SEL_SD (0x1 << MCIF_SEL_SHIFT)
#define MCIF_SEL_CF (0x2 << MCIF_SEL_SHIFT)
#define MCIF_SEL_XD (0x3 << MCIF_SEL_SHIFT)
@@ -164,6 +164,10 @@ static const struct pinctrl_pin_desc spear1310_pins[] = {
#define PMX_SSP0_CS0_MASK (1 << 29)
#define PMX_SSP0_CS1_2_MASK (1 << 30)
+#define PAD_DIRECTION_SEL_0 0x65C
+#define PAD_DIRECTION_SEL_1 0x660
+#define PAD_DIRECTION_SEL_2 0x664
+
/* combined macros */
#define PMX_GMII_MASK (PMX_GMIICLK_MASK | \
PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK | \
@@ -237,6 +241,10 @@ static struct spear_muxreg i2c0_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_I2C0_MASK,
.val = PMX_I2C0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_I2C0_MASK,
+ .val = PMX_I2C0_MASK,
},
};
@@ -269,6 +277,10 @@ static struct spear_muxreg ssp0_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_SSP0_MASK,
.val = PMX_SSP0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_SSP0_MASK,
+ .val = PMX_SSP0_MASK,
},
};
@@ -294,6 +306,10 @@ static struct spear_muxreg ssp0_cs0_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_SSP0_CS0_MASK,
.val = PMX_SSP0_CS0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_SSP0_CS0_MASK,
+ .val = PMX_SSP0_CS0_MASK,
},
};
@@ -319,6 +335,10 @@ static struct spear_muxreg ssp0_cs1_2_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_SSP0_CS1_2_MASK,
.val = PMX_SSP0_CS1_2_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_SSP0_CS1_2_MASK,
+ .val = PMX_SSP0_CS1_2_MASK,
},
};
@@ -352,6 +372,10 @@ static struct spear_muxreg i2s0_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_I2S0_MASK,
.val = PMX_I2S0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_I2S0_MASK,
+ .val = PMX_I2S0_MASK,
},
};
@@ -384,6 +408,10 @@ static struct spear_muxreg i2s1_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_I2S1_MASK,
.val = PMX_I2S1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_I2S1_MASK,
+ .val = PMX_I2S1_MASK,
},
};
@@ -418,6 +446,10 @@ static struct spear_muxreg clcd_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_CLCD1_MASK,
.val = PMX_CLCD1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_CLCD1_MASK,
+ .val = PMX_CLCD1_MASK,
},
};
@@ -443,6 +475,10 @@ static struct spear_muxreg clcd_high_res_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_CLCD2_MASK,
.val = PMX_CLCD2_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_CLCD2_MASK,
+ .val = PMX_CLCD2_MASK,
},
};
@@ -461,7 +497,7 @@ static struct spear_pingroup clcd_high_res_pingroup = {
.nmodemuxs = ARRAY_SIZE(clcd_high_res_modemux),
};
-static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res" };
+static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res_grp" };
static struct spear_function clcd_function = {
.name = "clcd",
.groups = clcd_grps,
@@ -479,6 +515,14 @@ static struct spear_muxreg arm_gpio_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_EGPIO_1_GRP_MASK,
.val = PMX_EGPIO_1_GRP_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_EGPIO_0_GRP_MASK,
+ .val = PMX_EGPIO_0_GRP_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_EGPIO_1_GRP_MASK,
+ .val = PMX_EGPIO_1_GRP_MASK,
},
};
@@ -511,6 +555,10 @@ static struct spear_muxreg smi_2_chips_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_SMI_MASK,
.val = PMX_SMI_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_SMI_MASK,
+ .val = PMX_SMI_MASK,
},
};
@@ -539,6 +587,14 @@ static struct spear_muxreg smi_4_chips_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
.val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_SMI_MASK,
+ .val = PMX_SMI_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
+ .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
},
};
@@ -573,6 +629,10 @@ static struct spear_muxreg gmii_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_GMII_MASK,
.val = PMX_GMII_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_GMII_MASK,
+ .val = PMX_GMII_MASK,
},
};
@@ -615,6 +675,18 @@ static struct spear_muxreg rgmii_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_RGMII_REG2_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_RGMII_REG0_MASK,
+ .val = PMX_RGMII_REG0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_RGMII_REG1_MASK,
+ .val = PMX_RGMII_REG1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_RGMII_REG2_MASK,
+ .val = PMX_RGMII_REG2_MASK,
},
};
@@ -649,6 +721,10 @@ static struct spear_muxreg smii_0_1_2_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_SMII_0_1_2_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_SMII_0_1_2_MASK,
+ .val = PMX_SMII_0_1_2_MASK,
},
};
@@ -681,6 +757,10 @@ static struct spear_muxreg ras_mii_txclk_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_NFCE2_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_NFCE2_MASK,
+ .val = PMX_NFCE2_MASK,
},
};
@@ -721,6 +801,14 @@ static struct spear_muxreg nand_8bit_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_NAND8BIT_1_MASK,
.val = PMX_NAND8BIT_1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_NAND8BIT_0_MASK,
+ .val = PMX_NAND8BIT_0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_NAND8BIT_1_MASK,
+ .val = PMX_NAND8BIT_1_MASK,
},
};
@@ -747,6 +835,10 @@ static struct spear_muxreg nand_16bit_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_NAND16BIT_1_MASK,
.val = PMX_NAND16BIT_1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_NAND16BIT_1_MASK,
+ .val = PMX_NAND16BIT_1_MASK,
},
};
@@ -772,6 +864,10 @@ static struct spear_muxreg nand_4_chips_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_NAND_4CHIPS_MASK,
.val = PMX_NAND_4CHIPS_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_NAND_4CHIPS_MASK,
+ .val = PMX_NAND_4CHIPS_MASK,
},
};
@@ -833,6 +929,10 @@ static struct spear_muxreg keyboard_rowcol6_8_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_KBD_ROWCOL68_MASK,
.val = PMX_KBD_ROWCOL68_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_KBD_ROWCOL68_MASK,
+ .val = PMX_KBD_ROWCOL68_MASK,
},
};
@@ -866,6 +966,10 @@ static struct spear_muxreg uart0_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_UART0_MASK,
.val = PMX_UART0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_UART0_MASK,
+ .val = PMX_UART0_MASK,
},
};
@@ -891,6 +995,10 @@ static struct spear_muxreg uart0_modem_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_UART0_MODEM_MASK,
.val = PMX_UART0_MODEM_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = PMX_UART0_MODEM_MASK,
},
};
@@ -923,6 +1031,10 @@ static struct spear_muxreg gpt0_tmr0_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_GPT0_TMR0_MASK,
.val = PMX_GPT0_TMR0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_GPT0_TMR0_MASK,
+ .val = PMX_GPT0_TMR0_MASK,
},
};
@@ -948,6 +1060,10 @@ static struct spear_muxreg gpt0_tmr1_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_GPT0_TMR1_MASK,
.val = PMX_GPT0_TMR1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_GPT0_TMR1_MASK,
+ .val = PMX_GPT0_TMR1_MASK,
},
};
@@ -980,6 +1096,10 @@ static struct spear_muxreg gpt1_tmr0_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_GPT1_TMR0_MASK,
.val = PMX_GPT1_TMR0_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_GPT1_TMR0_MASK,
+ .val = PMX_GPT1_TMR0_MASK,
},
};
@@ -1005,6 +1125,10 @@ static struct spear_muxreg gpt1_tmr1_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_GPT1_TMR1_MASK,
.val = PMX_GPT1_TMR1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_GPT1_TMR1_MASK,
+ .val = PMX_GPT1_TMR1_MASK,
},
};
@@ -1049,6 +1173,20 @@ static const unsigned mcif_pins[] = { 86, 87, 88, 89, 90, 91, 92, 93, 213, 214,
.reg = PAD_FUNCTION_EN_2, \
.mask = PMX_MCIFALL_2_MASK, \
.val = PMX_MCIFALL_2_MASK, \
+ }, { \
+ .reg = PAD_DIRECTION_SEL_0, \
+ .mask = PMX_MCI_DATA8_15_MASK, \
+ .val = PMX_MCI_DATA8_15_MASK, \
+ }, { \
+ .reg = PAD_DIRECTION_SEL_1, \
+ .mask = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \
+ PMX_NFWPRT2_MASK, \
+ .val = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \
+ PMX_NFWPRT2_MASK, \
+ }, { \
+ .reg = PAD_DIRECTION_SEL_2, \
+ .mask = PMX_MCIFALL_2_MASK, \
+ .val = PMX_MCIFALL_2_MASK, \
}
/* sdhci device */
@@ -1154,6 +1292,10 @@ static struct spear_muxreg touch_xy_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_TOUCH_XY_MASK,
.val = PMX_TOUCH_XY_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_TOUCH_XY_MASK,
+ .val = PMX_TOUCH_XY_MASK,
},
};
@@ -1187,6 +1329,10 @@ static struct spear_muxreg uart1_dis_i2c_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_I2C0_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_I2C0_MASK,
+ .val = PMX_I2C0_MASK,
},
};
@@ -1213,6 +1359,12 @@ static struct spear_muxreg uart1_dis_sd_muxreg[] = {
.mask = PMX_MCIDATA1_MASK |
PMX_MCIDATA2_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_MCIDATA1_MASK |
+ PMX_MCIDATA2_MASK,
+ .val = PMX_MCIDATA1_MASK |
+ PMX_MCIDATA2_MASK,
},
};
@@ -1246,6 +1398,10 @@ static struct spear_muxreg uart2_3_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_I2S0_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_I2S0_MASK,
+ .val = PMX_I2S0_MASK,
},
};
@@ -1278,6 +1434,10 @@ static struct spear_muxreg uart4_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_I2S0_MASK | PMX_CLCD1_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK,
+ .val = PMX_I2S0_MASK | PMX_CLCD1_MASK,
},
};
@@ -1310,6 +1470,10 @@ static struct spear_muxreg uart5_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_CLCD1_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_CLCD1_MASK,
+ .val = PMX_CLCD1_MASK,
},
};
@@ -1344,6 +1508,10 @@ static struct spear_muxreg rs485_0_1_tdm_0_1_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_CLCD1_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_CLCD1_MASK,
+ .val = PMX_CLCD1_MASK,
},
};
@@ -1376,6 +1544,10 @@ static struct spear_muxreg i2c_1_2_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_CLCD1_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_CLCD1_MASK,
+ .val = PMX_CLCD1_MASK,
},
};
@@ -1409,6 +1581,10 @@ static struct spear_muxreg i2c3_dis_smi_clcd_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_CLCD1_MASK | PMX_SMI_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_CLCD1_MASK | PMX_SMI_MASK,
+ .val = PMX_CLCD1_MASK | PMX_SMI_MASK,
},
};
@@ -1435,6 +1611,10 @@ static struct spear_muxreg i2c3_dis_sd_i2s0_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK,
+ .val = PMX_I2S1_MASK | PMX_MCIDATA3_MASK,
},
};
@@ -1469,6 +1649,10 @@ static struct spear_muxreg i2c_4_5_dis_smi_muxreg[] = {
.reg = PAD_FUNCTION_EN_0,
.mask = PMX_SMI_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_SMI_MASK,
+ .val = PMX_SMI_MASK,
},
};
@@ -1499,6 +1683,14 @@ static struct spear_muxreg i2c4_dis_sd_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_MCIDATA5_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_MCIDATA4_MASK,
+ .val = PMX_MCIDATA4_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCIDATA5_MASK,
+ .val = PMX_MCIDATA5_MASK,
},
};
@@ -1526,6 +1718,12 @@ static struct spear_muxreg i2c5_dis_sd_muxreg[] = {
.mask = PMX_MCIDATA6_MASK |
PMX_MCIDATA7_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCIDATA6_MASK |
+ PMX_MCIDATA7_MASK,
+ .val = PMX_MCIDATA6_MASK |
+ PMX_MCIDATA7_MASK,
},
};
@@ -1560,6 +1758,10 @@ static struct spear_muxreg i2c_6_7_dis_kbd_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_KBD_ROWCOL25_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_KBD_ROWCOL25_MASK,
+ .val = PMX_KBD_ROWCOL25_MASK,
},
};
@@ -1587,6 +1789,12 @@ static struct spear_muxreg i2c6_dis_sd_muxreg[] = {
.mask = PMX_MCIIORDRE_MASK |
PMX_MCIIOWRWE_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCIIORDRE_MASK |
+ PMX_MCIIOWRWE_MASK,
+ .val = PMX_MCIIORDRE_MASK |
+ PMX_MCIIOWRWE_MASK,
},
};
@@ -1613,6 +1821,12 @@ static struct spear_muxreg i2c7_dis_sd_muxreg[] = {
.mask = PMX_MCIRESETCF_MASK |
PMX_MCICS0CE_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCIRESETCF_MASK |
+ PMX_MCICS0CE_MASK,
+ .val = PMX_MCIRESETCF_MASK |
+ PMX_MCICS0CE_MASK,
},
};
@@ -1651,6 +1865,14 @@ static struct spear_muxreg can0_dis_nor_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_NFRSTPWDWN3_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_NFRSTPWDWN2_MASK,
+ .val = PMX_NFRSTPWDWN2_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_NFRSTPWDWN3_MASK,
+ .val = PMX_NFRSTPWDWN3_MASK,
},
};
@@ -1677,6 +1899,10 @@ static struct spear_muxreg can0_dis_sd_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK,
+ .val = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK,
},
};
@@ -1711,6 +1937,10 @@ static struct spear_muxreg can1_dis_sd_muxreg[] = {
.reg = PAD_FUNCTION_EN_2,
.mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK,
+ .val = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK,
},
};
@@ -1737,6 +1967,10 @@ static struct spear_muxreg can1_dis_kbd_muxreg[] = {
.reg = PAD_FUNCTION_EN_1,
.mask = PMX_KBD_ROWCOL25_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_KBD_ROWCOL25_MASK,
+ .val = PMX_KBD_ROWCOL25_MASK,
},
};
@@ -1763,29 +1997,64 @@ static struct spear_function can1_function = {
.ngroups = ARRAY_SIZE(can1_grps),
};
-/* Pad multiplexing for pci device */
-static const unsigned pci_sata_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18,
+/* Pad multiplexing for (ras-ip) pci device */
+static const unsigned pci_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 };
-#define PCI_SATA_MUXREG \
- { \
- .reg = PAD_FUNCTION_EN_0, \
- .mask = PMX_MCI_DATA8_15_MASK, \
- .val = 0, \
- }, { \
- .reg = PAD_FUNCTION_EN_1, \
- .mask = PMX_PCI_REG1_MASK, \
- .val = 0, \
- }, { \
- .reg = PAD_FUNCTION_EN_2, \
- .mask = PMX_PCI_REG2_MASK, \
- .val = 0, \
- }
-/* pad multiplexing for pcie0 device */
+static struct spear_muxreg pci_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_MCI_DATA8_15_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_PCI_REG1_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_PCI_REG2_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_0,
+ .mask = PMX_MCI_DATA8_15_MASK,
+ .val = PMX_MCI_DATA8_15_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_PCI_REG1_MASK,
+ .val = PMX_PCI_REG1_MASK,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_PCI_REG2_MASK,
+ .val = PMX_PCI_REG2_MASK,
+ },
+};
+
+static struct spear_modemux pci_modemux[] = {
+ {
+ .muxregs = pci_muxreg,
+ .nmuxregs = ARRAY_SIZE(pci_muxreg),
+ },
+};
+
+static struct spear_pingroup pci_pingroup = {
+ .name = "pci_grp",
+ .pins = pci_pins,
+ .npins = ARRAY_SIZE(pci_pins),
+ .modemuxs = pci_modemux,
+ .nmodemuxs = ARRAY_SIZE(pci_modemux),
+};
+
+static const char *const pci_grps[] = { "pci_grp" };
+static struct spear_function pci_function = {
+ .name = "pci",
+ .groups = pci_grps,
+ .ngroups = ARRAY_SIZE(pci_grps),
+};
+
+/* pad multiplexing for (fix-part) pcie0 device */
static struct spear_muxreg pcie0_muxreg[] = {
- PCI_SATA_MUXREG,
{
.reg = PCIE_SATA_CFG,
.mask = PCIE_CFG_VAL(0),
@@ -1802,15 +2071,12 @@ static struct spear_modemux pcie0_modemux[] = {
static struct spear_pingroup pcie0_pingroup = {
.name = "pcie0_grp",
- .pins = pci_sata_pins,
- .npins = ARRAY_SIZE(pci_sata_pins),
.modemuxs = pcie0_modemux,
.nmodemuxs = ARRAY_SIZE(pcie0_modemux),
};
-/* pad multiplexing for pcie1 device */
+/* pad multiplexing for (fix-part) pcie1 device */
static struct spear_muxreg pcie1_muxreg[] = {
- PCI_SATA_MUXREG,
{
.reg = PCIE_SATA_CFG,
.mask = PCIE_CFG_VAL(1),
@@ -1827,15 +2093,12 @@ static struct spear_modemux pcie1_modemux[] = {
static struct spear_pingroup pcie1_pingroup = {
.name = "pcie1_grp",
- .pins = pci_sata_pins,
- .npins = ARRAY_SIZE(pci_sata_pins),
.modemuxs = pcie1_modemux,
.nmodemuxs = ARRAY_SIZE(pcie1_modemux),
};
-/* pad multiplexing for pcie2 device */
+/* pad multiplexing for (fix-part) pcie2 device */
static struct spear_muxreg pcie2_muxreg[] = {
- PCI_SATA_MUXREG,
{
.reg = PCIE_SATA_CFG,
.mask = PCIE_CFG_VAL(2),
@@ -1852,22 +2115,20 @@ static struct spear_modemux pcie2_modemux[] = {
static struct spear_pingroup pcie2_pingroup = {
.name = "pcie2_grp",
- .pins = pci_sata_pins,
- .npins = ARRAY_SIZE(pci_sata_pins),
.modemuxs = pcie2_modemux,
.nmodemuxs = ARRAY_SIZE(pcie2_modemux),
};
-static const char *const pci_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" };
-static struct spear_function pci_function = {
- .name = "pci",
- .groups = pci_grps,
- .ngroups = ARRAY_SIZE(pci_grps),
+static const char *const pcie_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp"
+};
+static struct spear_function pcie_function = {
+ .name = "pci_express",
+ .groups = pcie_grps,
+ .ngroups = ARRAY_SIZE(pcie_grps),
};
/* pad multiplexing for sata0 device */
static struct spear_muxreg sata0_muxreg[] = {
- PCI_SATA_MUXREG,
{
.reg = PCIE_SATA_CFG,
.mask = SATA_CFG_VAL(0),
@@ -1884,15 +2145,12 @@ static struct spear_modemux sata0_modemux[] = {
static struct spear_pingroup sata0_pingroup = {
.name = "sata0_grp",
- .pins = pci_sata_pins,
- .npins = ARRAY_SIZE(pci_sata_pins),
.modemuxs = sata0_modemux,
.nmodemuxs = ARRAY_SIZE(sata0_modemux),
};
/* pad multiplexing for sata1 device */
static struct spear_muxreg sata1_muxreg[] = {
- PCI_SATA_MUXREG,
{
.reg = PCIE_SATA_CFG,
.mask = SATA_CFG_VAL(1),
@@ -1909,15 +2167,12 @@ static struct spear_modemux sata1_modemux[] = {
static struct spear_pingroup sata1_pingroup = {
.name = "sata1_grp",
- .pins = pci_sata_pins,
- .npins = ARRAY_SIZE(pci_sata_pins),
.modemuxs = sata1_modemux,
.nmodemuxs = ARRAY_SIZE(sata1_modemux),
};
/* pad multiplexing for sata2 device */
static struct spear_muxreg sata2_muxreg[] = {
- PCI_SATA_MUXREG,
{
.reg = PCIE_SATA_CFG,
.mask = SATA_CFG_VAL(2),
@@ -1934,8 +2189,6 @@ static struct spear_modemux sata2_modemux[] = {
static struct spear_pingroup sata2_pingroup = {
.name = "sata2_grp",
- .pins = pci_sata_pins,
- .npins = ARRAY_SIZE(pci_sata_pins),
.modemuxs = sata2_modemux,
.nmodemuxs = ARRAY_SIZE(sata2_modemux),
};
@@ -1957,6 +2210,14 @@ static struct spear_muxreg ssp1_dis_kbd_muxreg[] = {
PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK |
PMX_NFCE2_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_1,
+ .mask = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK |
+ PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK |
+ PMX_NFCE2_MASK,
+ .val = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK |
+ PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK |
+ PMX_NFCE2_MASK,
},
};
@@ -1983,6 +2244,12 @@ static struct spear_muxreg ssp1_dis_sd_muxreg[] = {
.mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK |
PMX_MCICECF_MASK | PMX_MCICEXD_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK |
+ PMX_MCICECF_MASK | PMX_MCICEXD_MASK,
+ .val = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK |
+ PMX_MCICECF_MASK | PMX_MCICEXD_MASK,
},
};
@@ -2017,6 +2284,12 @@ static struct spear_muxreg gpt64_muxreg[] = {
.mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK
| PMX_MCILEDS_MASK,
.val = 0,
+ }, {
+ .reg = PAD_DIRECTION_SEL_2,
+ .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK
+ | PMX_MCILEDS_MASK,
+ .val = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK
+ | PMX_MCILEDS_MASK,
},
};
@@ -2093,6 +2366,7 @@ static struct spear_pingroup *spear1310_pingroups[] = {
&can0_dis_sd_pingroup,
&can1_dis_sd_pingroup,
&can1_dis_kbd_pingroup,
+ &pci_pingroup,
&pcie0_pingroup,
&pcie1_pingroup,
&pcie2_pingroup,
@@ -2138,6 +2412,7 @@ static struct spear_function *spear1310_functions[] = {
&can0_function,
&can1_function,
&pci_function,
+ &pcie_function,
&sata_function,
&ssp1_function,
&gpt64_function,
diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c
index a0eb057e55b..0606b8cf3f2 100644
--- a/drivers/pinctrl/spear/pinctrl-spear1340.c
+++ b/drivers/pinctrl/spear/pinctrl-spear1340.c
@@ -213,7 +213,7 @@ static const struct pinctrl_pin_desc spear1340_pins[] = {
* Pad multiplexing for making all pads as gpio's. This is done to override the
* values passed from bootloader and start from scratch.
*/
-static const unsigned pads_as_gpio_pins[] = { 251 };
+static const unsigned pads_as_gpio_pins[] = { 12, 88, 89, 251 };
static struct spear_muxreg pads_as_gpio_muxreg[] = {
{
.reg = PAD_FUNCTION_EN_1,
@@ -1692,7 +1692,43 @@ static struct spear_pingroup clcd_pingroup = {
.nmodemuxs = ARRAY_SIZE(clcd_modemux),
};
-static const char *const clcd_grps[] = { "clcd_grp" };
+/* Disable cld runtime to save panel damage */
+static struct spear_muxreg clcd_sleep_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = ARM_TRACE_MASK | MIPHY_DBG_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_5,
+ .mask = CLCD_REG4_MASK | CLCD_AND_ARM_TRACE_REG4_MASK,
+ .val = 0x0,
+ }, {
+ .reg = PAD_FUNCTION_EN_6,
+ .mask = CLCD_AND_ARM_TRACE_REG5_MASK,
+ .val = 0x0,
+ }, {
+ .reg = PAD_FUNCTION_EN_7,
+ .mask = CLCD_AND_ARM_TRACE_REG6_MASK,
+ .val = 0x0,
+ },
+};
+
+static struct spear_modemux clcd_sleep_modemux[] = {
+ {
+ .muxregs = clcd_sleep_muxreg,
+ .nmuxregs = ARRAY_SIZE(clcd_sleep_muxreg),
+ },
+};
+
+static struct spear_pingroup clcd_sleep_pingroup = {
+ .name = "clcd_sleep_grp",
+ .pins = clcd_pins,
+ .npins = ARRAY_SIZE(clcd_pins),
+ .modemuxs = clcd_sleep_modemux,
+ .nmodemuxs = ARRAY_SIZE(clcd_sleep_modemux),
+};
+
+static const char *const clcd_grps[] = { "clcd_grp", "clcd_sleep_grp" };
static struct spear_function clcd_function = {
.name = "clcd",
.groups = clcd_grps,
@@ -1893,6 +1929,7 @@ static struct spear_pingroup *spear1340_pingroups[] = {
&sdhci_pingroup,
&cf_pingroup,
&xd_pingroup,
+ &clcd_sleep_pingroup,
&clcd_pingroup,
&arm_trace_pingroup,
&miphy_dbg_pingroup,
diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c
index 020b1e0bdb3..ca47b0e5078 100644
--- a/drivers/pinctrl/spear/pinctrl-spear320.c
+++ b/drivers/pinctrl/spear/pinctrl-spear320.c
@@ -2240,6 +2240,10 @@ static struct spear_muxreg pwm2_pin_34_muxreg[] = {
.mask = PMX_SSP_CS_MASK,
.val = 0,
}, {
+ .reg = MODE_CONFIG_REG,
+ .mask = PMX_PWM_MASK,
+ .val = PMX_PWM_MASK,
+ }, {
.reg = IP_SEL_PAD_30_39_REG,
.mask = PMX_PL_34_MASK,
.val = PMX_PWM2_PL_34_VAL,
@@ -2956,9 +2960,9 @@ static struct spear_function mii2_function = {
};
/* Pad multiplexing for cadence mii 1_2 as smii or rmii device */
-static const unsigned smii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20,
+static const unsigned rmii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27 };
-static const unsigned rmii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 };
+static const unsigned smii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 };
static struct spear_muxreg mii0_1_muxreg[] = {
{
.reg = PMX_CONFIG_REG,
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.h b/drivers/pinctrl/spear/pinctrl-spear3xx.h
index 31f44347f17..7860b36053c 100644
--- a/drivers/pinctrl/spear/pinctrl-spear3xx.h
+++ b/drivers/pinctrl/spear/pinctrl-spear3xx.h
@@ -15,6 +15,7 @@
#include "pinctrl-spear.h"
/* pad mux declarations */
+#define PMX_PWM_MASK (1 << 16)
#define PMX_FIRDA_MASK (1 << 14)
#define PMX_I2C_MASK (1 << 13)
#define PMX_SSP_CS_MASK (1 << 12)
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index c17ae22567e..0c6fcb461fa 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -401,7 +401,7 @@ EXPORT_SYMBOL_GPL(rio_release_inb_pwrite);
/**
* rio_map_inb_region -- Map inbound memory region.
* @mport: Master port.
- * @lstart: physical address of memory region to be mapped
+ * @local: physical address of memory region to be mapped
* @rbase: RIO base address assigned to this window
* @size: Size of the memory region
* @rflags: Flags for mapping.
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 5c4829cba6a..e872c8be080 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1381,22 +1381,14 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
}
EXPORT_SYMBOL_GPL(regulator_get_exclusive);
-/**
- * regulator_put - "free" the regulator source
- * @regulator: regulator source
- *
- * Note: drivers must ensure that all regulator_enable calls made on this
- * regulator source are balanced by regulator_disable calls prior to calling
- * this function.
- */
-void regulator_put(struct regulator *regulator)
+/* Locks held by regulator_put() */
+static void _regulator_put(struct regulator *regulator)
{
struct regulator_dev *rdev;
if (regulator == NULL || IS_ERR(regulator))
return;
- mutex_lock(&regulator_list_mutex);
rdev = regulator->rdev;
debugfs_remove_recursive(regulator->debugfs);
@@ -1412,6 +1404,20 @@ void regulator_put(struct regulator *regulator)
rdev->exclusive = 0;
module_put(rdev->owner);
+}
+
+/**
+ * regulator_put - "free" the regulator source
+ * @regulator: regulator source
+ *
+ * Note: drivers must ensure that all regulator_enable calls made on this
+ * regulator source are balanced by regulator_disable calls prior to calling
+ * this function.
+ */
+void regulator_put(struct regulator *regulator)
+{
+ mutex_lock(&regulator_list_mutex);
+ _regulator_put(regulator);
mutex_unlock(&regulator_list_mutex);
}
EXPORT_SYMBOL_GPL(regulator_put);
@@ -1974,7 +1980,7 @@ int regulator_is_supported_voltage(struct regulator *regulator,
if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
ret = regulator_get_voltage(regulator);
if (ret >= 0)
- return (min_uV >= ret && ret <= max_uV);
+ return (min_uV <= ret && ret <= max_uV);
else
return ret;
}
@@ -3365,7 +3371,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
if (ret != 0) {
rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
config->ena_gpio, ret);
- goto clean;
+ goto wash;
}
rdev->ena_gpio = config->ena_gpio;
@@ -3445,10 +3451,11 @@ unset_supplies:
scrub:
if (rdev->supply)
- regulator_put(rdev->supply);
+ _regulator_put(rdev->supply);
if (rdev->ena_gpio)
gpio_free(rdev->ena_gpio);
kfree(rdev->constraints);
+wash:
device_unregister(&rdev->dev);
/* device core frees rdev */
rdev = ERR_PTR(ret);
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 9ffb6d5f17a..4ed343e4eb4 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -44,7 +44,6 @@
#define RAW3215_NR_CCWS 3
#define RAW3215_TIMEOUT HZ/10 /* time for delayed output */
-#define RAW3215_FIXED 1 /* 3215 console device is not be freed */
#define RAW3215_WORKING 4 /* set if a request is being worked on */
#define RAW3215_THROTTLED 8 /* set if reading is disabled */
#define RAW3215_STOPPED 16 /* set if writing is disabled */
@@ -339,8 +338,10 @@ static void raw3215_wakeup(unsigned long data)
struct tty_struct *tty;
tty = tty_port_tty_get(&raw->port);
- tty_wakeup(tty);
- tty_kref_put(tty);
+ if (tty) {
+ tty_wakeup(tty);
+ tty_kref_put(tty);
+ }
}
/*
@@ -629,8 +630,7 @@ static void raw3215_shutdown(struct raw3215_info *raw)
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
- if (!(raw->port.flags & ASYNC_INITIALIZED) ||
- (raw->flags & RAW3215_FIXED))
+ if (!(raw->port.flags & ASYNC_INITIALIZED))
return;
/* Wait for outstanding requests, then free irq */
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
@@ -926,8 +926,6 @@ static int __init con3215_init(void)
dev_set_drvdata(&cdev->dev, raw);
cdev->handler = raw3215_irq;
- raw->flags |= RAW3215_FIXED;
-
/* Request the console irq */
if (raw3215_startup(raw) != 0) {
raw3215_free_info(raw);
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 33bb4d891e1..4af3dfe70ef 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -112,9 +112,6 @@ extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *);
extern void css_reiterate_subchannels(void);
void css_update_ssd_info(struct subchannel *sch);
-#define __MAX_SUBCHANNEL 65535
-#define __MAX_SSID 3
-
struct channel_subsystem {
u8 cssid;
int valid;
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index fc916f5d731..fd3143c291c 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1424,7 +1424,7 @@ static enum io_sch_action sch_get_action(struct subchannel *sch)
}
if (device_is_disconnected(cdev))
return IO_SCH_REPROBE;
- if (cdev->online)
+ if (cdev->online && !cdev->private->flags.resuming)
return IO_SCH_VERIFY;
if (cdev->private->state == DEV_STATE_NOT_OPER)
return IO_SCH_UNREG_ATTACH;
@@ -1469,12 +1469,6 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
rc = 0;
goto out_unlock;
case IO_SCH_VERIFY:
- if (cdev->private->flags.resuming == 1) {
- if (cio_enable_subchannel(sch, (u32)(addr_t)sch)) {
- ccw_device_set_notoper(cdev);
- break;
- }
- }
/* Trigger path verification. */
io_subchannel_verify(sch);
rc = 0;
diff --git a/drivers/s390/cio/idset.c b/drivers/s390/cio/idset.c
index 199bc679117..65d13e38803 100644
--- a/drivers/s390/cio/idset.c
+++ b/drivers/s390/cio/idset.c
@@ -125,8 +125,7 @@ int idset_is_empty(struct idset *set)
void idset_add_set(struct idset *to, struct idset *from)
{
- int len = min(__BITOPS_WORDS(to->num_ssid * to->num_id),
- __BITOPS_WORDS(from->num_ssid * from->num_id));
+ int len = min(to->num_ssid * to->num_id, from->num_ssid * from->num_id);
bitmap_or(to->bitmap, to->bitmap, from->bitmap, len);
}
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 3e25d315045..4d6ba00d004 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2942,13 +2942,33 @@ static int qeth_query_ipassists_cb(struct qeth_card *card,
QETH_DBF_TEXT(SETUP, 2, "qipasscb");
cmd = (struct qeth_ipa_cmd *) data;
+
+ switch (cmd->hdr.return_code) {
+ case IPA_RC_NOTSUPP:
+ case IPA_RC_L2_UNSUPPORTED_CMD:
+ QETH_DBF_TEXT(SETUP, 2, "ipaunsup");
+ card->options.ipa4.supported_funcs |= IPA_SETADAPTERPARMS;
+ card->options.ipa6.supported_funcs |= IPA_SETADAPTERPARMS;
+ return -0;
+ default:
+ if (cmd->hdr.return_code) {
+ QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Unhandled "
+ "rc=%d\n",
+ dev_name(&card->gdev->dev),
+ cmd->hdr.return_code);
+ return 0;
+ }
+ }
+
if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
- } else {
+ } else if (cmd->hdr.prot_version == QETH_PROT_IPV6) {
card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
- }
+ } else
+ QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Flawed LIC detected"
+ "\n", dev_name(&card->gdev->dev));
QETH_DBF_TEXT(SETUP, 2, "suppenbl");
QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_supported);
QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_enabled);
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index e67e0258aec..fddb62654b6 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -626,10 +626,13 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card)
QETH_DBF_TEXT(SETUP, 2, "doL2init");
QETH_DBF_TEXT_(SETUP, 2, "doL2%s", CARD_BUS_ID(card));
- rc = qeth_query_setadapterparms(card);
- if (rc) {
- QETH_DBF_MESSAGE(2, "could not query adapter parameters on "
- "device %s: x%x\n", CARD_BUS_ID(card), rc);
+ if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) {
+ rc = qeth_query_setadapterparms(card);
+ if (rc) {
+ QETH_DBF_MESSAGE(2, "could not query adapter "
+ "parameters on device %s: x%x\n",
+ CARD_BUS_ID(card), rc);
+ }
}
if (card->info.type == QETH_CARD_TYPE_IQD ||
@@ -676,7 +679,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
return -ERESTARTSYS;
}
rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]);
- if (!rc)
+ if (!rc || (rc == IPA_RC_L2_MAC_NOT_FOUND))
rc = qeth_l2_send_setmac(card, addr->sa_data);
return rc ? -EINVAL : 0;
}
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index c1bafc3f3fb..9594ab62702 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -1972,7 +1972,7 @@ sci_io_request_frame_handler(struct isci_request *ireq,
frame_index,
(void **)&frame_buffer);
- sci_controller_copy_sata_response(&ireq->stp.req,
+ sci_controller_copy_sata_response(&ireq->stp.rsp,
frame_header,
frame_buffer);
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index b191dd54920..71fddbc60f1 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -1294,26 +1294,19 @@ static struct scsi_host_template qpti_template = {
static const struct of_device_id qpti_match[];
static int __devinit qpti_sbus_probe(struct platform_device *op)
{
- const struct of_device_id *match;
- struct scsi_host_template *tpnt;
struct device_node *dp = op->dev.of_node;
struct Scsi_Host *host;
struct qlogicpti *qpti;
static int nqptis;
const char *fcode;
- match = of_match_device(qpti_match, &op->dev);
- if (!match)
- return -EINVAL;
- tpnt = match->data;
-
/* Sometimes Antares cards come up not completely
* setup, and we get a report of a zero IRQ.
*/
if (op->archdata.irqs[0] == 0)
return -ENODEV;
- host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti));
+ host = scsi_host_alloc(&qpti_template, sizeof(struct qlogicpti));
if (!host)
return -ENOMEM;
@@ -1445,19 +1438,15 @@ static int __devexit qpti_sbus_remove(struct platform_device *op)
static const struct of_device_id qpti_match[] = {
{
.name = "ptisp",
- .data = &qpti_template,
},
{
.name = "PTI,ptisp",
- .data = &qpti_template,
},
{
.name = "QLGC,isp",
- .data = &qpti_template,
},
{
.name = "SUNW,isp",
- .data = &qpti_template,
},
{},
};
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 2936b447cae..2c0d0ec8150 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -55,6 +55,7 @@
#include <linux/cpu.h>
#include <linux/mutex.h>
#include <linux/async.h>
+#include <asm/unaligned.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -1062,6 +1063,50 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf,
EXPORT_SYMBOL_GPL(scsi_get_vpd_page);
/**
+ * scsi_report_opcode - Find out if a given command opcode is supported
+ * @sdev: scsi device to query
+ * @buffer: scratch buffer (must be at least 20 bytes long)
+ * @len: length of buffer
+ * @opcode: opcode for command to look up
+ *
+ * Uses the REPORT SUPPORTED OPERATION CODES to look up the given
+ * opcode. Returns 0 if RSOC fails or if the command opcode is
+ * unsupported. Returns 1 if the device claims to support the command.
+ */
+int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
+ unsigned int len, unsigned char opcode)
+{
+ unsigned char cmd[16];
+ struct scsi_sense_hdr sshdr;
+ int result;
+
+ if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3)
+ return 0;
+
+ memset(cmd, 0, 16);
+ cmd[0] = MAINTENANCE_IN;
+ cmd[1] = MI_REPORT_SUPPORTED_OPERATION_CODES;
+ cmd[2] = 1; /* One command format */
+ cmd[3] = opcode;
+ put_unaligned_be32(len, &cmd[6]);
+ memset(buffer, 0, len);
+
+ result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
+ &sshdr, 30 * HZ, 3, NULL);
+
+ if (result && scsi_sense_valid(&sshdr) &&
+ sshdr.sense_key == ILLEGAL_REQUEST &&
+ (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00)
+ return 0;
+
+ if ((buffer[1] & 3) == 3) /* Command supported */
+ return 1;
+
+ return 0;
+}
+EXPORT_SYMBOL(scsi_report_opcode);
+
+/**
* scsi_device_get - get an additional reference to a scsi_device
* @sdev: device to get a reference to
*
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index da36a3a81a9..9032e910bca 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -900,11 +900,23 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
action = ACTION_FAIL;
error = -EILSEQ;
/* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */
- } else if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) &&
- (cmd->cmnd[0] == UNMAP ||
- cmd->cmnd[0] == WRITE_SAME_16 ||
- cmd->cmnd[0] == WRITE_SAME)) {
- description = "Discard failure";
+ } else if (sshdr.asc == 0x20 || sshdr.asc == 0x24) {
+ switch (cmd->cmnd[0]) {
+ case UNMAP:
+ description = "Discard failure";
+ break;
+ case WRITE_SAME:
+ case WRITE_SAME_16:
+ if (cmd->cmnd[1] & 0x8)
+ description = "Discard failure";
+ else
+ description =
+ "Write same failure";
+ break;
+ default:
+ description = "Invalid command failure";
+ break;
+ }
action = ACTION_FAIL;
error = -EREMOTEIO;
} else
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 12f6fdfc114..352bc77b7c8 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -99,6 +99,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
#endif
static void sd_config_discard(struct scsi_disk *, unsigned int);
+static void sd_config_write_same(struct scsi_disk *);
static int sd_revalidate_disk(struct gendisk *);
static void sd_unlock_native_capacity(struct gendisk *disk);
static int sd_probe(struct device *);
@@ -395,6 +396,45 @@ sd_store_max_medium_access_timeouts(struct device *dev,
return err ? err : count;
}
+static ssize_t
+sd_show_write_same_blocks(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
+
+ return snprintf(buf, 20, "%u\n", sdkp->max_ws_blocks);
+}
+
+static ssize_t
+sd_store_write_same_blocks(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct scsi_disk *sdkp = to_scsi_disk(dev);
+ struct scsi_device *sdp = sdkp->device;
+ unsigned long max;
+ int err;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ if (sdp->type != TYPE_DISK)
+ return -EINVAL;
+
+ err = kstrtoul(buf, 10, &max);
+
+ if (err)
+ return err;
+
+ if (max == 0)
+ sdp->no_write_same = 1;
+ else if (max <= SD_MAX_WS16_BLOCKS)
+ sdkp->max_ws_blocks = max;
+
+ sd_config_write_same(sdkp);
+
+ return count;
+}
+
static struct device_attribute sd_disk_attrs[] = {
__ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type,
sd_store_cache_type),
@@ -410,6 +450,8 @@ static struct device_attribute sd_disk_attrs[] = {
__ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL),
__ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode,
sd_store_provisioning_mode),
+ __ATTR(max_write_same_blocks, S_IRUGO|S_IWUSR,
+ sd_show_write_same_blocks, sd_store_write_same_blocks),
__ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR,
sd_show_max_medium_access_timeouts,
sd_store_max_medium_access_timeouts),
@@ -561,19 +603,23 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
return;
case SD_LBP_UNMAP:
- max_blocks = min_not_zero(sdkp->max_unmap_blocks, 0xffffffff);
+ max_blocks = min_not_zero(sdkp->max_unmap_blocks,
+ (u32)SD_MAX_WS16_BLOCKS);
break;
case SD_LBP_WS16:
- max_blocks = min_not_zero(sdkp->max_ws_blocks, 0xffffffff);
+ max_blocks = min_not_zero(sdkp->max_ws_blocks,
+ (u32)SD_MAX_WS16_BLOCKS);
break;
case SD_LBP_WS10:
- max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff);
+ max_blocks = min_not_zero(sdkp->max_ws_blocks,
+ (u32)SD_MAX_WS10_BLOCKS);
break;
case SD_LBP_ZERO:
- max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff);
+ max_blocks = min_not_zero(sdkp->max_ws_blocks,
+ (u32)SD_MAX_WS10_BLOCKS);
q->limits.discard_zeroes_data = 1;
break;
}
@@ -583,29 +629,26 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
}
/**
- * scsi_setup_discard_cmnd - unmap blocks on thinly provisioned device
+ * sd_setup_discard_cmnd - unmap blocks on thinly provisioned device
* @sdp: scsi device to operate one
* @rq: Request to prepare
*
* Will issue either UNMAP or WRITE SAME(16) depending on preference
* indicated by target device.
**/
-static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
+static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
{
struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
- struct bio *bio = rq->bio;
- sector_t sector = bio->bi_sector;
- unsigned int nr_sectors = bio_sectors(bio);
+ sector_t sector = blk_rq_pos(rq);
+ unsigned int nr_sectors = blk_rq_sectors(rq);
+ unsigned int nr_bytes = blk_rq_bytes(rq);
unsigned int len;
int ret;
char *buf;
struct page *page;
- if (sdkp->device->sector_size == 4096) {
- sector >>= 3;
- nr_sectors >>= 3;
- }
-
+ sector >>= ilog2(sdp->sector_size) - 9;
+ nr_sectors >>= ilog2(sdp->sector_size) - 9;
rq->timeout = SD_TIMEOUT;
memset(rq->cmd, 0, rq->cmd_len);
@@ -660,6 +703,7 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
blk_add_request_payload(rq, page, len);
ret = scsi_setup_blk_pc_cmnd(sdp, rq);
rq->buffer = page_address(page);
+ rq->__data_len = nr_bytes;
out:
if (ret != BLKPREP_OK) {
@@ -669,6 +713,83 @@ out:
return ret;
}
+static void sd_config_write_same(struct scsi_disk *sdkp)
+{
+ struct request_queue *q = sdkp->disk->queue;
+ unsigned int logical_block_size = sdkp->device->sector_size;
+ unsigned int blocks = 0;
+
+ if (sdkp->device->no_write_same) {
+ sdkp->max_ws_blocks = 0;
+ goto out;
+ }
+
+ /* Some devices can not handle block counts above 0xffff despite
+ * supporting WRITE SAME(16). Consequently we default to 64k
+ * blocks per I/O unless the device explicitly advertises a
+ * bigger limit.
+ */
+ if (sdkp->max_ws_blocks == 0)
+ sdkp->max_ws_blocks = SD_MAX_WS10_BLOCKS;
+
+ if (sdkp->ws16 || sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS)
+ blocks = min_not_zero(sdkp->max_ws_blocks,
+ (u32)SD_MAX_WS16_BLOCKS);
+ else
+ blocks = min_not_zero(sdkp->max_ws_blocks,
+ (u32)SD_MAX_WS10_BLOCKS);
+
+out:
+ blk_queue_max_write_same_sectors(q, blocks * (logical_block_size >> 9));
+}
+
+/**
+ * sd_setup_write_same_cmnd - write the same data to multiple blocks
+ * @sdp: scsi device to operate one
+ * @rq: Request to prepare
+ *
+ * Will issue either WRITE SAME(10) or WRITE SAME(16) depending on
+ * preference indicated by target device.
+ **/
+static int sd_setup_write_same_cmnd(struct scsi_device *sdp, struct request *rq)
+{
+ struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+ struct bio *bio = rq->bio;
+ sector_t sector = blk_rq_pos(rq);
+ unsigned int nr_sectors = blk_rq_sectors(rq);
+ unsigned int nr_bytes = blk_rq_bytes(rq);
+ int ret;
+
+ if (sdkp->device->no_write_same)
+ return BLKPREP_KILL;
+
+ BUG_ON(bio_offset(bio) || bio_iovec(bio)->bv_len != sdp->sector_size);
+
+ sector >>= ilog2(sdp->sector_size) - 9;
+ nr_sectors >>= ilog2(sdp->sector_size) - 9;
+
+ rq->__data_len = sdp->sector_size;
+ rq->timeout = SD_WRITE_SAME_TIMEOUT;
+ memset(rq->cmd, 0, rq->cmd_len);
+
+ if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff) {
+ rq->cmd_len = 16;
+ rq->cmd[0] = WRITE_SAME_16;
+ put_unaligned_be64(sector, &rq->cmd[2]);
+ put_unaligned_be32(nr_sectors, &rq->cmd[10]);
+ } else {
+ rq->cmd_len = 10;
+ rq->cmd[0] = WRITE_SAME;
+ put_unaligned_be32(sector, &rq->cmd[2]);
+ put_unaligned_be16(nr_sectors, &rq->cmd[7]);
+ }
+
+ ret = scsi_setup_blk_pc_cmnd(sdp, rq);
+ rq->__data_len = nr_bytes;
+
+ return ret;
+}
+
static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq)
{
rq->timeout = SD_FLUSH_TIMEOUT;
@@ -712,7 +833,10 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
* block PC requests to make life easier.
*/
if (rq->cmd_flags & REQ_DISCARD) {
- ret = scsi_setup_discard_cmnd(sdp, rq);
+ ret = sd_setup_discard_cmnd(sdp, rq);
+ goto out;
+ } else if (rq->cmd_flags & REQ_WRITE_SAME) {
+ ret = sd_setup_write_same_cmnd(sdp, rq);
goto out;
} else if (rq->cmd_flags & REQ_FLUSH) {
ret = scsi_setup_flush_cmnd(sdp, rq);
@@ -1482,12 +1606,21 @@ static int sd_done(struct scsi_cmnd *SCpnt)
unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt);
struct scsi_sense_hdr sshdr;
struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk);
+ struct request *req = SCpnt->request;
int sense_valid = 0;
int sense_deferred = 0;
unsigned char op = SCpnt->cmnd[0];
+ unsigned char unmap = SCpnt->cmnd[1] & 8;
- if ((SCpnt->request->cmd_flags & REQ_DISCARD) && !result)
- scsi_set_resid(SCpnt, 0);
+ if (req->cmd_flags & REQ_DISCARD || req->cmd_flags & REQ_WRITE_SAME) {
+ if (!result) {
+ good_bytes = blk_rq_bytes(req);
+ scsi_set_resid(SCpnt, 0);
+ } else {
+ good_bytes = 0;
+ scsi_set_resid(SCpnt, blk_rq_bytes(req));
+ }
+ }
if (result) {
sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr);
@@ -1536,9 +1669,25 @@ static int sd_done(struct scsi_cmnd *SCpnt)
if (sshdr.asc == 0x10) /* DIX: Host detected corruption */
good_bytes = sd_completed_bytes(SCpnt);
/* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */
- if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) &&
- (op == UNMAP || op == WRITE_SAME_16 || op == WRITE_SAME))
- sd_config_discard(sdkp, SD_LBP_DISABLE);
+ if (sshdr.asc == 0x20 || sshdr.asc == 0x24) {
+ switch (op) {
+ case UNMAP:
+ sd_config_discard(sdkp, SD_LBP_DISABLE);
+ break;
+ case WRITE_SAME_16:
+ case WRITE_SAME:
+ if (unmap)
+ sd_config_discard(sdkp, SD_LBP_DISABLE);
+ else {
+ sdkp->device->no_write_same = 1;
+ sd_config_write_same(sdkp);
+
+ good_bytes = 0;
+ req->__data_len = blk_rq_bytes(req);
+ req->cmd_flags |= REQ_QUIET;
+ }
+ }
+ }
break;
default:
break;
@@ -2374,9 +2523,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
if (buffer[3] == 0x3c) {
unsigned int lba_count, desc_count;
- sdkp->max_ws_blocks =
- (u32) min_not_zero(get_unaligned_be64(&buffer[36]),
- (u64)0xffffffff);
+ sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]);
if (!sdkp->lbpme)
goto out;
@@ -2469,6 +2616,13 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp)
kfree(buffer);
}
+static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
+{
+ if (scsi_report_opcode(sdkp->device, buffer, SD_BUF_SIZE,
+ WRITE_SAME_16))
+ sdkp->ws16 = 1;
+}
+
static int sd_try_extended_inquiry(struct scsi_device *sdp)
{
/*
@@ -2528,6 +2682,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
sd_read_write_protect_flag(sdkp, buffer);
sd_read_cache_type(sdkp, buffer);
sd_read_app_tag_own(sdkp, buffer);
+ sd_read_write_same(sdkp, buffer);
}
sdkp->first_scan = 0;
@@ -2545,6 +2700,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
blk_queue_flush(sdkp->disk->queue, flush);
set_capacity(disk, sdkp->capacity);
+ sd_config_write_same(sdkp);
kfree(buffer);
out:
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 47c52a6d733..74a1e4ca540 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -14,6 +14,7 @@
#define SD_TIMEOUT (30 * HZ)
#define SD_MOD_TIMEOUT (75 * HZ)
#define SD_FLUSH_TIMEOUT (60 * HZ)
+#define SD_WRITE_SAME_TIMEOUT (120 * HZ)
/*
* Number of allowed retries
@@ -39,6 +40,11 @@ enum {
};
enum {
+ SD_MAX_WS10_BLOCKS = 0xffff,
+ SD_MAX_WS16_BLOCKS = 0x7fffff,
+};
+
+enum {
SD_LBP_FULL = 0, /* Full logical block provisioning */
SD_LBP_UNMAP, /* Use UNMAP command */
SD_LBP_WS16, /* Use WRITE SAME(16) with UNMAP bit */
@@ -77,6 +83,7 @@ struct scsi_disk {
unsigned lbpws : 1;
unsigned lbpws10 : 1;
unsigned lbpvpd : 1;
+ unsigned ws16 : 1;
};
#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h
index f2ffd963f1c..d0cafd63719 100644
--- a/drivers/staging/android/android_alarm.h
+++ b/drivers/staging/android/android_alarm.h
@@ -51,12 +51,10 @@ enum android_alarm_return_flags {
#define ANDROID_ALARM_WAIT _IO('a', 1)
#define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size)
-#define ALARM_IOR(c, type, size) _IOR('a', (c) | ((type) << 4), size)
-
/* Set alarm */
#define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec)
#define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec)
-#define ANDROID_ALARM_GET_TIME(type) ALARM_IOR(4, type, struct timespec)
+#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec)
#define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec)
#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0)))
#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4)
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index a5dec1ca1b8..13ee53bd0bf 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -424,7 +424,6 @@ static void hvc_hangup(struct tty_struct *tty)
{
struct hvc_struct *hp = tty->driver_data;
unsigned long flags;
- int temp_open_count;
if (!hp)
return;
@@ -444,7 +443,6 @@ static void hvc_hangup(struct tty_struct *tty)
return;
}
- temp_open_count = hp->port.count;
hp->port.count = 0;
spin_unlock_irqrestore(&hp->port.lock, flags);
tty_port_tty_set(&hp->port, NULL);
@@ -453,11 +451,6 @@ static void hvc_hangup(struct tty_struct *tty)
if (hp->ops->notifier_hangup)
hp->ops->notifier_hangup(hp, hp->data);
-
- while(temp_open_count) {
- --temp_open_count;
- tty_port_put(&hp->port);
- }
}
/*
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index 2bc28a59d38..1ab1d2c66de 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -1239,6 +1239,7 @@ static int __devexit max310x_remove(struct spi_device *spi)
static const struct spi_device_id max310x_id_table[] = {
{ "max3107", MAX310X_TYPE_MAX3107 },
{ "max3108", MAX310X_TYPE_MAX3108 },
+ { }
};
MODULE_DEVICE_TABLE(spi, max310x_id_table);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 1e741bca026..f034716190f 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2151,8 +2151,15 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum);
irqreturn_t usb_hcd_irq (int irq, void *__hcd)
{
struct usb_hcd *hcd = __hcd;
+ unsigned long flags;
irqreturn_t rc;
+ /* IRQF_DISABLED doesn't work correctly with shared IRQs
+ * when the first handler doesn't use it. So let's just
+ * assume it's never used.
+ */
+ local_irq_save(flags);
+
if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd)))
rc = IRQ_NONE;
else if (hcd->driver->irq(hcd) == IRQ_NONE)
@@ -2160,6 +2167,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)
else
rc = IRQ_HANDLED;
+ local_irq_restore(flags);
return rc;
}
EXPORT_SYMBOL_GPL(usb_hcd_irq);
@@ -2347,6 +2355,14 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd,
int retval;
if (hcd->driver->irq) {
+
+ /* IRQF_DISABLED doesn't work as advertised when used together
+ * with IRQF_SHARED. As usb_hcd_irq() will always disable
+ * interrupts we can remove it here.
+ */
+ if (irqflags & IRQF_SHARED)
+ irqflags &= ~IRQF_DISABLED;
+
snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
hcd->driver->description, hcd->self.busnum);
retval = request_irq(irqnum, &usb_hcd_irq, irqflags,
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c
index e426ad626d7..4bfa78af379 100644
--- a/drivers/usb/early/ehci-dbgp.c
+++ b/drivers/usb/early/ehci-dbgp.c
@@ -20,6 +20,7 @@
#include <linux/usb/ehci_def.h>
#include <linux/delay.h>
#include <linux/serial_core.h>
+#include <linux/kconfig.h>
#include <linux/kgdb.h>
#include <linux/kthread.h>
#include <asm/io.h>
@@ -614,12 +615,6 @@ err:
return -ENODEV;
}
-int dbgp_external_startup(struct usb_hcd *hcd)
-{
- return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
-}
-EXPORT_SYMBOL_GPL(dbgp_external_startup);
-
static int ehci_reset_port(int port)
{
u32 portsc;
@@ -979,6 +974,7 @@ struct console early_dbgp_console = {
.index = -1,
};
+#if IS_ENABLED(CONFIG_USB_EHCI_HCD)
int dbgp_reset_prep(struct usb_hcd *hcd)
{
int ret = xen_dbgp_reset_prep(hcd);
@@ -1007,6 +1003,13 @@ int dbgp_reset_prep(struct usb_hcd *hcd)
}
EXPORT_SYMBOL_GPL(dbgp_reset_prep);
+int dbgp_external_startup(struct usb_hcd *hcd)
+{
+ return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
+}
+EXPORT_SYMBOL_GPL(dbgp_external_startup);
+#endif /* USB_EHCI_HCD */
+
#ifdef CONFIG_KGDB
static char kgdbdbgp_buf[DBGP_MAX_PACKET];
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 6458764994e..4ec3c0d7a18 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -20,6 +20,7 @@
#include <linux/ctype.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
#include "u_ether.h"
@@ -295,7 +296,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req)
while (skb2) {
if (status < 0
|| ETH_HLEN > skb2->len
- || skb2->len > ETH_FRAME_LEN) {
+ || skb2->len > VLAN_ETH_FRAME_LEN) {
dev->net->stats.rx_errors++;
dev->net->stats.rx_length_errors++;
DBG(dev, "rx length %d\n", skb2->len);
diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c
index ca759652626..aa0f328922d 100644
--- a/drivers/usb/host/ehci-ls1x.c
+++ b/drivers/usb/host/ehci-ls1x.c
@@ -113,7 +113,7 @@ static int ehci_hcd_ls1x_probe(struct platform_device *pdev)
goto err_put_hcd;
}
- ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
if (ret)
goto err_put_hcd;
diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c
index 84201cd1a47..41e378f17c6 100644
--- a/drivers/usb/host/ohci-xls.c
+++ b/drivers/usb/host/ohci-xls.c
@@ -56,7 +56,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver,
goto err3;
}
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
if (retval != 0)
goto err4;
return retval;
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index d0b87e7b4ab..b6b84dacc79 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -707,11 +707,12 @@ static void rxstate(struct musb *musb, struct musb_request *req)
fifo_count = musb_readw(epio, MUSB_RXCOUNT);
/*
- * use mode 1 only if we expect data of at least ep packet_sz
- * and have not yet received a short packet
+ * Enable Mode 1 on RX transfers only when short_not_ok flag
+ * is set. Currently short_not_ok flag is set only from
+ * file_storage and f_mass_storage drivers
*/
- if ((request->length - request->actual >= musb_ep->packet_sz) &&
- (fifo_count >= musb_ep->packet_sz))
+
+ if (request->short_not_ok && fifo_count == musb_ep->packet_sz)
use_mode_1 = 1;
else
use_mode_1 = 0;
@@ -727,6 +728,27 @@ static void rxstate(struct musb *musb, struct musb_request *req)
c = musb->dma_controller;
channel = musb_ep->dma;
+ /* We use DMA Req mode 0 in rx_csr, and DMA controller operates in
+ * mode 0 only. So we do not get endpoint interrupts due to DMA
+ * completion. We only get interrupts from DMA controller.
+ *
+ * We could operate in DMA mode 1 if we knew the size of the tranfer
+ * in advance. For mass storage class, request->length = what the host
+ * sends, so that'd work. But for pretty much everything else,
+ * request->length is routinely more than what the host sends. For
+ * most these gadgets, end of is signified either by a short packet,
+ * or filling the last byte of the buffer. (Sending extra data in
+ * that last pckate should trigger an overflow fault.) But in mode 1,
+ * we don't get DMA completion interrupt for short packets.
+ *
+ * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1),
+ * to get endpoint interrupt on every DMA req, but that didn't seem
+ * to work reliably.
+ *
+ * REVISIT an updated g_file_storage can set req->short_not_ok, which
+ * then becomes usable as a runtime "use mode 1" hint...
+ */
+
/* Experimental: Mode1 works with mass storage use cases */
if (use_mode_1) {
csr |= MUSB_RXCSR_AUTOCLEAR;
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c
index d62a91fedc2..0e62f504410 100644
--- a/drivers/usb/musb/ux500.c
+++ b/drivers/usb/musb/ux500.c
@@ -65,7 +65,7 @@ static int __devinit ux500_probe(struct platform_device *pdev)
struct platform_device *musb;
struct ux500_glue *glue;
struct clk *clk;
-
+ int musbid;
int ret = -ENOMEM;
glue = kzalloc(sizeof(*glue), GFP_KERNEL);
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index d8c8a42bff3..6223062d5d1 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -58,7 +58,7 @@ config USB_ULPI_VIEWPORT
config TWL4030_USB
tristate "TWL4030 USB Transceiver Driver"
- depends on TWL4030_CORE && REGULATOR_TWL4030
+ depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
select USB_OTG_UTILS
help
Enable this to support the USB OTG transceiver on TWL4030
@@ -68,7 +68,7 @@ config TWL4030_USB
config TWL6030_USB
tristate "TWL6030 USB Transceiver Driver"
- depends on TWL4030_CORE && OMAP_USB2
+ depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS
select USB_OTG_UTILS
help
Enable this to support the USB OTG transceiver on TWL6030
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 7179b0c5f81..cff8dd5b462 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -2430,7 +2430,7 @@ static void keyspan_release(struct usb_serial *serial)
static int keyspan_port_probe(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
- struct keyspan_port_private *s_priv;
+ struct keyspan_serial_private *s_priv;
struct keyspan_port_private *p_priv;
const struct keyspan_device_details *d_details;
struct callbacks *cback;
@@ -2445,7 +2445,6 @@ static int keyspan_port_probe(struct usb_serial_port *port)
if (!p_priv)
return -ENOMEM;
- s_priv = usb_get_serial_data(port->serial);
p_priv->device_details = d_details;
/* Setup values for the various callback routines */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 5dee7d61241..edc64bb6f45 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -158,6 +158,7 @@ static void option_instat_callback(struct urb *urb);
#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001
+#define NOVATELWIRELESS_PRODUCT_E362 0x9010
#define NOVATELWIRELESS_PRODUCT_G1 0xA001
#define NOVATELWIRELESS_PRODUCT_G1_M 0xA002
#define NOVATELWIRELESS_PRODUCT_G2 0xA010
@@ -193,6 +194,9 @@ static void option_instat_callback(struct urb *urb);
#define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181
#define DELL_PRODUCT_5730_MINICARD_VZW 0x8182
+#define DELL_PRODUCT_5800_MINICARD_VZW 0x8195 /* Novatel E362 */
+#define DELL_PRODUCT_5800_V2_MINICARD_VZW 0x8196 /* Novatel E362 */
+
#define KYOCERA_VENDOR_ID 0x0c88
#define KYOCERA_PRODUCT_KPC650 0x17da
#define KYOCERA_PRODUCT_KPC680 0x180a
@@ -283,6 +287,7 @@ static void option_instat_callback(struct urb *urb);
/* ALCATEL PRODUCTS */
#define ALCATEL_VENDOR_ID 0x1bbb
#define ALCATEL_PRODUCT_X060S_X200 0x0000
+#define ALCATEL_PRODUCT_X220_X500D 0x0017
#define PIRELLI_VENDOR_ID 0x1266
#define PIRELLI_PRODUCT_C100_1 0x1002
@@ -706,6 +711,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) },
/* Novatel Ovation MC551 a.k.a. Verizon USB551L */
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
@@ -728,6 +734,8 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
+ { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
@@ -1157,6 +1165,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
.driver_info = (kernel_ulong_t)&alcatel_x200_blacklist
},
+ { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) },
{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
{ USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index 61a73ad1a18..a3e9c095f0d 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -455,9 +455,6 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
struct usb_serial *serial = port->serial;
struct urb *urb;
- if (endpoint == -1)
- return NULL; /* endpoint not needed */
-
urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */
if (urb == NULL) {
dev_dbg(&serial->interface->dev,
@@ -489,6 +486,9 @@ int usb_wwan_port_probe(struct usb_serial_port *port)
init_usb_anchor(&portdata->delayed);
for (i = 0; i < N_IN_URB; i++) {
+ if (!port->bulk_in_size)
+ break;
+
buffer = (u8 *)__get_free_page(GFP_KERNEL);
if (!buffer)
goto bail_out_error;
@@ -502,8 +502,8 @@ int usb_wwan_port_probe(struct usb_serial_port *port)
}
for (i = 0; i < N_OUT_URB; i++) {
- if (port->bulk_out_endpointAddress == -1)
- continue;
+ if (!port->bulk_out_size)
+ break;
buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
if (!buffer)
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index a3d54366afc..92f35abee92 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -186,6 +186,12 @@ static int slave_configure(struct scsi_device *sdev)
/* Some devices don't handle VPD pages correctly */
sdev->skip_vpd_pages = 1;
+ /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */
+ sdev->no_report_opcodes = 1;
+
+ /* Do not attempt to use WRITE SAME */
+ sdev->no_write_same = 1;
+
/* Some disks return the total number of blocks in response
* to READ CAPACITY rather than the highest block number.
* If this device makes that mistake, tell the sd driver. */
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index d64ac384288..bee92846cfa 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -365,11 +365,20 @@ struct platform_device *dsi_get_dsidev_from_id(int module)
struct omap_dss_output *out;
enum omap_dss_output_id id;
- id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+ switch (module) {
+ case 0:
+ id = OMAP_DSS_OUTPUT_DSI1;
+ break;
+ case 1:
+ id = OMAP_DSS_OUTPUT_DSI2;
+ break;
+ default:
+ return NULL;
+ }
out = omap_dss_get_output(id);
- return out->pdev;
+ return out ? out->pdev : NULL;
}
static inline void dsi_write_reg(struct platform_device *dsidev,
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 2ab1c3e9655..5f6eea801b0 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -697,11 +697,15 @@ static int dss_get_clocks(void)
dss.dss_clk = clk;
- clk = clk_get(NULL, dss.feat->clk_name);
- if (IS_ERR(clk)) {
- DSSERR("Failed to get %s\n", dss.feat->clk_name);
- r = PTR_ERR(clk);
- goto err;
+ if (dss.feat->clk_name) {
+ clk = clk_get(NULL, dss.feat->clk_name);
+ if (IS_ERR(clk)) {
+ DSSERR("Failed to get %s\n", dss.feat->clk_name);
+ r = PTR_ERR(clk);
+ goto err;
+ }
+ } else {
+ clk = NULL;
}
dss.dpll4_m4_ck = clk;
@@ -805,10 +809,10 @@ static int __init dss_init_features(struct device *dev)
if (cpu_is_omap24xx())
src = &omap24xx_dss_feats;
- else if (cpu_is_omap34xx())
- src = &omap34xx_dss_feats;
else if (cpu_is_omap3630())
src = &omap3630_dss_feats;
+ else if (cpu_is_omap34xx())
+ src = &omap34xx_dss_feats;
else if (cpu_is_omap44xx())
src = &omap44xx_dss_feats;
else if (soc_is_omap54xx())
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index a48a7dd75b3..8c9b8b3b7f7 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -644,8 +644,10 @@ static void hdmi_dump_regs(struct seq_file *s)
{
mutex_lock(&hdmi.lock);
- if (hdmi_runtime_get())
+ if (hdmi_runtime_get()) {
+ mutex_unlock(&hdmi.lock);
return;
+ }
hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s);
hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s);
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 606b89f1235..d630b26a005 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -787,7 +787,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
case OMAPFB_WAITFORVSYNC:
DBG("ioctl WAITFORVSYNC\n");
- if (!display && !display->output && !display->output->manager) {
+ if (!display || !display->output || !display->output->manager) {
r = -EINVAL;
break;
}
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 1e8659ca27e..809b0de59c0 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -225,8 +225,10 @@ EXPORT_SYMBOL_GPL(register_virtio_device);
void unregister_virtio_device(struct virtio_device *dev)
{
+ int index = dev->index; /* save for after device release */
+
device_unregister(&dev->dev);
- ida_simple_remove(&virtio_index_ida, dev->index);
+ ida_simple_remove(&virtio_index_ida, index);
}
EXPORT_SYMBOL_GPL(unregister_virtio_device);
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 0e863703545..74354708c6c 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -2,6 +2,7 @@ ifneq ($(CONFIG_ARM),y)
obj-y += manage.o balloon.o
obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
endif
+obj-$(CONFIG_X86) += fallback.o
obj-y += grant-table.o features.o events.o
obj-y += xenbus/
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 912ac81b6db..0be4df39e95 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -1395,10 +1395,10 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
+ irq_enter();
#ifdef CONFIG_X86
exit_idle();
#endif
- irq_enter();
__xen_evtchn_do_upcall();
diff --git a/drivers/xen/fallback.c b/drivers/xen/fallback.c
new file mode 100644
index 00000000000..0ef7c4d40f8
--- /dev/null
+++ b/drivers/xen/fallback.c
@@ -0,0 +1,80 @@
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/bug.h>
+#include <linux/export.h>
+#include <asm/hypervisor.h>
+#include <asm/xen/hypercall.h>
+
+int xen_event_channel_op_compat(int cmd, void *arg)
+{
+ struct evtchn_op op;
+ int rc;
+
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, event_channel_op_compat, &op);
+
+ switch (cmd) {
+ case EVTCHNOP_close:
+ case EVTCHNOP_send:
+ case EVTCHNOP_bind_vcpu:
+ case EVTCHNOP_unmask:
+ /* no output */
+ break;
+
+#define COPY_BACK(eop) \
+ case EVTCHNOP_##eop: \
+ memcpy(arg, &op.u.eop, sizeof(op.u.eop)); \
+ break
+
+ COPY_BACK(bind_interdomain);
+ COPY_BACK(bind_virq);
+ COPY_BACK(bind_pirq);
+ COPY_BACK(status);
+ COPY_BACK(alloc_unbound);
+ COPY_BACK(bind_ipi);
+#undef COPY_BACK
+
+ default:
+ WARN_ON(rc != -ENOSYS);
+ break;
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(xen_event_channel_op_compat);
+
+int HYPERVISOR_physdev_op_compat(int cmd, void *arg)
+{
+ struct physdev_op op;
+ int rc;
+
+ op.cmd = cmd;
+ memcpy(&op.u, arg, sizeof(op.u));
+ rc = _hypercall1(int, physdev_op_compat, &op);
+
+ switch (cmd) {
+ case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
+ case PHYSDEVOP_set_iopl:
+ case PHYSDEVOP_set_iobitmap:
+ case PHYSDEVOP_apic_write:
+ /* no output */
+ break;
+
+#define COPY_BACK(pop, fld) \
+ case PHYSDEVOP_##pop: \
+ memcpy(arg, &op.u.fld, sizeof(op.u.fld)); \
+ break
+
+ COPY_BACK(irq_status_query, irq_status_query);
+ COPY_BACK(apic_read, apic_op);
+ COPY_BACK(ASSIGN_VECTOR, irq_op);
+#undef COPY_BACK
+
+ default:
+ WARN_ON(rc != -ENOSYS);
+ break;
+ }
+
+ return rc;
+}
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index 8adb9cc267f..71f5c459b08 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -361,13 +361,13 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
down_write(&mm->mmap_sem);
vma = find_vma(mm, m.addr);
- ret = -EINVAL;
if (!vma ||
vma->vm_ops != &privcmd_vm_ops ||
(m.addr != vma->vm_start) ||
((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) ||
!privcmd_enforce_singleshot_mapping(vma)) {
up_write(&mm->mmap_sem);
+ ret = -EINVAL;
goto out;
}
@@ -383,12 +383,16 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
up_write(&mm->mmap_sem);
- if (state.global_error && (version == 1)) {
- /* Write back errors in second pass. */
- state.user_mfn = (xen_pfn_t *)m.arr;
- state.err = err_array;
- ret = traverse_pages(m.num, sizeof(xen_pfn_t),
- &pagelist, mmap_return_errors_v1, &state);
+ if (version == 1) {
+ if (state.global_error) {
+ /* Write back errors in second pass. */
+ state.user_mfn = (xen_pfn_t *)m.arr;
+ state.err = err_array;
+ ret = traverse_pages(m.num, sizeof(xen_pfn_t),
+ &pagelist, mmap_return_errors_v1, &state);
+ } else
+ ret = 0;
+
} else if (version == 2) {
ret = __copy_to_user(m.err, err_array, m.num * sizeof(int));
if (ret)
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index fc783e26442..0fb15bbbe43 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -225,6 +225,13 @@ sid_to_str(struct cifs_sid *sidptr, char *sidstr)
}
static void
+cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
+{
+ memcpy(dst, src, sizeof(*dst));
+ dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS);
+}
+
+static void
id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
struct cifs_sid_id **psidid, char *typestr)
{
@@ -248,7 +255,7 @@ id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
}
}
- memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid));
+ cifs_copy_sid(&(*psidid)->sid, sidptr);
(*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
(*psidid)->refcount = 0;
@@ -354,7 +361,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
* any fields of the node after a reference is put .
*/
if (test_bit(SID_ID_MAPPED, &psidid->state)) {
- memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
+ cifs_copy_sid(ssid, &psidid->sid);
psidid->time = jiffies; /* update ts for accessing */
goto id_sid_out;
}
@@ -370,14 +377,14 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
if (IS_ERR(sidkey)) {
rc = -EINVAL;
cFYI(1, "%s: Can't map and id to a SID", __func__);
+ } else if (sidkey->datalen < sizeof(struct cifs_sid)) {
+ rc = -EIO;
+ cFYI(1, "%s: Downcall contained malformed key "
+ "(datalen=%hu)", __func__, sidkey->datalen);
} else {
lsid = (struct cifs_sid *)sidkey->payload.data;
- memcpy(&psidid->sid, lsid,
- sidkey->datalen < sizeof(struct cifs_sid) ?
- sidkey->datalen : sizeof(struct cifs_sid));
- memcpy(ssid, &psidid->sid,
- sidkey->datalen < sizeof(struct cifs_sid) ?
- sidkey->datalen : sizeof(struct cifs_sid));
+ cifs_copy_sid(&psidid->sid, lsid);
+ cifs_copy_sid(ssid, &psidid->sid);
set_bit(SID_ID_MAPPED, &psidid->state);
key_put(sidkey);
kfree(psidid->sidstr);
@@ -396,7 +403,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
return rc;
}
if (test_bit(SID_ID_MAPPED, &psidid->state))
- memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
+ cifs_copy_sid(ssid, &psidid->sid);
else
rc = -EINVAL;
}
@@ -675,8 +682,6 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
static void copy_sec_desc(const struct cifs_ntsd *pntsd,
struct cifs_ntsd *pnntsd, __u32 sidsoffset)
{
- int i;
-
struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
@@ -692,26 +697,14 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd,
owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
le32_to_cpu(pntsd->osidoffset));
nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
-
- nowner_sid_ptr->revision = owner_sid_ptr->revision;
- nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
- for (i = 0; i < 6; i++)
- nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
- for (i = 0; i < 5; i++)
- nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
+ cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
/* copy group sid */
group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
le32_to_cpu(pntsd->gsidoffset));
ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
sizeof(struct cifs_sid));
-
- ngroup_sid_ptr->revision = group_sid_ptr->revision;
- ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
- for (i = 0; i < 6; i++)
- ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
- for (i = 0; i < 5; i++)
- ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
+ cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
return;
}
@@ -1120,8 +1113,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
kfree(nowner_sid_ptr);
return rc;
}
- memcpy(owner_sid_ptr, nowner_sid_ptr,
- sizeof(struct cifs_sid));
+ cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
kfree(nowner_sid_ptr);
*aclflag = CIFS_ACL_OWNER;
}
@@ -1139,8 +1131,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
kfree(ngroup_sid_ptr);
return rc;
}
- memcpy(group_sid_ptr, ngroup_sid_ptr,
- sizeof(struct cifs_sid));
+ cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
kfree(ngroup_sid_ptr);
*aclflag = CIFS_ACL_GROUP;
}
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 7c0a8128364..d3671f2acb2 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -398,7 +398,16 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
* in network traffic in the other paths.
*/
if (!(oflags & O_CREAT)) {
- struct dentry *res = cifs_lookup(inode, direntry, 0);
+ struct dentry *res;
+
+ /*
+ * Check for hashed negative dentry. We have already revalidated
+ * the dentry and it is fine. No need to perform another lookup.
+ */
+ if (!d_unhashed(direntry))
+ return -ENOENT;
+
+ res = cifs_lookup(inode, direntry, 0);
if (IS_ERR(res))
return PTR_ERR(res);
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index da72250ddc1..cd96649bfe6 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -346,7 +346,7 @@ static inline struct epitem *ep_item_from_epqueue(poll_table *p)
/* Tells if the epoll_ctl(2) operation needs an event copy from userspace */
static inline int ep_op_has_event(int op)
{
- return op == EPOLL_CTL_ADD || op == EPOLL_CTL_MOD;
+ return op != EPOLL_CTL_DEL;
}
/* Initialize the poll safe wake up structure */
@@ -676,34 +676,6 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
return 0;
}
-/*
- * Disables a "struct epitem" in the eventpoll set. Returns -EBUSY if the item
- * had no event flags set, indicating that another thread may be currently
- * handling that item's events (in the case that EPOLLONESHOT was being
- * used). Otherwise a zero result indicates that the item has been disabled
- * from receiving events. A disabled item may be re-enabled via
- * EPOLL_CTL_MOD. Must be called with "mtx" held.
- */
-static int ep_disable(struct eventpoll *ep, struct epitem *epi)
-{
- int result = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&ep->lock, flags);
- if (epi->event.events & ~EP_PRIVATE_BITS) {
- if (ep_is_linked(&epi->rdllink))
- list_del_init(&epi->rdllink);
- /* Ensure ep_poll_callback will not add epi back onto ready
- list: */
- epi->event.events &= EP_PRIVATE_BITS;
- }
- else
- result = -EBUSY;
- spin_unlock_irqrestore(&ep->lock, flags);
-
- return result;
-}
-
static void ep_free(struct eventpoll *ep)
{
struct rb_node *rbp;
@@ -1048,6 +1020,8 @@ static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi)
rb_insert_color(&epi->rbn, &ep->rbr);
}
+
+
#define PATH_ARR_SIZE 5
/*
* These are the number paths of length 1 to 5, that we are allowing to emanate
@@ -1813,12 +1787,6 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
} else
error = -ENOENT;
break;
- case EPOLL_CTL_DISABLE:
- if (epi)
- error = ep_disable(ep, epi);
- else
- error = -ENOENT;
- break;
}
mutex_unlock(&ep->mtx);
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 7320a66e958..22548f56197 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -2101,8 +2101,9 @@ int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range)
end = start + (range->len >> sb->s_blocksize_bits) - 1;
minlen = range->minlen >> sb->s_blocksize_bits;
- if (unlikely(minlen > EXT3_BLOCKS_PER_GROUP(sb)) ||
- unlikely(start >= max_blks))
+ if (minlen > EXT3_BLOCKS_PER_GROUP(sb) ||
+ start >= max_blks ||
+ range->len < sb->s_blocksize)
return -EINVAL;
if (end >= max_blks)
end = max_blks - 1;
diff --git a/fs/file.c b/fs/file.c
index 708d997a774..7cb71b99260 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -685,7 +685,6 @@ void do_close_on_exec(struct files_struct *files)
struct fdtable *fdt;
/* exec unshares first */
- BUG_ON(atomic_read(&files->count) != 1);
spin_lock(&files->file_lock);
for (i = 0; ; i++) {
unsigned long set;
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 0def0504afc..e056b4ce487 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -516,15 +516,13 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
struct gfs2_holder i_gh;
int error;
- gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
- error = gfs2_glock_nq(&i_gh);
- if (error == 0) {
- file_accessed(file);
- gfs2_glock_dq(&i_gh);
- }
- gfs2_holder_uninit(&i_gh);
+ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,
+ &i_gh);
if (error)
return error;
+ /* grab lock to update inode */
+ gfs2_glock_dq_uninit(&i_gh);
+ file_accessed(file);
}
vma->vm_ops = &gfs2_vm_ops;
@@ -677,10 +675,8 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
size_t writesize = iov_length(iov, nr_segs);
struct dentry *dentry = file->f_dentry;
struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
- struct gfs2_sbd *sdp;
int ret;
- sdp = GFS2_SB(file->f_mapping->host);
ret = gfs2_rs_alloc(ip);
if (ret)
return ret;
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 8ff95a2d54e..9ceccb1595a 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -393,12 +393,10 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
struct gfs2_meta_header *mh;
struct gfs2_trans *tr;
- lock_buffer(bd->bd_bh);
- gfs2_log_lock(sdp);
tr = current->journal_info;
tr->tr_touched = 1;
if (!list_empty(&bd->bd_list))
- goto out;
+ return;
set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
mh = (struct gfs2_meta_header *)bd->bd_bh->b_data;
@@ -414,9 +412,6 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
sdp->sd_log_num_buf++;
list_add(&bd->bd_list, &sdp->sd_log_le_buf);
tr->tr_num_buf_new++;
-out:
- gfs2_log_unlock(sdp);
- unlock_buffer(bd->bd_bh);
}
static void gfs2_check_magic(struct buffer_head *bh)
@@ -621,7 +616,6 @@ static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
{
- struct gfs2_log_descriptor *ld;
struct gfs2_meta_header *mh;
unsigned int offset;
struct list_head *head = &sdp->sd_log_le_revoke;
@@ -634,7 +628,6 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
length = gfs2_struct2blk(sdp, sdp->sd_log_num_revoke, sizeof(u64));
page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE, length, sdp->sd_log_num_revoke);
- ld = page_address(page);
offset = sizeof(struct gfs2_log_descriptor);
list_for_each_entry(bd, head, bd_list) {
@@ -777,12 +770,10 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
struct address_space *mapping = bd->bd_bh->b_page->mapping;
struct gfs2_inode *ip = GFS2_I(mapping->host);
- lock_buffer(bd->bd_bh);
- gfs2_log_lock(sdp);
if (tr)
tr->tr_touched = 1;
if (!list_empty(&bd->bd_list))
- goto out;
+ return;
set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
if (gfs2_is_jdata(ip)) {
@@ -793,9 +784,6 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
} else {
list_add_tail(&bd->bd_list, &sdp->sd_log_le_ordered);
}
-out:
- gfs2_log_unlock(sdp);
- unlock_buffer(bd->bd_bh);
}
/**
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 40c4b0d42fa..c5af8e18f27 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -497,8 +497,11 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
struct gfs2_quota_data **qd;
int error;
- if (ip->i_res == NULL)
- gfs2_rs_alloc(ip);
+ if (ip->i_res == NULL) {
+ error = gfs2_rs_alloc(ip);
+ if (error)
+ return error;
+ }
qd = ip->i_res->rs_qa_qd;
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 3cc402ce6fe..38fe18f2f05 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -553,7 +553,6 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd)
*/
int gfs2_rs_alloc(struct gfs2_inode *ip)
{
- int error = 0;
struct gfs2_blkreserv *res;
if (ip->i_res)
@@ -561,7 +560,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip)
res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS);
if (!res)
- error = -ENOMEM;
+ return -ENOMEM;
RB_CLEAR_NODE(&res->rs_node);
@@ -571,7 +570,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip)
else
ip->i_res = res;
up_write(&ip->i_rw_mutex);
- return error;
+ return 0;
}
static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs)
@@ -1263,7 +1262,9 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
int ret = 0;
u64 amt;
u64 trimmed = 0;
+ u64 start, end, minlen;
unsigned int x;
+ unsigned bs_shift = sdp->sd_sb.sb_bsize_shift;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -1271,19 +1272,25 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
if (!blk_queue_discard(q))
return -EOPNOTSUPP;
- if (argp == NULL) {
- r.start = 0;
- r.len = ULLONG_MAX;
- r.minlen = 0;
- } else if (copy_from_user(&r, argp, sizeof(r)))
+ if (copy_from_user(&r, argp, sizeof(r)))
return -EFAULT;
ret = gfs2_rindex_update(sdp);
if (ret)
return ret;
- rgd = gfs2_blk2rgrpd(sdp, r.start, 0);
- rgd_end = gfs2_blk2rgrpd(sdp, r.start + r.len, 0);
+ start = r.start >> bs_shift;
+ end = start + (r.len >> bs_shift);
+ minlen = max_t(u64, r.minlen,
+ q->limits.discard_granularity) >> bs_shift;
+
+ rgd = gfs2_blk2rgrpd(sdp, start, 0);
+ rgd_end = gfs2_blk2rgrpd(sdp, end - 1, 0);
+
+ if (end <= start ||
+ minlen > sdp->sd_max_rg_data ||
+ start > rgd_end->rd_data0 + rgd_end->rd_data)
+ return -EINVAL;
while (1) {
@@ -1295,7 +1302,9 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
/* Trim each bitmap in the rgrp */
for (x = 0; x < rgd->rd_length; x++) {
struct gfs2_bitmap *bi = rgd->rd_bits + x;
- ret = gfs2_rgrp_send_discards(sdp, rgd->rd_data0, NULL, bi, r.minlen, &amt);
+ ret = gfs2_rgrp_send_discards(sdp,
+ rgd->rd_data0, NULL, bi, minlen,
+ &amt);
if (ret) {
gfs2_glock_dq_uninit(&gh);
goto out;
@@ -1324,7 +1333,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
out:
r.len = trimmed << 9;
- if (argp && copy_to_user(argp, &r, sizeof(r)))
+ if (copy_to_user(argp, &r, sizeof(r)))
return -EFAULT;
return ret;
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index bc737261f23..d6488674d91 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -810,7 +810,8 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
return;
}
need_unlock = 1;
- }
+ } else if (WARN_ON_ONCE(ip->i_gl->gl_state != LM_ST_EXCLUSIVE))
+ return;
if (current->journal_info == NULL) {
ret = gfs2_trans_begin(sdp, RES_DINODE, 0);
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
index adbd27875ef..413627072f3 100644
--- a/fs/gfs2/trans.c
+++ b/fs/gfs2/trans.c
@@ -155,14 +155,22 @@ void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta)
struct gfs2_sbd *sdp = gl->gl_sbd;
struct gfs2_bufdata *bd;
+ lock_buffer(bh);
+ gfs2_log_lock(sdp);
bd = bh->b_private;
if (bd)
gfs2_assert(sdp, bd->bd_gl == gl);
else {
+ gfs2_log_unlock(sdp);
+ unlock_buffer(bh);
gfs2_attach_bufdata(gl, bh, meta);
bd = bh->b_private;
+ lock_buffer(bh);
+ gfs2_log_lock(sdp);
}
lops_add(sdp, bd);
+ gfs2_log_unlock(sdp);
+ unlock_buffer(bh);
}
void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index f35794b97e8..a5063602536 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -21,6 +21,7 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new)
if ((old->path.mnt == new->path.mnt) &&
(old->path.dentry == new->path.dentry))
return true;
+ break;
case (FSNOTIFY_EVENT_NONE):
return true;
default:
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 721d692fa8d..6fcaeb8c902 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -258,7 +258,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
if (ret)
goto out_close_fd;
- fd_install(fd, f);
+ if (fd != FAN_NOFD)
+ fd_install(fd, f);
return fanotify_event_metadata.event_len;
out_close_fd:
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 144a96732dd..3c231adf845 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -873,6 +873,113 @@ static const struct file_operations proc_environ_operations = {
.release = mem_release,
};
+static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
+ char buffer[PROC_NUMBUF];
+ int oom_adj = OOM_ADJUST_MIN;
+ size_t len;
+ unsigned long flags;
+
+ if (!task)
+ return -ESRCH;
+ if (lock_task_sighand(task, &flags)) {
+ if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX)
+ oom_adj = OOM_ADJUST_MAX;
+ else
+ oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) /
+ OOM_SCORE_ADJ_MAX;
+ unlock_task_sighand(task, &flags);
+ }
+ put_task_struct(task);
+ len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj);
+ return simple_read_from_buffer(buf, count, ppos, buffer, len);
+}
+
+static ssize_t oom_adj_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct task_struct *task;
+ char buffer[PROC_NUMBUF];
+ int oom_adj;
+ unsigned long flags;
+ int err;
+
+ memset(buffer, 0, sizeof(buffer));
+ if (count > sizeof(buffer) - 1)
+ count = sizeof(buffer) - 1;
+ if (copy_from_user(buffer, buf, count)) {
+ err = -EFAULT;
+ goto out;
+ }
+
+ err = kstrtoint(strstrip(buffer), 0, &oom_adj);
+ if (err)
+ goto out;
+ if ((oom_adj < OOM_ADJUST_MIN || oom_adj > OOM_ADJUST_MAX) &&
+ oom_adj != OOM_DISABLE) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ task = get_proc_task(file->f_path.dentry->d_inode);
+ if (!task) {
+ err = -ESRCH;
+ goto out;
+ }
+
+ task_lock(task);
+ if (!task->mm) {
+ err = -EINVAL;
+ goto err_task_lock;
+ }
+
+ if (!lock_task_sighand(task, &flags)) {
+ err = -ESRCH;
+ goto err_task_lock;
+ }
+
+ /*
+ * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum
+ * value is always attainable.
+ */
+ if (oom_adj == OOM_ADJUST_MAX)
+ oom_adj = OOM_SCORE_ADJ_MAX;
+ else
+ oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
+
+ if (oom_adj < task->signal->oom_score_adj &&
+ !capable(CAP_SYS_RESOURCE)) {
+ err = -EACCES;
+ goto err_sighand;
+ }
+
+ /*
+ * /proc/pid/oom_adj is provided for legacy purposes, ask users to use
+ * /proc/pid/oom_score_adj instead.
+ */
+ printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n",
+ current->comm, task_pid_nr(current), task_pid_nr(task),
+ task_pid_nr(task));
+
+ task->signal->oom_score_adj = oom_adj;
+ trace_oom_score_adj_update(task);
+err_sighand:
+ unlock_task_sighand(task, &flags);
+err_task_lock:
+ task_unlock(task);
+ put_task_struct(task);
+out:
+ return err < 0 ? err : count;
+}
+
+static const struct file_operations proc_oom_adj_operations = {
+ .read = oom_adj_read,
+ .write = oom_adj_write,
+ .llseek = generic_file_llseek,
+};
+
static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
@@ -2598,6 +2705,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("cgroup", S_IRUGO, proc_cgroup_operations),
#endif
INF("oom_score", S_IRUGO, proc_oom_score),
+ REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
#ifdef CONFIG_AUDITSYSCALL
REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
@@ -2964,6 +3072,7 @@ static const struct pid_entry tid_base_stuff[] = {
REG("cgroup", S_IRUGO, proc_cgroup_operations),
#endif
INF("oom_score", S_IRUGO, proc_oom_score),
+ REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
#ifdef CONFIG_AUDITSYSCALL
REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index a40da07e93d..947fbe06c3b 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -161,6 +161,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
while (s < e) {
unsigned long flags;
+ u64 id;
if (c > psinfo->bufsize)
c = psinfo->bufsize;
@@ -172,7 +173,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
spin_lock_irqsave(&psinfo->buf_lock, flags);
}
memcpy(psinfo->buf, s, c);
- psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo);
+ psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo);
spin_unlock_irqrestore(&psinfo->buf_lock, flags);
s += c;
c = e - s;
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index f27f01a98aa..d83736fbc26 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1782,8 +1782,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
BUG_ON(!th->t_trans_id);
- dquot_initialize(inode);
+ reiserfs_write_unlock(inode->i_sb);
err = dquot_alloc_inode(inode);
+ reiserfs_write_lock(inode->i_sb);
if (err)
goto out_end_trans;
if (!dir->i_nlink) {
@@ -1979,8 +1980,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
out_end_trans:
journal_end(th, th->t_super, th->t_blocks_allocated);
+ reiserfs_write_unlock(inode->i_sb);
/* Drop can be outside and it needs more credits so it's better to have it outside */
dquot_drop(inode);
+ reiserfs_write_lock(inode->i_sb);
inode->i_flags |= S_NOQUOTA;
make_bad_inode(inode);
@@ -3103,10 +3106,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
/* must be turned off for recursive notify_change calls */
ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
- depth = reiserfs_write_lock_once(inode->i_sb);
if (is_quota_modification(inode, attr))
dquot_initialize(inode);
-
+ depth = reiserfs_write_lock_once(inode->i_sb);
if (attr->ia_valid & ATTR_SIZE) {
/* version 2 items will be caught by the s_maxbytes check
** done for us in vmtruncate
@@ -3170,7 +3172,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
error = journal_begin(&th, inode->i_sb, jbegin_count);
if (error)
goto out;
+ reiserfs_write_unlock_once(inode->i_sb, depth);
error = dquot_transfer(inode, attr);
+ depth = reiserfs_write_lock_once(inode->i_sb);
if (error) {
journal_end(&th, inode->i_sb, jbegin_count);
goto out;
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index f8afa4b162b..2f40a4c70a4 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -1968,7 +1968,9 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree
key2type(&(key->on_disk_key)));
#endif
+ reiserfs_write_unlock(inode->i_sb);
retval = dquot_alloc_space_nodirty(inode, pasted_size);
+ reiserfs_write_lock(inode->i_sb);
if (retval) {
pathrelse(search_path);
return retval;
@@ -2061,9 +2063,11 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th,
"reiserquota insert_item(): allocating %u id=%u type=%c",
quota_bytes, inode->i_uid, head2type(ih));
#endif
+ reiserfs_write_unlock(inode->i_sb);
/* We can't dirty inode here. It would be immediately written but
* appropriate stat item isn't inserted yet... */
retval = dquot_alloc_space_nodirty(inode, quota_bytes);
+ reiserfs_write_lock(inode->i_sb);
if (retval) {
pathrelse(path);
return retval;
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 1078ae17999..418bdc3a57d 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -298,7 +298,9 @@ static int finish_unfinished(struct super_block *s)
retval = remove_save_link_only(s, &save_link_key, 0);
continue;
}
+ reiserfs_write_unlock(s);
dquot_initialize(inode);
+ reiserfs_write_lock(s);
if (truncate && S_ISDIR(inode->i_mode)) {
/* We got a truncate request for a dir which is impossible.
@@ -1335,7 +1337,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
kfree(qf_names[i]);
#endif
err = -EINVAL;
- goto out_err;
+ goto out_unlock;
}
#ifdef CONFIG_QUOTA
handle_quota_files(s, qf_names, &qfmt);
@@ -1379,7 +1381,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
if (blocks) {
err = reiserfs_resize(s, blocks);
if (err != 0)
- goto out_err;
+ goto out_unlock;
}
if (*mount_flags & MS_RDONLY) {
@@ -1389,9 +1391,15 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
/* it is read-only already */
goto out_ok;
+ /*
+ * Drop write lock. Quota will retake it when needed and lock
+ * ordering requires calling dquot_suspend() without it.
+ */
+ reiserfs_write_unlock(s);
err = dquot_suspend(s, -1);
if (err < 0)
goto out_err;
+ reiserfs_write_lock(s);
/* try to remount file system with read-only permissions */
if (sb_umount_state(rs) == REISERFS_VALID_FS
@@ -1401,7 +1409,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
err = journal_begin(&th, s, 10);
if (err)
- goto out_err;
+ goto out_unlock;
/* Mounting a rw partition read-only. */
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
@@ -1416,7 +1424,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
if (reiserfs_is_journal_aborted(journal)) {
err = journal->j_errno;
- goto out_err;
+ goto out_unlock;
}
handle_data_mode(s, mount_options);
@@ -1425,7 +1433,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */
err = journal_begin(&th, s, 10);
if (err)
- goto out_err;
+ goto out_unlock;
/* Mount a partition which is read-only, read-write */
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
@@ -1442,10 +1450,16 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
SB_JOURNAL(s)->j_must_wait = 1;
err = journal_end(&th, s, 10);
if (err)
- goto out_err;
+ goto out_unlock;
if (!(*mount_flags & MS_RDONLY)) {
+ /*
+ * Drop write lock. Quota will retake it when needed and lock
+ * ordering requires calling dquot_resume() without it.
+ */
+ reiserfs_write_unlock(s);
dquot_resume(s, -1);
+ reiserfs_write_lock(s);
finish_unfinished(s);
reiserfs_xattr_init(s, *mount_flags);
}
@@ -1455,9 +1469,10 @@ out_ok:
reiserfs_write_unlock(s);
return 0;
+out_unlock:
+ reiserfs_write_unlock(s);
out_err:
kfree(new_opts);
- reiserfs_write_unlock(s);
return err;
}
@@ -2095,13 +2110,15 @@ static int reiserfs_write_dquot(struct dquot *dquot)
REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
if (ret)
goto out;
+ reiserfs_write_unlock(dquot->dq_sb);
ret = dquot_commit(dquot);
+ reiserfs_write_lock(dquot->dq_sb);
err =
journal_end(&th, dquot->dq_sb,
REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
if (!ret && err)
ret = err;
- out:
+out:
reiserfs_write_unlock(dquot->dq_sb);
return ret;
}
@@ -2117,13 +2134,15 @@ static int reiserfs_acquire_dquot(struct dquot *dquot)
REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
if (ret)
goto out;
+ reiserfs_write_unlock(dquot->dq_sb);
ret = dquot_acquire(dquot);
+ reiserfs_write_lock(dquot->dq_sb);
err =
journal_end(&th, dquot->dq_sb,
REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
if (!ret && err)
ret = err;
- out:
+out:
reiserfs_write_unlock(dquot->dq_sb);
return ret;
}
@@ -2137,19 +2156,21 @@ static int reiserfs_release_dquot(struct dquot *dquot)
ret =
journal_begin(&th, dquot->dq_sb,
REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
+ reiserfs_write_unlock(dquot->dq_sb);
if (ret) {
/* Release dquot anyway to avoid endless cycle in dqput() */
dquot_release(dquot);
goto out;
}
ret = dquot_release(dquot);
+ reiserfs_write_lock(dquot->dq_sb);
err =
journal_end(&th, dquot->dq_sb,
REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
if (!ret && err)
ret = err;
- out:
reiserfs_write_unlock(dquot->dq_sb);
+out:
return ret;
}
@@ -2174,11 +2195,13 @@ static int reiserfs_write_info(struct super_block *sb, int type)
ret = journal_begin(&th, sb, 2);
if (ret)
goto out;
+ reiserfs_write_unlock(sb);
ret = dquot_commit_info(sb, type);
+ reiserfs_write_lock(sb);
err = journal_end(&th, sb, 2);
if (!ret && err)
ret = err;
- out:
+out:
reiserfs_write_unlock(sb);
return ret;
}
@@ -2203,8 +2226,11 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
struct reiserfs_transaction_handle th;
int opt = type == USRQUOTA ? REISERFS_USRQUOTA : REISERFS_GRPQUOTA;
- if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt)))
- return -EINVAL;
+ reiserfs_write_lock(sb);
+ if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt))) {
+ err = -EINVAL;
+ goto out;
+ }
/* Quotafile not on the same filesystem? */
if (path->dentry->d_sb != sb) {
@@ -2246,8 +2272,10 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
if (err)
goto out;
}
- err = dquot_quota_on(sb, type, format_id, path);
+ reiserfs_write_unlock(sb);
+ return dquot_quota_on(sb, type, format_id, path);
out:
+ reiserfs_write_unlock(sb);
return err;
}
@@ -2320,7 +2348,9 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
tocopy = sb->s_blocksize - offset < towrite ?
sb->s_blocksize - offset : towrite;
tmp_bh.b_state = 0;
+ reiserfs_write_lock(sb);
err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE);
+ reiserfs_write_unlock(sb);
if (err)
goto out;
if (offset || tocopy != sb->s_blocksize)
@@ -2336,10 +2366,12 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
flush_dcache_page(bh->b_page);
set_buffer_uptodate(bh);
unlock_buffer(bh);
+ reiserfs_write_lock(sb);
reiserfs_prepare_for_journal(sb, bh, 1);
journal_mark_dirty(current->journal_info, sb, bh);
if (!journal_quota)
reiserfs_add_ordered_list(inode, bh);
+ reiserfs_write_unlock(sb);
brelse(bh);
offset = 0;
towrite -= tocopy;
diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c
index 28ec13af28d..2dcf3d473fe 100644
--- a/fs/ubifs/find.c
+++ b/fs/ubifs/find.c
@@ -681,8 +681,16 @@ int ubifs_find_free_leb_for_idx(struct ubifs_info *c)
if (!lprops) {
lprops = ubifs_fast_find_freeable(c);
if (!lprops) {
- ubifs_assert(c->freeable_cnt == 0);
- if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
+ /*
+ * The first condition means the following: go scan the
+ * LPT if there are uncategorized lprops, which means
+ * there may be freeable LEBs there (UBIFS does not
+ * store the information about freeable LEBs in the
+ * master node).
+ */
+ if (c->in_a_category_cnt != c->main_lebs ||
+ c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
+ ubifs_assert(c->freeable_cnt == 0);
lprops = scan_for_leb_for_idx(c);
if (IS_ERR(lprops)) {
err = PTR_ERR(lprops);
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
index e5a2a35a46d..46190a7c42a 100644
--- a/fs/ubifs/lprops.c
+++ b/fs/ubifs/lprops.c
@@ -300,8 +300,11 @@ void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops,
default:
ubifs_assert(0);
}
+
lprops->flags &= ~LPROPS_CAT_MASK;
lprops->flags |= cat;
+ c->in_a_category_cnt += 1;
+ ubifs_assert(c->in_a_category_cnt <= c->main_lebs);
}
/**
@@ -334,6 +337,9 @@ static void ubifs_remove_from_cat(struct ubifs_info *c,
default:
ubifs_assert(0);
}
+
+ c->in_a_category_cnt -= 1;
+ ubifs_assert(c->in_a_category_cnt >= 0);
}
/**
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 5486346d0a3..d133c276fe0 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1183,6 +1183,8 @@ struct ubifs_debug_info;
* @freeable_list: list of freeable non-index LEBs (free + dirty == @leb_size)
* @frdi_idx_list: list of freeable index LEBs (free + dirty == @leb_size)
* @freeable_cnt: number of freeable LEBs in @freeable_list
+ * @in_a_category_cnt: count of lprops which are in a certain category, which
+ * basically meants that they were loaded from the flash
*
* @ltab_lnum: LEB number of LPT's own lprops table
* @ltab_offs: offset of LPT's own lprops table
@@ -1412,6 +1414,7 @@ struct ubifs_info {
struct list_head freeable_list;
struct list_head frdi_idx_list;
int freeable_cnt;
+ int in_a_category_cnt;
int ltab_lnum;
int ltab_offs;
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 4f33c32affe..335206a9c69 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -1866,6 +1866,7 @@ xfs_alloc_fix_freelist(
/*
* Initialize the args structure.
*/
+ memset(&targs, 0, sizeof(targs));
targs.tp = tp;
targs.mp = mp;
targs.agbp = agbp;
@@ -2207,7 +2208,7 @@ xfs_alloc_read_agf(
* group or loop over the allocation groups to find the result.
*/
int /* error */
-__xfs_alloc_vextent(
+xfs_alloc_vextent(
xfs_alloc_arg_t *args) /* allocation argument structure */
{
xfs_agblock_t agsize; /* allocation group size */
@@ -2417,46 +2418,6 @@ error0:
return error;
}
-static void
-xfs_alloc_vextent_worker(
- struct work_struct *work)
-{
- struct xfs_alloc_arg *args = container_of(work,
- struct xfs_alloc_arg, work);
- unsigned long pflags;
-
- /* we are in a transaction context here */
- current_set_flags_nested(&pflags, PF_FSTRANS);
-
- args->result = __xfs_alloc_vextent(args);
- complete(args->done);
-
- current_restore_flags_nested(&pflags, PF_FSTRANS);
-}
-
-/*
- * Data allocation requests often come in with little stack to work on. Push
- * them off to a worker thread so there is lots of stack to use. Metadata
- * requests, OTOH, are generally from low stack usage paths, so avoid the
- * context switch overhead here.
- */
-int
-xfs_alloc_vextent(
- struct xfs_alloc_arg *args)
-{
- DECLARE_COMPLETION_ONSTACK(done);
-
- if (!args->userdata)
- return __xfs_alloc_vextent(args);
-
-
- args->done = &done;
- INIT_WORK_ONSTACK(&args->work, xfs_alloc_vextent_worker);
- queue_work(xfs_alloc_wq, &args->work);
- wait_for_completion(&done);
- return args->result;
-}
-
/*
* Free an extent.
* Just break up the extent address and hand off to xfs_free_ag_extent
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
index 93be4a667ca..feacb061bab 100644
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -120,9 +120,6 @@ typedef struct xfs_alloc_arg {
char isfl; /* set if is freelist blocks - !acctg */
char userdata; /* set if this is user data */
xfs_fsblock_t firstblock; /* io first block allocated */
- struct completion *done;
- struct work_struct work;
- int result;
} xfs_alloc_arg_t;
/*
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index f1647caace8..f7876c6d616 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -121,6 +121,8 @@ xfs_allocbt_free_block(
xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1,
XFS_EXTENT_BUSY_SKIP_DISCARD);
xfs_trans_agbtree_delta(cur->bc_tp, -1);
+
+ xfs_trans_binval(cur->bc_tp, bp);
return 0;
}
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index e562dd43f41..e57e2daa357 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -481,11 +481,17 @@ static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh)
*
* The fix is two passes across the ioend list - one to start writeback on the
* buffer_heads, and then submit them for I/O on the second pass.
+ *
+ * If @fail is non-zero, it means that we have a situation where some part of
+ * the submission process has failed after we have marked paged for writeback
+ * and unlocked them. In this situation, we need to fail the ioend chain rather
+ * than submit it to IO. This typically only happens on a filesystem shutdown.
*/
STATIC void
xfs_submit_ioend(
struct writeback_control *wbc,
- xfs_ioend_t *ioend)
+ xfs_ioend_t *ioend,
+ int fail)
{
xfs_ioend_t *head = ioend;
xfs_ioend_t *next;
@@ -506,6 +512,18 @@ xfs_submit_ioend(
next = ioend->io_list;
bio = NULL;
+ /*
+ * If we are failing the IO now, just mark the ioend with an
+ * error and finish it. This will run IO completion immediately
+ * as there is only one reference to the ioend at this point in
+ * time.
+ */
+ if (fail) {
+ ioend->io_error = -fail;
+ xfs_finish_ioend(ioend);
+ continue;
+ }
+
for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) {
if (!bio) {
@@ -1060,7 +1078,18 @@ xfs_vm_writepage(
xfs_start_page_writeback(page, 1, count);
- if (ioend && imap_valid) {
+ /* if there is no IO to be submitted for this page, we are done */
+ if (!ioend)
+ return 0;
+
+ ASSERT(iohead);
+
+ /*
+ * Any errors from this point onwards need tobe reported through the IO
+ * completion path as we have marked the initial page as under writeback
+ * and unlocked it.
+ */
+ if (imap_valid) {
xfs_off_t end_index;
end_index = imap.br_startoff + imap.br_blockcount;
@@ -1079,20 +1108,15 @@ xfs_vm_writepage(
wbc, end_index);
}
- if (iohead) {
- /*
- * Reserve log space if we might write beyond the on-disk
- * inode size.
- */
- if (ioend->io_type != XFS_IO_UNWRITTEN &&
- xfs_ioend_is_append(ioend)) {
- err = xfs_setfilesize_trans_alloc(ioend);
- if (err)
- goto error;
- }
- xfs_submit_ioend(wbc, iohead);
- }
+ /*
+ * Reserve log space if we might write beyond the on-disk inode size.
+ */
+ err = 0;
+ if (ioend->io_type != XFS_IO_UNWRITTEN && xfs_ioend_is_append(ioend))
+ err = xfs_setfilesize_trans_alloc(ioend);
+
+ xfs_submit_ioend(wbc, iohead, err);
return 0;
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index d330111ca73..70eec182977 100644