Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 13 Apr 2016 15:53:26 +0000 (08:53 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 13 Apr 2016 15:53:26 +0000 (08:53 -0700)
Pull KVM fixes from Radim Krčmář:
 "ARM fixes:
   - Wrong indentation in the PMU code from the merge window
   - A long-time bug occuring with running ntpd on the host, candidate
     for stable
   - Properly handle (and warn about) the unsupported configuration of
     running on systems with less than 40 bits of PA space
   - More fixes to the PM and hotplug notifier stuff from the merge
     window

  x86:
   - leak of guest xcr0 (typically shows up as SIGILL)
   - new maintainer (who is sending the pull request too)
   - fix for merge window regression
   - fix for guest CPUID"

Paolo Bonzini points out:
 "For the record, this tag is signed by me because I prepared the pull
  request.  Further pull requests for 4.6 will be signed and sent out by
  Radim directly"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: x86: mask CPUID(0xD,0x1).EAX against host value
  kvm: x86: do not leak guest xcr0 into host interrupt handlers
  KVM: MMU: fix permission_fault()
  KVM: new maintainer on the block
  arm64: KVM: unregister notifiers in hyp mode teardown path
  arm64: KVM: Warn when PARange is less than 40 bits
  KVM: arm/arm64: Handle forward time correction gracefully
  arm64: KVM: Add braces to multi-line if statement in virtual PMU code

243 files changed:
Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl
Documentation/power/runtime_pm.txt
MAINTAINERS
Makefile
arch/arc/Kconfig
arch/arc/boot/dts/axs10x_mb.dtsi
arch/arc/configs/axs103_defconfig
arch/arc/configs/axs103_smp_defconfig
arch/arc/include/asm/fb.h [new file with mode: 0644]
arch/arm/include/asm/unistd.h
arch/arm/include/uapi/asm/unistd.h
arch/arm/kernel/calls.S
arch/arm/kernel/setup.c
arch/arm/mm/proc-v7.S
arch/m68k/configs/amiga_defconfig
arch/m68k/configs/apollo_defconfig
arch/m68k/configs/atari_defconfig
arch/m68k/configs/bvme6000_defconfig
arch/m68k/configs/hp300_defconfig
arch/m68k/configs/mac_defconfig
arch/m68k/configs/multi_defconfig
arch/m68k/configs/mvme147_defconfig
arch/m68k/configs/mvme16x_defconfig
arch/m68k/configs/q40_defconfig
arch/m68k/configs/sun3_defconfig
arch/m68k/configs/sun3x_defconfig
arch/m68k/include/asm/unistd.h
arch/m68k/include/uapi/asm/unistd.h
arch/m68k/kernel/syscalltable.S
arch/parisc/include/asm/uaccess.h
arch/parisc/kernel/asm-offsets.c
arch/parisc/kernel/module.c
arch/parisc/kernel/parisc_ksyms.c
arch/parisc/kernel/traps.c
arch/parisc/lib/fixup.S
arch/parisc/mm/fault.c
arch/x86/include/asm/msr-index.h
arch/x86/kernel/setup.c
drivers/base/power/wakeup.c
drivers/block/rbd.c
drivers/cpufreq/cpufreq-dt.c
drivers/cpufreq/intel_pstate.c
drivers/firmware/qemu_fw_cfg.c
drivers/gpio/gpio-pca953x.c
drivers/gpio/gpio-pxa.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
drivers/gpu/drm/amd/include/cgs_common.h
drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
drivers/gpu/drm/arm/hdlcd_drv.c
drivers/gpu/drm/imx/dw_hdmi-imx.c
drivers/gpu/drm/imx/imx-drm-core.c
drivers/gpu/drm/imx/ipuv3-plane.c
drivers/gpu/drm/imx/ipuv3-plane.h
drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
drivers/gpu/drm/nouveau/nouveau_platform.c
drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
drivers/gpu/ipu-v3/ipu-cpmem.c
drivers/gpu/ipu-v3/ipu-dmfc.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-lenovo.c
drivers/hid/hid-microsoft.c
drivers/hid/hid-multitouch.c
drivers/hid/hid-wiimote-modules.c
drivers/hid/usbhid/hid-core.c
drivers/hid/wacom_sys.c
drivers/hid/wacom_wac.c
drivers/hid/wacom_wac.h
drivers/i2c/busses/i2c-jz4780.c
drivers/i2c/i2c-core.c
drivers/i2c/muxes/i2c-demux-pinctrl.c
drivers/idle/intel_idle.c
drivers/iio/accel/bmc150-accel-core.c
drivers/iio/adc/Kconfig
drivers/iio/adc/max1363.c
drivers/iio/gyro/bmg160_core.c
drivers/iio/health/max30100.c
drivers/iio/imu/inv_mpu6050/Kconfig
drivers/iio/industrialio-buffer.c
drivers/iio/light/apds9960.c
drivers/iio/magnetometer/st_magn.h
drivers/infiniband/hw/i40iw/i40iw_cm.c
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/infiniband/ulp/srpt/ib_srpt.h
drivers/iommu/dma-iommu.c
drivers/iommu/intel-iommu.c
drivers/iommu/iommu.c
drivers/iommu/rockchip-iommu.c
drivers/mailbox/pcc.c
drivers/md/bitmap.c
drivers/md/md.c
drivers/md/raid1.c
drivers/mmc/host/sdhci-pci-core.c
drivers/mmc/host/sdhci-pci.h
drivers/mmc/host/sdhci-pxav3.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h
drivers/net/ethernet/intel/e1000/e1000_main.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/tun.c
drivers/nvdimm/bus.c
drivers/nvdimm/core.c
drivers/nvdimm/nd.h
drivers/nvdimm/pfn_devs.c
drivers/nvdimm/pmem.c
drivers/powercap/intel_rapl.c
drivers/scsi/aacraid/linit.c
drivers/scsi/cxlflash/main.c
drivers/scsi/cxlflash/main.h
drivers/scsi/device_handler/scsi_dh_alua.c
drivers/scsi/mpt3sas/mpt3sas_base.c
drivers/scsi/scsi.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/sd.c
drivers/scsi/sd.h
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/olpc_dcon/Kconfig [new file with mode: 0644]
drivers/staging/olpc_dcon/Makefile [new file with mode: 0644]
drivers/staging/olpc_dcon/TODO [new file with mode: 0644]
drivers/staging/olpc_dcon/olpc_dcon.c [new file with mode: 0644]
drivers/staging/olpc_dcon/olpc_dcon.h [new file with mode: 0644]
drivers/staging/olpc_dcon/olpc_dcon_xo_1.c [new file with mode: 0644]
drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c [new file with mode: 0644]
drivers/staging/rdma/hfi1/Kconfig
drivers/tty/tty_io.c
drivers/usb/core/config.c
drivers/usb/dwc2/gadget.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/dwc3-keystone.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/function/f_midi.c
drivers/usb/gadget/udc/atmel_usba_udc.c
drivers/usb/gadget/udc/udc-core.c
drivers/usb/phy/phy-qcom-8x16-usb.c
drivers/usb/renesas_usbhs/fifo.c
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/mct_u232.c
drivers/usb/serial/option.c
drivers/usb/usbip/usbip_common.c
drivers/virtio/virtio_pci_modern.c
fs/btrfs/ctree.c
fs/btrfs/dev-replace.c
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/ioctl.c
fs/btrfs/qgroup.c
fs/btrfs/relocation.c
fs/btrfs/tree-log.c
fs/dcache.c
fs/ext4/crypto.c
fs/ext4/ext4.h
fs/ext4/file.c
fs/ext4/inode.c
fs/ext4/move_extent.c
fs/ext4/page-io.c
fs/ext4/readpage.c
fs/ext4/super.c
fs/ext4/xattr.c
fs/nfs/dir.c
fs/nfs/inode.c
fs/nfs/nfs4file.c
fs/orangefs/dir.c
fs/orangefs/inode.c
fs/orangefs/orangefs-debugfs.c
fs/orangefs/orangefs-utils.c
fs/orangefs/protocol.h
fs/orangefs/xattr.c
fs/overlayfs/super.c
include/drm/ttm/ttm_bo_api.h
include/linux/dcache.h
include/linux/fs.h
include/linux/iommu.h
include/linux/netdevice.h
include/net/act_api.h
include/net/mac80211.h
include/net/sctp/sctp.h
include/scsi/scsi_device.h
include/trace/events/btrfs.h
include/uapi/linux/usb/ch9.h
include/uapi/linux/virtio_config.h
include/video/imx-ipu-v3.h
lib/test_bpf.c
net/core/dev.c
net/core/netpoll.c
net/core/sock.c
net/ipv4/fou.c
net/ipv4/gre_offload.c
net/ipv4/ip_gre.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/l2tp/l2tp_ip.c
net/l2tp/l2tp_ip6.c
net/mac80211/chan.c
net/mac80211/ieee80211_i.h
net/mac80211/mesh_hwmp.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/tdls.c
net/mac80211/tx.c
net/mac80211/vht.c
net/mpls/af_mpls.c
net/packet/af_packet.c
net/rds/ib_recv.c
net/rds/page.c
net/sctp/output.c
net/vmw_vsock/vmci_transport.c
samples/bpf/Makefile
samples/bpf/bpf_helpers.h
samples/bpf/map_perf_test_user.c
samples/bpf/spintest_kern.c
samples/bpf/tracex2_kern.c
samples/bpf/tracex4_kern.c
tools/power/x86/turbostat/turbostat.c

index 7ac7d7262bb718f7d9e1d5e60c14491a4d7e7db0..3c3514815cd53bada6852068370d7cd193be9293 100644 (file)
@@ -1,23 +1,18 @@
-What:          /sys/devices/platform/<i2c-demux-name>/cur_master
+What:          /sys/devices/platform/<i2c-demux-name>/available_masters
 Date:          January 2016
 KernelVersion: 4.6
 Contact:       Wolfram Sang <wsa@the-dreams.de>
 Description:
+               Reading the file will give you a list of masters which can be
+               selected for a demultiplexed bus. The format is
+               "<index>:<name>". Example from a Renesas Lager board:
 
-This file selects the active I2C master for a demultiplexed bus.
+               0:/i2c@e6500000 1:/i2c@e6508000
 
-Write 0 there for the first master, 1 for the second etc. Reading the file will
-give you a list with the active master marked. Example from a Renesas Lager
-board:
-
-root@Lager:~# cat /sys/devices/platform/i2c@8/cur_master
-* 0 - /i2c@9
-  1 - /i2c@e6520000
-  2 - /i2c@e6530000
-
-root@Lager:~# echo 2 > /sys/devices/platform/i2c@8/cur_master
-
-root@Lager:~# cat /sys/devices/platform/i2c@8/cur_master
-  0 - /i2c@9
-  1 - /i2c@e6520000
-* 2 - /i2c@e6530000
+What:          /sys/devices/platform/<i2c-demux-name>/current_master
+Date:          January 2016
+KernelVersion: 4.6
+Contact:       Wolfram Sang <wsa@the-dreams.de>
+Description:
+               This file selects/shows the active I2C master for a demultiplexed
+               bus. It uses the <index> value from the file 'available_masters'.
index 7328cf85236c2b2bc5a4c078dc9f81f2e3febd11..1fd1fbe9ce95adf9b37109cfea9833d586fcfffe 100644 (file)
@@ -586,6 +586,10 @@ drivers to make their ->remove() callbacks avoid races with runtime PM directly,
 but also it allows of more flexibility in the handling of devices during the
 removal of their drivers.
 
+Drivers in ->remove() callback should undo the runtime PM changes done
+in ->probe(). Usually this means calling pm_runtime_disable(),
+pm_runtime_dont_use_autosuspend() etc.
+
 The user space can effectively disallow the driver of the device to power manage
 it at run time by changing the value of its /sys/devices/.../power/control
 attribute to "on", which causes pm_runtime_forbid() to be called.  In principle,
index 7f9f4bda9d15a24b96920b404ead2d9d0adb6dc7..1d5b4becab6f9a1d3272dc950a16665590e8b6a0 100644 (file)
@@ -4302,7 +4302,7 @@ F:        drivers/net/ethernet/agere/
 
 ETHERNET BRIDGE
 M:     Stephen Hemminger <stephen@networkplumber.org>
-L:     bridge@lists.linux-foundation.org
+L:     bridge@lists.linux-foundation.org (moderated for non-subscribers)
 L:     netdev@vger.kernel.org
 W:     http://www.linuxfoundation.org/en/Net:Bridge
 S:     Maintained
@@ -5751,7 +5751,7 @@ R:        Don Skidmore <donald.c.skidmore@intel.com>
 R:     Bruce Allan <bruce.w.allan@intel.com>
 R:     John Ronciak <john.ronciak@intel.com>
 R:     Mitch Williams <mitch.a.williams@intel.com>
-L:     intel-wired-lan@lists.osuosl.org
+L:     intel-wired-lan@lists.osuosl.org (moderated for non-subscribers)
 W:     http://www.intel.com/support/feedback.htm
 W:     http://e1000.sourceforge.net/
 Q:     http://patchwork.ozlabs.org/project/intel-wired-lan/list/
@@ -7576,7 +7576,7 @@ F:        drivers/infiniband/hw/nes/
 
 NETEM NETWORK EMULATOR
 M:     Stephen Hemminger <stephen@networkplumber.org>
-L:     netem@lists.linux-foundation.org
+L:     netem@lists.linux-foundation.org (moderated for non-subscribers)
 S:     Maintained
 F:     net/sched/sch_netem.c
 
@@ -9142,6 +9142,13 @@ T:       git git://github.com/KrasnikovEugene/wcn36xx.git
 S:     Supported
 F:     drivers/net/wireless/ath/wcn36xx/
 
+QEMU MACHINE EMULATOR AND VIRTUALIZER SUPPORT
+M:     Gabriel Somlo <somlo@cmu.edu>
+M:     "Michael S. Tsirkin" <mst@redhat.com>
+L:     qemu-devel@nongnu.org
+S:     Maintained
+F:     drivers/firmware/qemu_fw_cfg.c
+
 RADOS BLOCK DEVICE (RBD)
 M:     Ilya Dryomov <idryomov@gmail.com>
 M:     Sage Weil <sage@redhat.com>
@@ -10588,6 +10595,14 @@ L:     linux-tegra@vger.kernel.org
 S:     Maintained
 F:     drivers/staging/nvec/
 
+STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON)
+M:     Jens Frederich <jfrederich@gmail.com>
+M:     Daniel Drake <dsd@laptop.org>
+M:     Jon Nettleton <jon.nettleton@gmail.com>
+W:     http://wiki.laptop.org/go/DCON
+S:     Maintained
+F:     drivers/staging/olpc_dcon/
+
 STAGING - REALTEK RTL8712U DRIVERS
 M:     Larry Finger <Larry.Finger@lwfinger.net>
 M:     Florian Schilhabel <florian.c.schilhabel@googlemail.com>.
index 173437debc873cf1c38287fa288be0abfbc40df9..1d0aef03eae7fae72f70016575c2f54502706bbb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 6
 SUBLEVEL = 0
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
 NAME = Blurry Fish Butt
 
 # *DOCUMENTATION*
index 208aae071b378550fa47ade47332ec9351f62e43..12d0284a46e54a6cc74edde0fb5956924673a183 100644 (file)
@@ -593,7 +593,6 @@ config PCI_SYSCALL
        def_bool PCI
 
 source "drivers/pci/Kconfig"
-source "drivers/pci/pcie/Kconfig"
 
 endmenu
 
index ab5d5701e11d448200d3010df229c9f5f57875d9..44a578c10732cd1ab79558415e3c66f6825c98bd 100644 (file)
                        clocks = <&apbclk>;
                        clock-names = "stmmaceth";
                        max-speed = <100>;
-                       mdio0 {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               compatible = "snps,dwmac-mdio";
-                               phy1: ethernet-phy@1 {
-                                       reg = <1>;
-                               };
-                       };
                };
 
                ehci@0x40000 {
index f8b396c9aedb77e23da95d5cd10c0272102b13fe..491b3b5f22bdcad4e787f9770448de4544241a53 100644 (file)
@@ -42,6 +42,7 @@ CONFIG_DEVTMPFS=y
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_BLK_DEV_LOOP=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_NETDEVICES=y
index 56128ea2b748783a5f0011a62cca2c6f5c9f7218..b25ee73b2e79a7967bfe9c31b0949ff9ece52b4d 100644 (file)
@@ -43,6 +43,7 @@ CONFIG_DEVTMPFS=y
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_BLK_DEV_LOOP=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_NETDEVICES=y
diff --git a/arch/arc/include/asm/fb.h b/arch/arc/include/asm/fb.h
new file mode 100644 (file)
index 0000000..bd3f68c
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _ASM_FB_H_
+#define _ASM_FB_H_
+
+#include <linux/fb.h>
+#include <linux/fs.h>
+#include <asm/page.h>
+
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+                               unsigned long off)
+{
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+}
+
+static inline int fb_is_primary_device(struct fb_info *info)
+{
+       return 0;
+}
+
+#endif /* _ASM_FB_H_ */
index 7b84657fba3577ea3d29ecf1b93e3267feecbb59..194b6992338920680c14c46326999791e33defa6 100644 (file)
@@ -19,7 +19,7 @@
  * This may need to be greater than __NR_last_syscall+1 in order to
  * account for the padding in the syscall table
  */
-#define __NR_syscalls  (392)
+#define __NR_syscalls  (396)
 
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_GETHOSTNAME
index 5dd2528e9e45e369d0879185291e6981dbea15e4..2cb9dc770e1d41e8867f949e1ef13e028568a3d3 100644 (file)
 #define __NR_membarrier                        (__NR_SYSCALL_BASE+389)
 #define __NR_mlock2                    (__NR_SYSCALL_BASE+390)
 #define __NR_copy_file_range           (__NR_SYSCALL_BASE+391)
+#define __NR_preadv2                   (__NR_SYSCALL_BASE+392)
+#define __NR_pwritev2                  (__NR_SYSCALL_BASE+393)
 
 /*
  * The following SWIs are ARM private.
index dfc7cd6851ad4bbd09b11ae94ee6056f691b1fcb..703fa0f3cd8f812907b47ac7c84646ff3e3aff94 100644 (file)
                CALL(sys_execveat)
                CALL(sys_userfaultfd)
                CALL(sys_membarrier)
-               CALL(sys_mlock2)
+/* 390 */      CALL(sys_mlock2)
                CALL(sys_copy_file_range)
+               CALL(sys_preadv2)
+               CALL(sys_pwritev2)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
index 139791ed473d5264682c004ea2ea7af8ddd28f5d..a28fce0bdbbe11b7a950a3a0943f8362d7124b87 100644 (file)
@@ -430,11 +430,13 @@ static void __init patch_aeabi_idiv(void)
        pr_info("CPU: div instructions available: patching division code\n");
 
        fn_addr = ((uintptr_t)&__aeabi_uidiv) & ~1;
+       asm ("" : "+g" (fn_addr));
        ((u32 *)fn_addr)[0] = udiv_instruction();
        ((u32 *)fn_addr)[1] = bx_lr_instruction();
        flush_icache_range(fn_addr, fn_addr + 8);
 
        fn_addr = ((uintptr_t)&__aeabi_idiv) & ~1;
+       asm ("" : "+g" (fn_addr));
        ((u32 *)fn_addr)[0] = sdiv_instruction();
        ((u32 *)fn_addr)[1] = bx_lr_instruction();
        flush_icache_range(fn_addr, fn_addr + 8);
index 0f8963a7e7d9db28465c63a2bab69a615fb6a2cb..6fcaac8e200f888e18207ae6cdfeca8adc000c5e 100644 (file)
@@ -281,12 +281,12 @@ __v7_ca17mp_setup:
        bl      v7_invalidate_l1
        ldmia   r12, {r1-r6, lr}
 #ifdef CONFIG_SMP
+       orr     r10, r10, #(1 << 6)             @ Enable SMP/nAMP mode
        ALT_SMP(mrc     p15, 0, r0, c1, c0, 1)
-       ALT_UP(mov      r0, #(1 << 6))          @ fake it for UP
-       tst     r0, #(1 << 6)                   @ SMP/nAMP mode enabled?
-       orreq   r0, r0, #(1 << 6)               @ Enable SMP/nAMP mode
-       orreq   r0, r0, r10                     @ Enable CPU-specific SMP bits
-       mcreq   p15, 0, r0, c1, c0, 1
+       ALT_UP(mov      r0, r10)                @ fake it for UP
+       orr     r10, r10, r0                    @ Set required bits
+       teq     r10, r0                         @ Were they already set?
+       mcrne   p15, 0, r10, c1, c0, 1          @ No, update register
 #endif
        b       __v7_setup_cont
 
index d1fc4796025edb8769ee01195e64b91821f3625a..3ee6976f60885e5b2e0e4e2a80df6d824de14694 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_LOCALVERSION="-amiga"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -64,7 +63,6 @@ CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
-# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6=m
@@ -285,7 +283,9 @@ CONFIG_NET_MPLS_GSO=m
 CONFIG_MPLS_ROUTING=m
 CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
+CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -359,6 +359,7 @@ CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
+CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
@@ -452,6 +453,7 @@ CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FS_ENCRYPTION=m
 CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
@@ -468,6 +470,7 @@ CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_CHILDREN=y
 CONFIG_TMPFS=y
+CONFIG_ORANGEFS_FS=m
 CONFIG_AFFS_FS=m
 CONFIG_ECRYPT_FS=m
 CONFIG_ECRYPT_FS_MESSAGING=y
@@ -549,6 +552,7 @@ CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
 CONFIG_TEST_KSTRTOX=m
 CONFIG_TEST_PRINTF=m
+CONFIG_TEST_BITMAP=m
 CONFIG_TEST_RHASHTABLE=m
 CONFIG_TEST_LKM=m
 CONFIG_TEST_USER_COPY=m
@@ -557,7 +561,6 @@ CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_UDELAY=m
 CONFIG_TEST_STATIC_KEYS=m
 CONFIG_EARLY_PRINTK=y
-CONFIG_ENCRYPTED_KEYS=m
 CONFIG_CRYPTO_RSA=m
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_USER=m
@@ -565,12 +568,9 @@ CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_MCRYPTD=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
@@ -594,7 +594,6 @@ CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
index 9bfe8be3658c18231ca4473d8c075a1fb2ac4d5e..e96787ffcbced33f9893d2760259177086b13c1f 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_LOCALVERSION="-apollo"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -62,7 +61,6 @@ CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
-# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6=m
@@ -283,7 +281,9 @@ CONFIG_NET_MPLS_GSO=m
 CONFIG_MPLS_ROUTING=m
 CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
+CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -341,6 +341,7 @@ CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
+CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
@@ -411,6 +412,7 @@ CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FS_ENCRYPTION=m
 CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
@@ -427,6 +429,7 @@ CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_CHILDREN=y
 CONFIG_TMPFS=y
+CONFIG_ORANGEFS_FS=m
 CONFIG_AFFS_FS=m
 CONFIG_ECRYPT_FS=m
 CONFIG_ECRYPT_FS_MESSAGING=y
@@ -508,6 +511,7 @@ CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
 CONFIG_TEST_KSTRTOX=m
 CONFIG_TEST_PRINTF=m
+CONFIG_TEST_BITMAP=m
 CONFIG_TEST_RHASHTABLE=m
 CONFIG_TEST_LKM=m
 CONFIG_TEST_USER_COPY=m
@@ -516,7 +520,6 @@ CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_UDELAY=m
 CONFIG_TEST_STATIC_KEYS=m
 CONFIG_EARLY_PRINTK=y
-CONFIG_ENCRYPTED_KEYS=m
 CONFIG_CRYPTO_RSA=m
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_USER=m
@@ -524,12 +527,9 @@ CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_MCRYPTD=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
@@ -553,7 +553,6 @@ CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
index ebdcfae555801cd1c7367d4ca40974b3d39099cb..083fe6beac149da81250ca4fccd50798f9e4ef0d 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_LOCALVERSION="-atari"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -62,7 +61,6 @@ CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
-# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6=m
@@ -283,7 +281,9 @@ CONFIG_NET_MPLS_GSO=m
 CONFIG_MPLS_ROUTING=m
 CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
+CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -350,6 +350,7 @@ CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
+CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
@@ -432,6 +433,7 @@ CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FS_ENCRYPTION=m
 CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
@@ -448,6 +450,7 @@ CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_CHILDREN=y
 CONFIG_TMPFS=y
+CONFIG_ORANGEFS_FS=m
 CONFIG_AFFS_FS=m
 CONFIG_ECRYPT_FS=m
 CONFIG_ECRYPT_FS_MESSAGING=y
@@ -529,6 +532,7 @@ CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
 CONFIG_TEST_KSTRTOX=m
 CONFIG_TEST_PRINTF=m
+CONFIG_TEST_BITMAP=m
 CONFIG_TEST_RHASHTABLE=m
 CONFIG_TEST_LKM=m
 CONFIG_TEST_USER_COPY=m
@@ -537,7 +541,6 @@ CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_UDELAY=m
 CONFIG_TEST_STATIC_KEYS=m
 CONFIG_EARLY_PRINTK=y
-CONFIG_ENCRYPTED_KEYS=m
 CONFIG_CRYPTO_RSA=m
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_USER=m
@@ -545,12 +548,9 @@ CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_MCRYPTD=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
@@ -574,7 +574,6 @@ CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
index 8acc65e54995388614666716febdab1dda706376..475130c06dcba04b646ec2e7c199aee7045dea7d 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_LOCALVERSION="-bvme6000"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -60,7 +59,6 @@ CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
-# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6=m
@@ -281,7 +279,9 @@ CONFIG_NET_MPLS_GSO=m
 CONFIG_MPLS_ROUTING=m
 CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
+CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -340,6 +340,7 @@ CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
+CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
@@ -403,6 +404,7 @@ CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FS_ENCRYPTION=m
 CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
@@ -419,6 +421,7 @@ CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_CHILDREN=y
 CONFIG_TMPFS=y
+CONFIG_ORANGEFS_FS=m
 CONFIG_AFFS_FS=m
 CONFIG_ECRYPT_FS=m
 CONFIG_ECRYPT_FS_MESSAGING=y
@@ -500,6 +503,7 @@ CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
 CONFIG_TEST_KSTRTOX=m
 CONFIG_TEST_PRINTF=m
+CONFIG_TEST_BITMAP=m
 CONFIG_TEST_RHASHTABLE=m
 CONFIG_TEST_LKM=m
 CONFIG_TEST_USER_COPY=m
@@ -508,7 +512,6 @@ CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_UDELAY=m
 CONFIG_TEST_STATIC_KEYS=m
 CONFIG_EARLY_PRINTK=y
-CONFIG_ENCRYPTED_KEYS=m
 CONFIG_CRYPTO_RSA=m
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_USER=m
@@ -516,12 +519,9 @@ CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_MCRYPTD=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
@@ -545,7 +545,6 @@ CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
index 0c6a3d52b26e2b2559f24963040d3ba65a91ed47..4339658c200f3eb8af4bc2645836e109466055cb 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_LOCALVERSION="-hp300"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -62,7 +61,6 @@ CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
-# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6=m
@@ -283,7 +281,9 @@ CONFIG_NET_MPLS_GSO=m
 CONFIG_MPLS_ROUTING=m
 CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
+CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -341,6 +341,7 @@ CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
+CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
@@ -413,6 +414,7 @@ CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FS_ENCRYPTION=m
 CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
@@ -429,6 +431,7 @@ CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_CHILDREN=y
 CONFIG_TMPFS=y
+CONFIG_ORANGEFS_FS=m
 CONFIG_AFFS_FS=m
 CONFIG_ECRYPT_FS=m
 CONFIG_ECRYPT_FS_MESSAGING=y
@@ -510,6 +513,7 @@ CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
 CONFIG_TEST_KSTRTOX=m
 CONFIG_TEST_PRINTF=m
+CONFIG_TEST_BITMAP=m
 CONFIG_TEST_RHASHTABLE=m
 CONFIG_TEST_LKM=m
 CONFIG_TEST_USER_COPY=m
@@ -518,7 +522,6 @@ CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_UDELAY=m
 CONFIG_TEST_STATIC_KEYS=m
 CONFIG_EARLY_PRINTK=y
-CONFIG_ENCRYPTED_KEYS=m
 CONFIG_CRYPTO_RSA=m
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_USER=m
@@ -526,12 +529,9 @@ CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_MCRYPTD=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
@@ -555,7 +555,6 @@ CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
index 12a8a6cb32f4914f06c1f5d4c8e5dd6ba31381ef..831cc8c3a2e259f67d318257e72bcab84e36b8c1 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_LOCALVERSION="-mac"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -61,7 +60,6 @@ CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
-# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6=m
@@ -285,7 +283,9 @@ CONFIG_NET_MPLS_GSO=m
 CONFIG_MPLS_ROUTING=m
 CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
+CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -357,6 +357,7 @@ CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
+CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
@@ -435,6 +436,7 @@ CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FS_ENCRYPTION=m
 CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
@@ -451,6 +453,7 @@ CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_CHILDREN=y
 CONFIG_TMPFS=y
+CONFIG_ORANGEFS_FS=m
 CONFIG_AFFS_FS=m
 CONFIG_ECRYPT_FS=m
 CONFIG_ECRYPT_FS_MESSAGING=y
@@ -532,6 +535,7 @@ CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
 CONFIG_TEST_KSTRTOX=m
 CONFIG_TEST_PRINTF=m
+CONFIG_TEST_BITMAP=m
 CONFIG_TEST_RHASHTABLE=m
 CONFIG_TEST_LKM=m
 CONFIG_TEST_USER_COPY=m
@@ -540,7 +544,6 @@ CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_UDELAY=m
 CONFIG_TEST_STATIC_KEYS=m
 CONFIG_EARLY_PRINTK=y
-CONFIG_ENCRYPTED_KEYS=m
 CONFIG_CRYPTO_RSA=m
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_USER=m
@@ -548,12 +551,9 @@ CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_MCRYPTD=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
@@ -577,7 +577,6 @@ CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
index 64ff2dcb34c89a3e60e26f9c468d654ed943e97f..6377afeb522bbb9a235d1bd57f36cc14ca36ac5b 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_LOCALVERSION="-multi"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -71,7 +70,6 @@ CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
-# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6=m
@@ -295,7 +293,9 @@ CONFIG_NET_MPLS_GSO=m
 CONFIG_MPLS_ROUTING=m
 CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
+CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -390,6 +390,7 @@ CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
+CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
@@ -515,6 +516,7 @@ CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FS_ENCRYPTION=m
 CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
@@ -531,6 +533,7 @@ CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_CHILDREN=y
 CONFIG_TMPFS=y
+CONFIG_ORANGEFS_FS=m
 CONFIG_AFFS_FS=m
 CONFIG_ECRYPT_FS=m
 CONFIG_ECRYPT_FS_MESSAGING=y
@@ -612,6 +615,7 @@ CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
 CONFIG_TEST_KSTRTOX=m
 CONFIG_TEST_PRINTF=m
+CONFIG_TEST_BITMAP=m
 CONFIG_TEST_RHASHTABLE=m
 CONFIG_TEST_LKM=m
 CONFIG_TEST_USER_COPY=m
@@ -620,7 +624,6 @@ CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_UDELAY=m
 CONFIG_TEST_STATIC_KEYS=m
 CONFIG_EARLY_PRINTK=y
-CONFIG_ENCRYPTED_KEYS=m
 CONFIG_CRYPTO_RSA=m
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_USER=m
@@ -628,12 +631,9 @@ CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_MCRYPTD=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
@@ -657,7 +657,6 @@ CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
index 07fc6abcfe0c50e4b656a63a9da36c728b13cec4..4304b3d56262bc677383ba4389b65d5e9a7625cd 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_LOCALVERSION="-mvme147"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -59,7 +58,6 @@ CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
-# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6=m
@@ -280,7 +278,9 @@ CONFIG_NET_MPLS_GSO=m
 CONFIG_MPLS_ROUTING=m
 CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
+CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -339,6 +339,7 @@ CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
+CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
@@ -403,6 +404,7 @@ CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FS_ENCRYPTION=m
 CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
@@ -419,6 +421,7 @@ CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_CHILDREN=y
 CONFIG_TMPFS=y
+CONFIG_ORANGEFS_FS=m
 CONFIG_AFFS_FS=m
 CONFIG_ECRYPT_FS=m
 CONFIG_ECRYPT_FS_MESSAGING=y
@@ -500,6 +503,7 @@ CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
 CONFIG_TEST_KSTRTOX=m
 CONFIG_TEST_PRINTF=m
+CONFIG_TEST_BITMAP=m
 CONFIG_TEST_RHASHTABLE=m
 CONFIG_TEST_LKM=m
 CONFIG_TEST_USER_COPY=m
@@ -508,7 +512,6 @@ CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_UDELAY=m
 CONFIG_TEST_STATIC_KEYS=m
 CONFIG_EARLY_PRINTK=y
-CONFIG_ENCRYPTED_KEYS=m
 CONFIG_CRYPTO_RSA=m
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_USER=m
@@ -516,12 +519,9 @@ CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_MCRYPTD=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
@@ -545,7 +545,6 @@ CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
index 69903ded88f71d1d51ad4b430acbd2f745fdf867..074bda4094ffd5b0913d4411371e2597774faab2 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_LOCALVERSION="-mvme16x"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -60,7 +59,6 @@ CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
-# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6=m
@@ -281,7 +279,9 @@ CONFIG_NET_MPLS_GSO=m
 CONFIG_MPLS_ROUTING=m
 CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
+CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -340,6 +340,7 @@ CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
+CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
@@ -403,6 +404,7 @@ CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FS_ENCRYPTION=m
 CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
@@ -419,6 +421,7 @@ CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_CHILDREN=y
 CONFIG_TMPFS=y
+CONFIG_ORANGEFS_FS=m
 CONFIG_AFFS_FS=m
 CONFIG_ECRYPT_FS=m
 CONFIG_ECRYPT_FS_MESSAGING=y
@@ -500,6 +503,7 @@ CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
 CONFIG_TEST_KSTRTOX=m
 CONFIG_TEST_PRINTF=m
+CONFIG_TEST_BITMAP=m
 CONFIG_TEST_RHASHTABLE=m
 CONFIG_TEST_LKM=m
 CONFIG_TEST_USER_COPY=m
@@ -508,7 +512,6 @@ CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_UDELAY=m
 CONFIG_TEST_STATIC_KEYS=m
 CONFIG_EARLY_PRINTK=y
-CONFIG_ENCRYPTED_KEYS=m
 CONFIG_CRYPTO_RSA=m
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_USER=m
@@ -516,12 +519,9 @@ CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_MCRYPTD=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
@@ -545,7 +545,6 @@ CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
index bd8401686ddef143bf036159cb3f4ea650772f32..07b9fa8d7f2ea71dd09a26c8d9abe4a519baa07c 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_LOCALVERSION="-q40"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -60,7 +59,6 @@ CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
-# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6=m
@@ -281,7 +279,9 @@ CONFIG_NET_MPLS_GSO=m
 CONFIG_MPLS_ROUTING=m
 CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
+CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -346,6 +346,7 @@ CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
+CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
@@ -426,6 +427,7 @@ CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FS_ENCRYPTION=m
 CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
@@ -442,6 +444,7 @@ CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_CHILDREN=y
 CONFIG_TMPFS=y
+CONFIG_ORANGEFS_FS=m
 CONFIG_AFFS_FS=m
 CONFIG_ECRYPT_FS=m
 CONFIG_ECRYPT_FS_MESSAGING=y
@@ -523,6 +526,7 @@ CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
 CONFIG_TEST_KSTRTOX=m
 CONFIG_TEST_PRINTF=m
+CONFIG_TEST_BITMAP=m
 CONFIG_TEST_RHASHTABLE=m
 CONFIG_TEST_LKM=m
 CONFIG_TEST_USER_COPY=m
@@ -531,7 +535,6 @@ CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_UDELAY=m
 CONFIG_TEST_STATIC_KEYS=m
 CONFIG_EARLY_PRINTK=y
-CONFIG_ENCRYPTED_KEYS=m
 CONFIG_CRYPTO_RSA=m
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_USER=m
@@ -539,12 +542,9 @@ CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_MCRYPTD=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
@@ -568,7 +568,6 @@ CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
index 5f9fb3ab9636808d46b75f3696f477ab91e6dd79..36e6fae02d458e2dcb1a96c0caee68a5301f0341 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_LOCALVERSION="-sun3"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -57,7 +56,6 @@ CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
-# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6=m
@@ -278,7 +276,9 @@ CONFIG_NET_MPLS_GSO=m
 CONFIG_MPLS_ROUTING=m
 CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
+CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -337,6 +337,7 @@ CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
+CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
@@ -405,6 +406,7 @@ CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FS_ENCRYPTION=m
 CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
@@ -421,6 +423,7 @@ CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_CHILDREN=y
 CONFIG_TMPFS=y
+CONFIG_ORANGEFS_FS=m
 CONFIG_AFFS_FS=m
 CONFIG_ECRYPT_FS=m
 CONFIG_ECRYPT_FS_MESSAGING=y
@@ -502,6 +505,7 @@ CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
 CONFIG_TEST_KSTRTOX=m
 CONFIG_TEST_PRINTF=m
+CONFIG_TEST_BITMAP=m
 CONFIG_TEST_RHASHTABLE=m
 CONFIG_TEST_LKM=m
 CONFIG_TEST_USER_COPY=m
@@ -509,7 +513,6 @@ CONFIG_TEST_BPF=m
 CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_UDELAY=m
 CONFIG_TEST_STATIC_KEYS=m
-CONFIG_ENCRYPTED_KEYS=m
 CONFIG_CRYPTO_RSA=m
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_USER=m
@@ -517,12 +520,9 @@ CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_MCRYPTD=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
@@ -546,7 +546,6 @@ CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
index 5d1c674530e2ba73ca43ffc4940f139772962152..903acf929511e5066403bfdd1c4d78bbc4084c35 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_LOCALVERSION="-sun3x"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -57,7 +56,6 @@ CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
-# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6=m
@@ -278,7 +276,9 @@ CONFIG_NET_MPLS_GSO=m
 CONFIG_MPLS_ROUTING=m
 CONFIG_MPLS_IPTUNNEL=m
 CONFIG_NET_L3_MASTER_DEV=y
+CONFIG_AF_KCM=m
 # CONFIG_WIRELESS is not set
+CONFIG_NET_DEVLINK=m
 # CONFIG_UEVENT_HELPER is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -337,6 +337,7 @@ CONFIG_MACVTAP=m
 CONFIG_IPVLAN=m
 CONFIG_VXLAN=m
 CONFIG_GENEVE=m
+CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
@@ -405,6 +406,7 @@ CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FS_ENCRYPTION=m
 CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
@@ -421,6 +423,7 @@ CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_CHILDREN=y
 CONFIG_TMPFS=y
+CONFIG_ORANGEFS_FS=m
 CONFIG_AFFS_FS=m
 CONFIG_ECRYPT_FS=m
 CONFIG_ECRYPT_FS_MESSAGING=y
@@ -502,6 +505,7 @@ CONFIG_TEST_HEXDUMP=m
 CONFIG_TEST_STRING_HELPERS=m
 CONFIG_TEST_KSTRTOX=m
 CONFIG_TEST_PRINTF=m
+CONFIG_TEST_BITMAP=m
 CONFIG_TEST_RHASHTABLE=m
 CONFIG_TEST_LKM=m
 CONFIG_TEST_USER_COPY=m
@@ -510,7 +514,6 @@ CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_UDELAY=m
 CONFIG_TEST_STATIC_KEYS=m
 CONFIG_EARLY_PRINTK=y
-CONFIG_ENCRYPTED_KEYS=m
 CONFIG_CRYPTO_RSA=m
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_USER=m
@@ -518,12 +521,9 @@ CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_MCRYPTD=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
@@ -547,7 +547,6 @@ CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 CONFIG_CRYPTO_842=m
 CONFIG_CRYPTO_LZ4=m
index bafaff6dcd7bda8a28101f140159f9a7a76638db..a857d82ec5094abc30e353f25370365194a01194 100644 (file)
@@ -4,7 +4,7 @@
 #include <uapi/asm/unistd.h>
 
 
-#define NR_syscalls            377
+#define NR_syscalls            379
 
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_OLD_STAT
index 0ca729665f29e9d67851aed2c1c52be75bbd078b..9fe674bf911fd2a4e61d7119f9b91ffbdddf44f5 100644 (file)
 #define __NR_membarrier                374
 #define __NR_mlock2            375
 #define __NR_copy_file_range   376
+#define __NR_preadv2           377
+#define __NR_pwritev2          378
 
 #endif /* _UAPI_ASM_M68K_UNISTD_H_ */
index 8bb94261ff97d953fcfbe7c305e6a7ecfce27a97..d6fd6d9ced2474ab477b0becefbd5f695d256e96 100644 (file)
@@ -397,3 +397,5 @@ ENTRY(sys_call_table)
        .long sys_membarrier
        .long sys_mlock2                /* 375 */
        .long sys_copy_file_range
+       .long sys_preadv2
+       .long sys_pwritev2
index d4dd6e58682ce582f9b6581095fb11e59dee2766..7955e43f3f3f27558da65b100b9c3f64ebe26b02 100644 (file)
@@ -44,20 +44,18 @@ static inline long access_ok(int type, const void __user * addr,
 #define LDD_USER(ptr)          BUILD_BUG()
 #define STD_KERNEL(x, ptr)     __put_kernel_asm64(x, ptr)
 #define STD_USER(x, ptr)       __put_user_asm64(x, ptr)
-#define ASM_WORD_INSN          ".word\t"
 #else
 #define LDD_KERNEL(ptr)                __get_kernel_asm("ldd", ptr)
 #define LDD_USER(ptr)          __get_user_asm("ldd", ptr)
 #define STD_KERNEL(x, ptr)     __put_kernel_asm("std", x, ptr)
 #define STD_USER(x, ptr)       __put_user_asm("std", x, ptr)
-#define ASM_WORD_INSN          ".dword\t"
 #endif
 
 /*
- * The exception table contains two values: the first is an address
- * for an instruction that is allowed to fault, and the second is
- * the address to the fixup routine. Even on a 64bit kernel we could
- * use a 32bit (unsigned int) address here.
+ * The exception table contains two values: the first is the relative offset to
+ * the address of the instruction that is allowed to fault, and the second is
+ * the relative offset to the address of the fixup routine. Since relative
+ * addresses are used, 32bit values are sufficient even on 64bit kernel.
  */
 
 #define ARCH_HAS_RELATIVE_EXTABLE
@@ -77,6 +75,7 @@ struct exception_table_entry {
  */
 struct exception_data {
        unsigned long fault_ip;
+       unsigned long fault_gp;
        unsigned long fault_space;
        unsigned long fault_addr;
 };
index d2f62570a7b16d4f4c6321515d980f048cd278f2..78d30d2ea2d8bb24116a7639a3d4bc5f90400058 100644 (file)
@@ -299,6 +299,7 @@ int main(void)
 #endif
        BLANK();
        DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
+       DEFINE(EXCDATA_GP, offsetof(struct exception_data, fault_gp));
        DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
        DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr));
        BLANK();
index b9d75d9fa9ace520e472874b5dcb0f0b0aad440e..a0ecdb4abcc878b3805d7a2d0f845272b1fc372d 100644 (file)
@@ -660,6 +660,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
                        }
                        *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
                        break;
+               case R_PARISC_PCREL32:
+                       /* 32-bit PC relative address */
+                       *loc = val - dot - 8 + addend;
+                       break;
 
                default:
                        printk(KERN_ERR "module %s: Unknown relocation: %u\n",
@@ -788,6 +792,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
                        CHECK_RELOC(val, 22);
                        *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val);
                        break;
+               case R_PARISC_PCREL32:
+                       /* 32-bit PC relative address */
+                       *loc = val - dot - 8 + addend;
+                       break;
                case R_PARISC_DIR64:
                        /* 64-bit effective address */
                        *loc64 = val + addend;
index 568b2c61ea0208de80bcd1f5fdc54f7aafa95a30..3cad8aadc69e7a1159c829a7e5e5cea9f6a1297b 100644 (file)
@@ -47,11 +47,11 @@ EXPORT_SYMBOL(__cmpxchg_u64);
 EXPORT_SYMBOL(lclear_user);
 EXPORT_SYMBOL(lstrnlen_user);
 
-/* Global fixups */
-extern void fixup_get_user_skip_1(void);
-extern void fixup_get_user_skip_2(void);
-extern void fixup_put_user_skip_1(void);
-extern void fixup_put_user_skip_2(void);
+/* Global fixups - defined as int to avoid creation of function pointers */
+extern int fixup_get_user_skip_1;
+extern int fixup_get_user_skip_2;
+extern int fixup_put_user_skip_1;
+extern int fixup_put_user_skip_2;
 EXPORT_SYMBOL(fixup_get_user_skip_1);
 EXPORT_SYMBOL(fixup_get_user_skip_2);
 EXPORT_SYMBOL(fixup_put_user_skip_1);
index 16e0735e2f46bebb2b3a806d4b9d7d2f1a01c786..97d6b208e1294d23f52d825ee14ca28694f7876e 100644 (file)
@@ -795,6 +795,9 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 
            if (fault_space == 0 && !faulthandler_disabled())
            {
+               /* Clean up and return if in exception table. */
+               if (fixup_exception(regs))
+                       return;
                pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
                parisc_terminate("Kernel Fault", regs, code, fault_address);
            }
index 536ef66bb94b5aa8c46800a968514184b5e2d85d..1052b747e011336621c6ca9f7c9eaf78af7af6df 100644 (file)
@@ -26,6 +26,7 @@
 
 #ifdef CONFIG_SMP
        .macro  get_fault_ip t1 t2
+       loadgp
        addil LT%__per_cpu_offset,%r27
        LDREG RT%__per_cpu_offset(%r1),\t1
        /* t2 = smp_processor_id() */
        LDREG RT%exception_data(%r1),\t1
        /* t1 = this_cpu_ptr(&exception_data) */
        add,l \t1,\t2,\t1
+       /* %r27 = t1->fault_gp - restore gp */
+       LDREG EXCDATA_GP(\t1), %r27
        /* t1 = t1->fault_ip */
        LDREG EXCDATA_IP(\t1), \t1
        .endm
 #else
        .macro  get_fault_ip t1 t2
+       loadgp
        /* t1 = this_cpu_ptr(&exception_data) */
        addil LT%exception_data,%r27
        LDREG RT%exception_data(%r1),\t2
+       /* %r27 = t2->fault_gp - restore gp */
+       LDREG EXCDATA_GP(\t2), %r27
        /* t1 = t2->fault_ip */
        LDREG EXCDATA_IP(\t2), \t1
        .endm
index 26fac9c671c9375ab9ae1663617c237186f55aba..16dbe81c97c9005df3cbb91045ccb6ed20878930 100644 (file)
@@ -145,6 +145,7 @@ int fixup_exception(struct pt_regs *regs)
                struct exception_data *d;
                d = this_cpu_ptr(&exception_data);
                d->fault_ip = regs->iaoq[0];
+               d->fault_gp = regs->gr[27];
                d->fault_space = regs->isr;
                d->fault_addr = regs->ior;
 
index 426e946ed0c0155d011c942dd28aca32b0b85f2f..5b3c9a55f51cbeda86cb52dedac1f3f494042e55 100644 (file)
 #define MSR_PKG_C9_RESIDENCY           0x00000631
 #define MSR_PKG_C10_RESIDENCY          0x00000632
 
+/* Interrupt Response Limit */
+#define MSR_PKGC3_IRTL                 0x0000060a
+#define MSR_PKGC6_IRTL                 0x0000060b
+#define MSR_PKGC7_IRTL                 0x0000060c
+#define MSR_PKGC8_IRTL                 0x00000633
+#define MSR_PKGC9_IRTL                 0x00000634
+#define MSR_PKGC10_IRTL                        0x00000635
+
 /* Run Time Average Power Limiting (RAPL) Interface */
 
 #define MSR_RAPL_POWER_UNIT            0x00000606
index 2367ae07eb76db48964ef311e6cdc50f8751ecee..319b08a5b6ed353fb1ca9a03bc1e29626b59677d 100644 (file)
@@ -146,31 +146,6 @@ int default_check_phys_apicid_present(int phys_apicid)
 
 struct boot_params boot_params;
 
-/*
- * Machine setup..
- */
-static struct resource data_resource = {
-       .name   = "Kernel data",
-       .start  = 0,
-       .end    = 0,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
-};
-
-static struct resource code_resource = {
-       .name   = "Kernel code",
-       .start  = 0,
-       .end    = 0,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
-};
-
-static struct resource bss_resource = {
-       .name   = "Kernel bss",
-       .start  = 0,
-       .end    = 0,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
-};
-
-
 #ifdef CONFIG_X86_32
 /* cpu data as detected by the assembly code in head.S */
 struct cpuinfo_x86 new_cpu_data = {
@@ -949,13 +924,6 @@ void __init setup_arch(char **cmdline_p)
 
        mpx_mm_init(&init_mm);
 
-       code_resource.start = __pa_symbol(_text);
-       code_resource.end = __pa_symbol(_etext)-1;
-       data_resource.start = __pa_symbol(_etext);
-       data_resource.end = __pa_symbol(_edata)-1;
-       bss_resource.start = __pa_symbol(__bss_start);
-       bss_resource.end = __pa_symbol(__bss_stop)-1;
-
 #ifdef CONFIG_CMDLINE_BOOL
 #ifdef CONFIG_CMDLINE_OVERRIDE
        strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
@@ -1019,11 +987,6 @@ void __init setup_arch(char **cmdline_p)
 
        x86_init.resources.probe_roms();
 
-       /* after parse_early_param, so could debug it */
-       insert_resource(&iomem_resource, &code_resource);
-       insert_resource(&iomem_resource, &data_resource);
-       insert_resource(&iomem_resource, &bss_resource);
-
        e820_add_kernel_range();
        trim_bios_range();
 #ifdef CONFIG_X86_32
index a1e0b9ab847a345c6a09adab3ff9f2fd9af3ad3e..5fb7718f256cf9d7bd45229dcc6e8a0b2225b1c5 100644 (file)
@@ -246,6 +246,8 @@ static int device_wakeup_attach(struct device *dev, struct wakeup_source *ws)
                return -EEXIST;
        }
        dev->power.wakeup = ws;
+       if (dev->power.wakeirq)
+               device_wakeup_attach_irq(dev, dev->power.wakeirq);
        spin_unlock_irq(&dev->power.lock);
        return 0;
 }
index 9c6234428607fb60a6d65a3ea0c1eebfa72b6b96..94a1843b0426dec0f94919bb8f56e99ad4315e87 100644 (file)
@@ -1953,7 +1953,7 @@ static struct ceph_osd_request *rbd_osd_req_create(
 
        osdc = &rbd_dev->rbd_client->client->osdc;
        osd_req = ceph_osdc_alloc_request(osdc, snapc, num_ops, false,
-                                         GFP_ATOMIC);
+                                         GFP_NOIO);
        if (!osd_req)
                return NULL;    /* ENOMEM */
 
@@ -2002,7 +2002,7 @@ rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request)
        rbd_dev = img_request->rbd_dev;
        osdc = &rbd_dev->rbd_client->client->osdc;
        osd_req = ceph_osdc_alloc_request(osdc, snapc, num_osd_ops,
-                                               false, GFP_ATOMIC);
+                                               false, GFP_NOIO);
        if (!osd_req)
                return NULL;    /* ENOMEM */
 
@@ -2504,7 +2504,7 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
                                        bio_chain_clone_range(&bio_list,
                                                                &bio_offset,
                                                                clone_size,
-                                                               GFP_ATOMIC);
+                                                               GFP_NOIO);
                        if (!obj_request->bio_list)
                                goto out_unwind;
                } else if (type == OBJ_REQUEST_PAGES) {
index f951f911786e086b2b6dc9d615018eb235347dbe..5f8dbe640a202baa2b12d26267ca78b983c8b7fc 100644 (file)
@@ -4,9 +4,6 @@
  * Copyright (C) 2014 Linaro.
  * Viresh Kumar <viresh.kumar@linaro.org>
  *
- * The OPP code in function set_target() is reused from
- * drivers/cpufreq/omap-cpufreq.c
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
index 4b644526fd5977943761d5430e1967d26997567d..8b5a415ee14a53d21e9358e2b6707df852e827b8 100644 (file)
@@ -64,6 +64,25 @@ static inline int ceiling_fp(int32_t x)
        return ret;
 }
 
+/**
+ * struct sample -     Store performance sample
+ * @core_pct_busy:     Ratio of APERF/MPERF in percent, which is actual
+ *                     performance during last sample period
+ * @busy_scaled:       Scaled busy value which is used to calculate next
+ *                     P state. This can be different than core_pct_busy
+ *                     to account for cpu idle period
+ * @aperf:             Difference of actual performance frequency clock count
+ *                     read from APERF MSR between last and current sample
+ * @mperf:             Difference of maximum performance frequency clock count
+ *                     read from MPERF MSR between last and current sample
+ * @tsc:               Difference of time stamp counter between last and
+ *                     current sample
+ * @freq:              Effective frequency calculated from APERF/MPERF
+ * @time:              Current time from scheduler
+ *
+ * This structure is used in the cpudata structure to store performance sample
+ * data for choosing next P State.
+ */
 struct sample {
        int32_t core_pct_busy;
        int32_t busy_scaled;
@@ -74,6 +93,20 @@ struct sample {
        u64 time;
 };
 
+/**
+ * struct pstate_data - Store P state data
+ * @current_pstate:    Current requested P state
+ * @min_pstate:                Min P state possible for this platform
+ * @max_pstate:                Max P state possible for this platform
+ * @max_pstate_physical:This is physical Max P state for a processor
+ *                     This can be higher than the max_pstate which can
+ *                     be limited by platform thermal design power limits
+ * @scaling:           Scaling factor to  convert frequency to cpufreq
+ *                     frequency units
+ * @turbo_pstate:      Max Turbo P state possible for this platform
+ *
+ * Stores the per cpu model P state limits and current P state.
+ */
 struct pstate_data {
        int     current_pstate;
        int     min_pstate;
@@ -83,6 +116,19 @@ struct pstate_data {
        int     turbo_pstate;
 };
 
+/**
+ * struct vid_data -   Stores voltage information data
+ * @min:               VID data for this platform corresponding to
+ *                     the lowest P state
+ * @max:               VID data corresponding to the highest P State.
+ * @turbo:             VID data for turbo P state
+ * @ratio:             Ratio of (vid max - vid min) /
+ *                     (max P state - Min P State)
+ *
+ * Stores the voltage data for DVFS (Dynamic Voltage and Frequency Scaling)
+ * This data is used in Atom platforms, where in addition to target P state,
+ * the voltage data needs to be specified to select next P State.
+ */
 struct vid_data {
        int min;
        int max;
@@ -90,6 +136,18 @@ struct vid_data {
        int32_t ratio;
 };
 
+/**
+ * struct _pid -       Stores PID data
+ * @setpoint:          Target set point for busyness or performance
+ * @integral:          Storage for accumulated error values
+ * @p_gain:            PID proportional gain
+ * @i_gain:            PID integral gain
+ * @d_gain:            PID derivative gain
+ * @deadband:          PID deadband
+ * @last_err:          Last error storage for integral part of PID calculation
+ *
+ * Stores PID coefficients and last error for PID controller.
+ */
 struct _pid {
        int setpoint;
        int32_t integral;
@@ -100,6 +158,23 @@ struct _pid {
        int32_t last_err;
 };
 
+/**
+ * struct cpudata -    Per CPU instance data storage
+ * @cpu:               CPU number for this instance data
+ * @update_util:       CPUFreq utility callback information
+ * @pstate:            Stores P state limits for this CPU
+ * @vid:               Stores VID limits for this CPU
+ * @pid:               Stores PID parameters for this CPU
+ * @last_sample_time:  Last Sample time
+ * @prev_aperf:                Last APERF value read from APERF MSR
+ * @prev_mperf:                Last MPERF value read from MPERF MSR
+ * @prev_tsc:          Last timestamp counter (TSC) value
+ * @prev_cummulative_iowait: IO Wait time difference from last and
+ *                     current sample
+ * @sample:            Storage for storing last Sample data
+ *
+ * This structure stores per CPU instance data for all CPUs.
+ */
 struct cpudata {
        int cpu;
 
@@ -118,6 +193,19 @@ struct cpudata {
 };
 
 static struct cpudata **all_cpu_data;
+
+/**
+ * struct pid_adjust_policy - Stores static PID configuration data
+ * @sample_rate_ms:    PID calculation sample rate in ms
+ * @sample_rate_ns:    Sample rate calculation in ns
+ * @deadband:          PID deadband
+ * @setpoint:          PID Setpoint
+ * @p_gain_pct:                PID proportional gain
+ * @i_gain_pct:                PID integral gain
+ * @d_gain_pct:                PID derivative gain
+ *
+ * Stores per CPU model static PID configuration data.
+ */
 struct pstate_adjust_policy {
        int sample_rate_ms;
        s64 sample_rate_ns;
@@ -128,6 +216,20 @@ struct pstate_adjust_policy {
        int i_gain_pct;
 };
 
+/**
+ * struct pstate_funcs - Per CPU model specific callbacks
+ * @get_max:           Callback to get maximum non turbo effective P state
+ * @get_max_physical:  Callback to get maximum non turbo physical P state
+ * @get_min:           Callback to get minimum P state
+ * @get_turbo:         Callback to get turbo P state
+ * @get_scaling:       Callback to get frequency scaling factor
+ * @get_val:           Callback to convert P state to actual MSR write value
+ * @get_vid:           Callback to get VID data for Atom platforms
+ * @get_target_pstate: Callback to a function to calculate next P state to use
+ *
+ * Core and Atom CPU models have different way to get P State limits. This
+ * structure is used to store those callbacks.
+ */
 struct pstate_funcs {
        int (*get_max)(void);
        int (*get_max_physical)(void);
@@ -139,6 +241,11 @@ struct pstate_funcs {
        int32_t (*get_target_pstate)(struct cpudata *);
 };
 
+/**
+ * struct cpu_defaults- Per CPU model default config data
+ * @pid_policy:        PID config data
+ * @funcs:             Callback function data
+ */
 struct cpu_defaults {
        struct pstate_adjust_policy pid_policy;
        struct pstate_funcs funcs;
@@ -151,6 +258,34 @@ static struct pstate_adjust_policy pid_params;
 static struct pstate_funcs pstate_funcs;
 static int hwp_active;
 
+
+/**
+ * struct perf_limits - Store user and policy limits
+ * @no_turbo:          User requested turbo state from intel_pstate sysfs
+ * @turbo_disabled:    Platform turbo status either from msr
+ *                     MSR_IA32_MISC_ENABLE or when maximum available pstate
+ *                     matches the maximum turbo pstate
+ * @max_perf_pct:      Effective maximum performance limit in percentage, this
+ *                     is minimum of either limits enforced by cpufreq policy
+ *                     or limits from user set limits via intel_pstate sysfs
+ * @min_perf_pct:      Effective minimum performance limit in percentage, this
+ *                     is maximum of either limits enforced by cpufreq policy
+ *                     or limits from user set limits via intel_pstate sysfs
+ * @max_perf:          This is a scaled value between 0 to 255 for max_perf_pct
+ *                     This value is used to limit max pstate
+ * @min_perf:          This is a scaled value between 0 to 255 for min_perf_pct
+ *                     This value is used to limit min pstate
+ * @max_policy_pct:    The maximum performance in percentage enforced by
+ *                     cpufreq setpolicy interface
+ * @max_sysfs_pct:     The maximum performance in percentage enforced by
+ *                     intel pstate sysfs interface
+ * @min_policy_pct:    The minimum performance in percentage enforced by
+ *                     cpufreq setpolicy interface
+ * @min_sysfs_pct:     The minimum performance in percentage enforced by
+ *                     intel pstate sysfs interface
+ *
+ * Storage for user and policy defined limits.
+ */
 struct perf_limits {
        int no_turbo;
        int turbo_disabled;
@@ -910,7 +1045,14 @@ static inline bool intel_pstate_sample(struct cpudata *cpu, u64 time)
        cpu->prev_aperf = aperf;
        cpu->prev_mperf = mperf;
        cpu->prev_tsc = tsc;
-       return true;
+       /*
+        * First time this function is invoked in a given cycle, all of the
+        * previous sample data fields are equal to zero or stale and they must
+        * be populated with meaningful numbers for things to work, so assume
+        * that sample.time will always be reset before setting the utilization
+        * update hook and make the caller skip the sample then.
+        */
+       return !!cpu->last_sample_time;
 }
 
 static inline int32_t get_avg_frequency(struct cpudata *cpu)
@@ -984,8 +1126,7 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
         * enough period of time to adjust our busyness.
         */
        duration_ns = cpu->sample.time - cpu->last_sample_time;
-       if ((s64)duration_ns > pid_params.sample_rate_ns * 3
-           && cpu->last_sample_time > 0) {
+       if ((s64)duration_ns > pid_params.sample_rate_ns * 3) {
                sample_ratio = div_fp(int_tofp(pid_params.sample_rate_ns),
                                      int_tofp(duration_ns));
                core_busy = mul_fp(core_busy, sample_ratio);
@@ -1100,10 +1241,8 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
        intel_pstate_get_cpu_pstates(cpu);
 
        intel_pstate_busy_pid_reset(cpu);
-       intel_pstate_sample(cpu, 0);
 
        cpu->update_util.func = intel_pstate_update_util;
-       cpufreq_set_update_util_data(cpunum, &cpu->update_util);
 
        pr_debug("intel_pstate: controlling: cpu %d\n", cpunum);
 
@@ -1122,22 +1261,54 @@ static unsigned int intel_pstate_get(unsigned int cpu_num)
        return get_avg_frequency(cpu);
 }
 
+static void intel_pstate_set_update_util_hook(unsigned int cpu_num)
+{
+       struct cpudata *cpu = all_cpu_data[cpu_num];
+
+       /* Prevent intel_pstate_update_util() from using stale data. */
+       cpu->sample.time = 0;
+       cpufreq_set_update_util_data(cpu_num, &cpu->update_util);
+}
+
+static void intel_pstate_clear_update_util_hook(unsigned int cpu)
+{
+       cpufreq_set_update_util_data(cpu, NULL);
+       synchronize_sched();
+}
+
+static void intel_pstate_set_performance_limits(struct perf_limits *limits)
+{
+       limits->no_turbo = 0;
+       limits->turbo_disabled = 0;
+       limits->max_perf_pct = 100;
+       limits->max_perf = int_tofp(1);
+       limits->min_perf_pct = 100;
+       limits->min_perf = int_tofp(1);
+       limits->max_policy_pct = 100;
+       limits->max_sysfs_pct = 100;
+       limits->min_policy_pct = 0;
+       limits->min_sysfs_pct = 0;
+}
+
 static int intel_pstate_set_policy(struct cpufreq_policy *policy)
 {
        if (!policy->cpuinfo.max_freq)
                return -ENODEV;
 
-       if (policy->policy == CPUFREQ_POLICY_PERFORMANCE &&
-           policy->max >= policy->cpuinfo.max_freq) {
-               pr_debug("intel_pstate: set performance\n");
+       intel_pstate_clear_update_util_hook(policy->cpu);
+
+       if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
                limits = &performance_limits;
-               if (hwp_active)
-                       intel_pstate_hwp_set(policy->cpus);
-               return 0;
+               if (policy->max >= policy->cpuinfo.max_freq) {
+                       pr_debug("intel_pstate: set performance\n");
+                       intel_pstate_set_performance_limits(limits);
+                       goto out;
+               }
+       } else {
+               pr_debug("intel_pstate: set powersave\n");
+               limits = &powersave_limits;
        }
 
-       pr_debug("intel_pstate: set powersave\n");
-       limits = &powersave_limits;
        limits->min_policy_pct = (policy->min * 100) / policy->cpuinfo.max_freq;
        limits->min_policy_pct = clamp_t(int, limits->min_policy_pct, 0 , 100);
        limits->max_policy_pct = DIV_ROUND_UP(policy->max * 100,
@@ -1163,6 +1334,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
        limits->max_perf = div_fp(int_tofp(limits->max_perf_pct),
                                  int_tofp(100));
 
+ out:
+       intel_pstate_set_update_util_hook(policy->cpu);
+
        if (hwp_active)
                intel_pstate_hwp_set(policy->cpus);
 
@@ -1187,8 +1361,7 @@ static void intel_pstate_stop_cpu(struct cpufreq_policy *policy)
 
        pr_debug("intel_pstate: CPU %d exiting\n", cpu_num);
 
-       cpufreq_set_update_util_data(cpu_num, NULL);
-       synchronize_sched();
+       intel_pstate_clear_update_util_hook(cpu_num);
 
        if (hwp_active)
                return;
@@ -1455,8 +1628,7 @@ out:
        get_online_cpus();
        for_each_online_cpu(cpu) {
                if (all_cpu_data[cpu]) {
-                       cpufreq_set_update_util_data(cpu, NULL);
-                       synchronize_sched();
+                       intel_pstate_clear_update_util_hook(cpu);
                        kfree(all_cpu_data[cpu]);
                }
        }
index fedbff55a7f3848872b7d0196086bc0f56caa0c7..815c4a5cae543e228a634eae28241bc6f24ac1ed 100644 (file)
@@ -77,12 +77,28 @@ static inline u16 fw_cfg_sel_endianness(u16 key)
 static inline void fw_cfg_read_blob(u16 key,
                                    void *buf, loff_t pos, size_t count)
 {
+       u32 glk;
+       acpi_status status;
+
+       /* If we have ACPI, ensure mutual exclusion against any potential
+        * device access by the firmware, e.g. via AML methods:
+        */
+       status = acpi_acquire_global_lock(ACPI_WAIT_FOREVER, &glk);
+       if (ACPI_FAILURE(status) && status != AE_NOT_CONFIGURED) {
+               /* Should never get here */
+               WARN(1, "fw_cfg_read_blob: Failed to lock ACPI!\n");
+               memset(buf, 0, count);
+               return;
+       }
+
        mutex_lock(&fw_cfg_dev_lock);
        iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl);
        while (pos-- > 0)
                ioread8(fw_cfg_reg_data);
        ioread8_rep(fw_cfg_reg_data, buf, count);
        mutex_unlock(&fw_cfg_dev_lock);
+
+       acpi_release_global_lock(glk);
 }
 
 /* clean up fw_cfg device i/o */
@@ -727,12 +743,18 @@ device_param_cb(mmio, &fw_cfg_cmdline_param_ops, NULL, S_IRUSR);
 
 static int __init fw_cfg_sysfs_init(void)
 {
+       int ret;
+
        /* create /sys/firmware/qemu_fw_cfg/ top level directory */
        fw_cfg_top_ko = kobject_create_and_add("qemu_fw_cfg", firmware_kobj);
        if (!fw_cfg_top_ko)
                return -ENOMEM;
 
-       return platform_driver_register(&fw_cfg_sysfs_driver);
+       ret = platform_driver_register(&fw_cfg_sysfs_driver);
+       if (ret)
+               fw_cfg_kobj_cleanup(fw_cfg_top_ko);
+
+       return ret;
 }
 
 static void __exit fw_cfg_sysfs_exit(void)
index d0d3065a755767dcfeec9108921ac431fc490235..e66084c295fbff18a115927ecc28822aae6b3e63 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_data/pca953x.h>
 #include <linux/slab.h>
+#include <asm/unaligned.h>
 #include <linux/of_platform.h>
 #include <linux/acpi.h>
 
@@ -159,7 +160,7 @@ static int pca953x_write_regs(struct pca953x_chip *chip, int reg, u8 *val)
                switch (chip->chip_type) {
                case PCA953X_TYPE:
                        ret = i2c_smbus_write_word_data(chip->client,
-                                                       reg << 1, (u16) *val);
+                           reg << 1, cpu_to_le16(get_unaligned((u16 *)val)));
                        break;
                case PCA957X_TYPE:
                        ret = i2c_smbus_write_byte_data(chip->client, reg << 1,
index b2b7b78664b8058d9be9314e2298765fe772c0e9..76ac906b4d78d262ab5473771e377c9c244b76b3 100644 (file)
@@ -283,8 +283,8 @@ static int pxa_gpio_direction_output(struct gpio_chip *chip,
        writel_relaxed(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET));
 
        ret = pinctrl_gpio_direction_output(chip->base + offset);
-       if (!ret)
-               return 0;
+       if (ret)
+               return ret;
 
        spin_lock_irqsave(&gpio_lock, flags);
 
index 72065532c1c7bfda9796c55e2d350d2a1da00349..b747c76fd2b1f4f8f1e117b6ce2836525b1166fd 100644 (file)
@@ -68,6 +68,7 @@ LIST_HEAD(gpio_devices);
 static void gpiochip_free_hogs(struct gpio_chip *chip);
 static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip);
 
+static bool gpiolib_initialized;
 
 static inline void desc_set_label(struct gpio_desc *d, const char *label)
 {
@@ -440,9 +441,63 @@ static void gpiodevice_release(struct device *dev)
        cdev_del(&gdev->chrdev);
        list_del(&gdev->list);
        ida_simple_remove(&gpio_ida, gdev->id);
+       kfree(gdev->label);
+       kfree(gdev->descs);
        kfree(gdev);
 }
 
+static int gpiochip_setup_dev(struct gpio_device *gdev)
+{
+       int status;
+
+       cdev_init(&gdev->chrdev, &gpio_fileops);
+       gdev->chrdev.owner = THIS_MODULE;
+       gdev->chrdev.kobj.parent = &gdev->dev.kobj;
+       gdev->dev.devt = MKDEV(MAJOR(gpio_devt), gdev->id);
+       status = cdev_add(&gdev->chrdev, gdev->dev.devt, 1);
+       if (status < 0)
+               chip_warn(gdev->chip, "failed to add char device %d:%d\n",
+                         MAJOR(gpio_devt), gdev->id);
+       else
+               chip_dbg(gdev->chip, "added GPIO chardev (%d:%d)\n",
+                        MAJOR(gpio_devt), gdev->id);
+       status = device_add(&gdev->dev);
+       if (status)
+               goto err_remove_chardev;
+
+       status = gpiochip_sysfs_register(gdev);
+       if (status)
+               goto err_remove_device;
+
+       /* From this point, the .release() function cleans up gpio_device */
+       gdev->dev.release = gpiodevice_release;
+       get_device(&gdev->dev);
+       pr_debug("%s: registered GPIOs %d to %d on device: %s (%s)\n",
+                __func__, gdev->base, gdev->base + gdev->ngpio - 1,
+                dev_name(&gdev->dev), gdev->chip->label ? : "generic");
+
+       return 0;
+
+err_remove_device:
+       device_del(&gdev->dev);
+err_remove_chardev:
+       cdev_del(&gdev->chrdev);
+       return status;
+}
+
+static void gpiochip_setup_devs(void)
+{
+       struct gpio_device *gdev;
+       int err;
+
+       list_for_each_entry(gdev, &gpio_devices, list) {
+               err = gpiochip_setup_dev(gdev);
+               if (err)
+                       pr_err("%s: Failed to initialize gpio device (%d)\n",
+                              dev_name(&gdev->dev), err);
+       }
+}
+
 /**
  * gpiochip_add_data() - register a gpio_chip
  * @chip: the chip to register, with chip->base initialized
@@ -457,6 +512,9 @@ static void gpiodevice_release(struct device *dev)
  * the gpio framework's arch_initcall().  Otherwise sysfs initialization
  * for GPIOs will fail rudely.
  *
+ * gpiochip_add_data() must only be called after gpiolib initialization,
+ * ie after core_initcall().
+ *
  * If chip->base is negative, this requests dynamic assignment of
  * a range of valid GPIOs.
  */
@@ -504,8 +562,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data)
        else
                gdev->owner = THIS_MODULE;
 
-       gdev->descs = devm_kcalloc(&gdev->dev, chip->ngpio,
-                                  sizeof(gdev->descs[0]), GFP_KERNEL);
+       gdev->descs = kcalloc(chip->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL);
        if (!gdev->descs) {
                status = -ENOMEM;
                goto err_free_gdev;
@@ -514,16 +571,16 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data)
        if (chip->ngpio == 0) {
                chip_err(chip, "tried to insert a GPIO chip with zero lines\n");
                status = -EINVAL;
-               goto err_free_gdev;
+               goto err_free_descs;
        }
 
        if (chip->label)
-               gdev->label = devm_kstrdup(&gdev->dev, chip->label, GFP_KERNEL);
+               gdev->label = kstrdup(chip->label, GFP_KERNEL);
        else
-               gdev->label = devm_kstrdup(&gdev->dev, "unknown", GFP_KERNEL);
+               gdev->label = kstrdup("unknown", GFP_KERNEL);
        if (!gdev->label) {
                status = -ENOMEM;
-               goto err_free_gdev;
+               goto err_free_descs;
        }
 
        gdev->ngpio = chip->ngpio;
@@ -543,7 +600,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data)
                if (base < 0) {
                        status = base;
                        spin_unlock_irqrestore(&gpio_lock, flags);
-                       goto err_free_gdev;
+                       goto err_free_label;
                }
                /*
                 * TODO: it should not be necessary to reflect the assigned
@@ -558,7 +615,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data)
        status = gpiodev_add_to_list(gdev);
        if (status) {
                spin_unlock_irqrestore(&gpio_lock, flags);
-               goto err_free_gdev;
+               goto err_free_label;
        }
 
        for (i = 0; i < chip->ngpio; i++) {
@@ -596,39 +653,16 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data)
         * we get a device node entry in sysfs under
         * /sys/bus/gpio/devices/gpiochipN/dev that can be used for
         * coldplug of device nodes and other udev business.
+        * We can do this only if gpiolib has been initialized.
+        * Otherwise, defer until later.
         */
-       cdev_init(&gdev->chrdev, &gpio_fileops);
-       gdev->chrdev.owner = THIS_MODULE;
-       gdev->chrdev.kobj.parent = &gdev->dev.kobj;
-       gdev->dev.devt = MKDEV(MAJOR(gpio_devt), gdev->id);
-       status = cdev_add(&gdev->chrdev, gdev->dev.devt, 1);
-       if (status < 0)
-               chip_warn(chip, "failed to add char device %d:%d\n",
-                         MAJOR(gpio_devt), gdev->id);
-       else
-               chip_dbg(chip, "added GPIO chardev (%d:%d)\n",
-                        MAJOR(gpio_devt), gdev->id);
-       status = device_add(&gdev->dev);
-       if (status)
-               goto err_remove_chardev;
-
-       status = gpiochip_sysfs_register(gdev);
-       if (status)
-               goto err_remove_device;
-
-       /* From this point, the .release() function cleans up gpio_device */
-       gdev->dev.release = gpiodevice_release;
-       get_device(&gdev->dev);
-       pr_debug("%s: registered GPIOs %d to %d on device: %s (%s)\n",
-                __func__, gdev->base, gdev->base + gdev->ngpio - 1,
-                dev_name(&gdev->dev), chip->label ? : "generic");
-
+       if (gpiolib_initialized) {
+               status = gpiochip_setup_dev(gdev);
+               if (status)
+                       goto err_remove_chip;
+       }
        return 0;
 
-err_remove_device:
-       device_del(&gdev->dev);
-err_remove_chardev:
-       cdev_del(&gdev->chrdev);
 err_remove_chip:
        acpi_gpiochip_remove(chip);
        gpiochip_free_hogs(chip);
@@ -637,6 +671,10 @@ err_remove_from_list:
        spin_lock_irqsave(&gpio_lock, flags);
        list_del(&gdev->list);
        spin_unlock_irqrestore(&gpio_lock, flags);
+err_free_label:
+       kfree(gdev->label);
+err_free_descs:
+       kfree(gdev->descs);
 err_free_gdev:
        ida_simple_remove(&gpio_ida, gdev->id);
        /* failures here can mean systems won't boot... */
@@ -2231,9 +2269,11 @@ static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
        return desc;
 }
 
-static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id,
+static struct gpio_desc *acpi_find_gpio(struct device *dev,
+                                       const char *con_id,
                                        unsigned int idx,
-                                       enum gpio_lookup_flags *flags)
+                                       enum gpiod_flags flags,
+                                       enum gpio_lookup_flags *lookupflags)
 {
        struct acpi_device *adev = ACPI_COMPANION(dev);
        struct acpi_gpio_info info;
@@ -2264,10 +2304,16 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id,
                desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info);
                if (IS_ERR(desc))
                        return desc;
+
+               if ((flags == GPIOD_OUT_LOW || flags == GPIOD_OUT_HIGH) &&
+                   info.gpioint) {
+                       dev_dbg(dev, "refusing GpioInt() entry when doing GPIOD_OUT_* lookup\n");
+                       return ERR_PTR(-ENOENT);
+               }
        }
 
        if (info.polarity == GPIO_ACTIVE_LOW)
-               *flags |= GPIO_ACTIVE_LOW;
+               *lookupflags |= GPIO_ACTIVE_LOW;
 
        return desc;
 }
@@ -2530,7 +2576,7 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
                        desc = of_find_gpio(dev, con_id, idx, &lookupflags);
                } else if (ACPI_COMPANION(dev)) {
                        dev_dbg(dev, "using ACPI for GPIO lookup\n");
-                       desc = acpi_find_gpio(dev, con_id, idx, &lookupflags);
+                       desc = acpi_find_gpio(dev, con_id, idx, flags, &lookupflags);
                }
        }
 
@@ -2829,6 +2875,9 @@ static int __init gpiolib_dev_init(void)
        if (ret < 0) {
                pr_err("gpiolib: failed to allocate char dev region\n");
                bus_unregister(&gpio_bus_type);
+       } else {
+               gpiolib_initialized = true;
+               gpiochip_setup_devs();
        }
        return ret;
 }
index c4a21c6428f5f526289c1da50b77d4a77157fe60..62a778012fe06cc572964b463f873c987ca34755 100644 (file)
@@ -1591,6 +1591,7 @@ struct amdgpu_uvd {
        struct amdgpu_bo        *vcpu_bo;
        void                    *cpu_addr;
        uint64_t                gpu_addr;
+       void                    *saved_bo;
        atomic_t                handles[AMDGPU_MAX_UVD_HANDLES];
        struct drm_file         *filp[AMDGPU_MAX_UVD_HANDLES];
        struct delayed_work     idle_work;
index 7a4b101e10c63564aa3b0b8fffc638c171c1d199..6043dc7c3a94d75350a6e8760376b772f0fc4baf 100644 (file)
@@ -816,10 +816,13 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
        struct drm_device *ddev = adev->ddev;
        struct drm_crtc *crtc;
        uint32_t line_time_us, vblank_lines;
+       struct cgs_mode_info *mode_info;
 
        if (info == NULL)
                return -EINVAL;
 
+       mode_info = info->mode_info;
+
        if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
                list_for_each_entry(crtc,
                                &ddev->mode_config.crtc_list, head) {
@@ -828,7 +831,7 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
                                info->active_display_mask |= (1 << amdgpu_crtc->crtc_id);
                                info->display_count++;
                        }
-                       if (info->mode_info != NULL &&
+                       if (mode_info != NULL &&
                                crtc->enabled && amdgpu_crtc->enabled &&
                                amdgpu_crtc->hw_mode.clock) {
                                line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) /
@@ -836,10 +839,10 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
                                vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
                                                        amdgpu_crtc->hw_mode.crtc_vdisplay +
                                                        (amdgpu_crtc->v_border * 2);
-                               info->mode_info->vblank_time_us = vblank_lines * line_time_us;
-                               info->mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
-                               info->mode_info->ref_clock = adev->clock.spll.reference_freq;
-                               info->mode_info++;
+                               mode_info->vblank_time_us = vblank_lines * line_time_us;
+                               mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
+                               mode_info->ref_clock = adev->clock.spll.reference_freq;
+                               mode_info = NULL;
                        }
                }
        }
@@ -847,6 +850,16 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
        return 0;
 }
 
+
+static int amdgpu_cgs_notify_dpm_enabled(void *cgs_device, bool enabled)
+{
+       CGS_FUNC_ADEV;
+
+       adev->pm.dpm_enabled = enabled;
+
+       return 0;
+}
+
 /** \brief evaluate acpi namespace object, handle or pathname must be valid
  *  \param cgs_device
  *  \param info input/output arguments for the control method
@@ -1097,6 +1110,7 @@ static const struct cgs_ops amdgpu_cgs_ops = {
        amdgpu_cgs_set_powergating_state,
        amdgpu_cgs_set_clockgating_state,
        amdgpu_cgs_get_active_displays_info,
+       amdgpu_cgs_notify_dpm_enabled,
        amdgpu_cgs_call_acpi_method,
        amdgpu_cgs_query_system_info,
 };
index f0ed974bd4e090f65881d5f3604475d7e44f38ee..3fb405b3a61457e4622dfe4b788ac3925d088f4a 100644 (file)
@@ -57,7 +57,7 @@ static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work,
        if (!fence_add_callback(fence, &work->cb, amdgpu_flip_callback))
                return true;
 
-       fence_put(*f);
+       fence_put(fence);
        return false;
 }
 
index 4303b447efe898145433985079a6cd10273acc81..d81f1f4883a6c4b1adff92ba0c32b52f1999b2fd 100644 (file)
@@ -121,7 +121,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f)
 {
        struct amdgpu_device *adev = ring->adev;
        struct amdgpu_fence *fence;
-       struct fence **ptr;
+       struct fence *old, **ptr;
        uint32_t seq;
 
        fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL);
@@ -141,7 +141,11 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f)
        /* This function can't be called concurrently anyway, otherwise
         * emitting the fence would mess up the hardware ring buffer.
         */
-       BUG_ON(rcu_dereference_protected(*ptr, 1));
+       old = rcu_dereference_protected(*ptr, 1);
+       if (old && !fence_is_signaled(old)) {
+               DRM_INFO("rcu slot is busy\n");
+               fence_wait(old, false);
+       }
 
        rcu_assign_pointer(*ptr, fence_get(&fence->base));
 
index f594cfaa97e513f0bc6d436e26430abc8783e5ce..762cfdb85147471855418fff997877951d4aca6d 100644 (file)
@@ -219,6 +219,8 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
        if (r) {
                return r;
        }
+       adev->ddev->vblank_disable_allowed = true;
+
        /* enable msi */
        adev->irq.msi_enabled = false;
 
index 7805a8706af7bfb9cde33e30a5761db9eab0abd4..598eb0cd5aab6a1b437ad04d0c58dce24adc8d9d 100644 (file)
@@ -382,6 +382,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
                struct drm_amdgpu_info_vram_gtt vram_gtt;
 
                vram_gtt.vram_size = adev->mc.real_vram_size;
+               vram_gtt.vram_size -= adev->vram_pin_size;
                vram_gtt.vram_cpu_accessible_size = adev->mc.visible_vram_size;
                vram_gtt.vram_cpu_accessible_size -= adev->vram_pin_size;
                vram_gtt.gtt_size  = adev->mc.gtt_size;
index 56d1458393ccfd86992be99d5b19db235ac40f11..5b6639faa731e83b1b14c07bf673aa30deff52c8 100644 (file)
@@ -476,6 +476,17 @@ int amdgpu_bo_evict_vram(struct amdgpu_device *adev)
        return ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_VRAM);
 }
 
+static const char *amdgpu_vram_names[] = {
+       "UNKNOWN",
+       "GDDR1",
+       "DDR2",
+       "GDDR3",
+       "GDDR4",
+       "GDDR5",
+       "HBM",
+       "DDR3"
+};
+
 int amdgpu_bo_init(struct amdgpu_device *adev)
 {
        /* Add an MTRR for the VRAM */
@@ -484,8 +495,8 @@ int amdgpu_bo_init(struct amdgpu_device *adev)
        DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n",
                adev->mc.mc_vram_size >> 20,
                (unsigned long long)adev->mc.aper_size >> 20);
-       DRM_INFO("RAM width %dbits DDR\n",
-                       adev->mc.vram_width);
+       DRM_INFO("RAM width %dbits %s\n",
+                adev->mc.vram_width, amdgpu_vram_names[adev->mc.vram_type]);
        return amdgpu_ttm_init(adev);
 }
 
index 3cb6d6c413c71b0207fe1766d26ca190a083e880..e9c6ae6ed2f73357d762f9aa75406c010238dd4a 100644 (file)
@@ -143,7 +143,7 @@ static int amdgpu_pp_late_init(void *handle)
                                        adev->powerplay.pp_handle);
 
 #ifdef CONFIG_DRM_AMD_POWERPLAY
-       if (adev->pp_enabled) {
+       if (adev->pp_enabled && adev->pm.dpm_enabled) {
                amdgpu_pm_sysfs_init(adev);
                amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL);
        }
@@ -161,12 +161,8 @@ static int amdgpu_pp_sw_init(void *handle)
                                        adev->powerplay.pp_handle);
 
 #ifdef CONFIG_DRM_AMD_POWERPLAY
-       if (adev->pp_enabled) {
-               if (amdgpu_dpm == 0)
-                       adev->pm.dpm_enabled = false;
-               else
-                       adev->pm.dpm_enabled = true;
-       }
+       if (adev->pp_enabled)
+               adev->pm.dpm_enabled = true;
 #endif
 
        return ret;
index c1a5810444174522193111d9a41ff26d6fc0eb16..338da80006b66ced7671b5ed63fabb02750355ba 100644 (file)
@@ -241,32 +241,28 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
 
 int amdgpu_uvd_suspend(struct amdgpu_device *adev)
 {
-       struct amdgpu_ring *ring = &adev->uvd.ring;
-       int i, r;
+       unsigned size;
+       void *ptr;
+       int i;
 
        if (adev->uvd.vcpu_bo == NULL)
                return 0;
 
-       for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) {
-               uint32_t handle = atomic_read(&adev->uvd.handles[i]);
-               if (handle != 0) {
-                       struct fence *fence;
+       for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i)
+               if (atomic_read(&adev->uvd.handles[i]))
+                       break;
 
-                       amdgpu_uvd_note_usage(adev);
+       if (i == AMDGPU_MAX_UVD_HANDLES)
+               return 0;
 
-                       r = amdgpu_uvd_get_destroy_msg(ring, handle, false, &fence);
-                       if (r) {
-                               DRM_ERROR("Error destroying UVD (%d)!\n", r);
-                               continue;
-                       }
+       size = amdgpu_bo_size(adev->uvd.vcpu_bo);
+       ptr = adev->uvd.cpu_addr;
 
-                       fence_wait(fence, false);
-                       fence_put(fence);
+       adev->uvd.saved_bo = kmalloc(size, GFP_KERNEL);
+       if (!adev->uvd.saved_bo)
+               return -ENOMEM;
 
-                       adev->uvd.filp[i] = NULL;
-                       atomic_set(&adev->uvd.handles[i], 0);
-               }
-       }
+       memcpy(adev->uvd.saved_bo, ptr, size);
 
        return 0;
 }
@@ -275,23 +271,29 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
 {
        unsigned size;
        void *ptr;
-       const struct common_firmware_header *hdr;
-       unsigned offset;
 
        if (adev->uvd.vcpu_bo == NULL)
                return -EINVAL;
 
-       hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
-       offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
-       memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset,
-               (adev->uvd.fw->size) - offset);
-
        size = amdgpu_bo_size(adev->uvd.vcpu_bo);
-       size -= le32_to_cpu(hdr->ucode_size_bytes);
        ptr = adev->uvd.cpu_addr;
-       ptr += le32_to_cpu(hdr->ucode_size_bytes);
 
-       memset(ptr, 0, size);
+       if (adev->uvd.saved_bo != NULL) {
+               memcpy(ptr, adev->uvd.saved_bo, size);
+               kfree(adev->uvd.saved_bo);
+               adev->uvd.saved_bo = NULL;
+       } else {
+               const struct common_firmware_header *hdr;
+               unsigned offset;
+
+               hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
+               offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
+               memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset,
+                       (adev->uvd.fw->size) - offset);
+               size -= le32_to_cpu(hdr->ucode_size_bytes);
+               ptr += le32_to_cpu(hdr->ucode_size_bytes);
+               memset(ptr, 0, size);
+       }
 
        return 0;
 }
index 82ce7d9438843283d6afd1d7eb764fb26de266ae..05b0353d3880092271da1115007ae7ce91e4e69b 100644 (file)
@@ -903,14 +903,6 @@ static int gmc_v7_0_early_init(void *handle)
        gmc_v7_0_set_gart_funcs(adev);
        gmc_v7_0_set_irq_funcs(adev);
 
-       if (adev->flags & AMD_IS_APU) {
-               adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
-       } else {
-               u32 tmp = RREG32(mmMC_SEQ_MISC0);
-               tmp &= MC_SEQ_MISC0__MT__MASK;
-               adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp);
-       }
-
        return 0;
 }
 
@@ -927,6 +919,14 @@ static int gmc_v7_0_sw_init(void *handle)
        int dma_bits;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+       if (adev->flags & AMD_IS_APU) {
+               adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
+       } else {
+               u32 tmp = RREG32(mmMC_SEQ_MISC0);
+               tmp &= MC_SEQ_MISC0__MT__MASK;
+               adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp);
+       }
+
        r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault);
        if (r)
                return r;
index 29bd7b57dc912be1b33fdc06ce7ab8944527c804..02deb322940565baa6d1d3e3f648fe7cf152e6aa 100644 (file)
@@ -863,14 +863,6 @@ static int gmc_v8_0_early_init(void *handle)
        gmc_v8_0_set_gart_funcs(adev);
        gmc_v8_0_set_irq_funcs(adev);
 
-       if (adev->flags & AMD_IS_APU) {
-               adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
-       } else {
-               u32 tmp = RREG32(mmMC_SEQ_MISC0);
-               tmp &= MC_SEQ_MISC0__MT__MASK;
-               adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp);
-       }
-
        return 0;
 }
 
@@ -881,12 +873,27 @@ static int gmc_v8_0_late_init(void *handle)
        return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0);
 }
 
+#define mmMC_SEQ_MISC0_FIJI 0xA71
+
 static int gmc_v8_0_sw_init(void *handle)
 {
        int r;
        int dma_bits;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+       if (adev->flags & AMD_IS_APU) {
+               adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
+       } else {
+               u32 tmp;
+
+               if (adev->asic_type == CHIP_FIJI)
+                       tmp = RREG32(mmMC_SEQ_MISC0_FIJI);
+               else
+                       tmp = RREG32(mmMC_SEQ_MISC0);
+               tmp &= MC_SEQ_MISC0__MT__MASK;
+               adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp);
+       }
+
        r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault);
        if (r)
                return r;
index c606ccb38d8b98bd8e05fd588352102cd3601cbc..cb463753115b8d4f8266464a9d69956be21a5750 100644 (file)
@@ -224,11 +224,11 @@ static int uvd_v4_2_suspend(void *handle)
        int r;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       r = amdgpu_uvd_suspend(adev);
+       r = uvd_v4_2_hw_fini(adev);
        if (r)
                return r;
 
-       r = uvd_v4_2_hw_fini(adev);
+       r = amdgpu_uvd_suspend(adev);
        if (r)
                return r;
 
index e3c852d9d79a45285c0dcb9445e43896be763eae..16476d80f475a77c17ae4bb8a5f60aa05c4562c8 100644 (file)
@@ -220,11 +220,11 @@ static int uvd_v5_0_suspend(void *handle)
        int r;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       r = amdgpu_uvd_suspend(adev);
+       r = uvd_v5_0_hw_fini(adev);
        if (r)
                return r;
 
-       r = uvd_v5_0_hw_fini(adev);
+       r = amdgpu_uvd_suspend(adev);
        if (r)
                return r;
 
index 3375e614ac67121f5832f56e0e480a1166601481..d49379145ef22e8468866a1b60bb17d40ebb5e70 100644 (file)
@@ -214,15 +214,16 @@ static int uvd_v6_0_suspend(void *handle)
        int r;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+       r = uvd_v6_0_hw_fini(adev);
+       if (r)
+               return r;
+
        /* Skip this for APU for now */
        if (!(adev->flags & AMD_IS_APU)) {
                r = amdgpu_uvd_suspend(adev);
                if (r)
                        return r;
        }
-       r = uvd_v6_0_hw_fini(adev);
-       if (r)
-               return r;
 
        return r;
 }
index aec38fc3834f9d867b4477c2f1d1d1166285f1fe..ab84d494724774d77100756c85c6d2a689b25516 100644 (file)
@@ -589,6 +589,8 @@ typedef int(*cgs_get_active_displays_info)(
                                        void *cgs_device,
                                        struct cgs_display_info *info);
 
+typedef int (*cgs_notify_dpm_enabled)(void *cgs_device, bool enabled);
+
 typedef int (*cgs_call_acpi_method)(void *cgs_device,
                                        uint32_t acpi_method,
                                        uint32_t acpi_function,
@@ -644,6 +646,8 @@ struct cgs_ops {
        cgs_set_clockgating_state set_clockgating_state;
        /* display manager */
        cgs_get_active_displays_info get_active_displays_info;
+       /* notify dpm enabled */
+       cgs_notify_dpm_enabled notify_dpm_enabled;
        /* ACPI */
        cgs_call_acpi_method call_acpi_method;
        /* get system info */
@@ -734,8 +738,12 @@ struct cgs_device
        CGS_CALL(set_powergating_state, dev, block_type, state)
 #define cgs_set_clockgating_state(dev, block_type, state)      \
        CGS_CALL(set_clockgating_state, dev, block_type, state)
+#define cgs_notify_dpm_enabled(dev, enabled)   \
+       CGS_CALL(notify_dpm_enabled, dev, enabled)
+
 #define cgs_get_active_displays_info(dev, info)        \
        CGS_CALL(get_active_displays_info, dev, info)
+
 #define cgs_call_acpi_method(dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size) \
        CGS_CALL(call_acpi_method, dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size)
 #define cgs_query_system_info(dev, sys_info)   \
index 6b52c78cb404870ae019b3cd262f7d9711b590b3..56856a2864d108c89cb2a961398f8f3613159fcc 100644 (file)
@@ -137,14 +137,14 @@ static const pem_event_action *resume_event[] = {
        reset_display_configCounter_tasks,
        update_dal_configuration_tasks,
        vari_bright_resume_tasks,
-       block_adjust_power_state_tasks,
        setup_asic_tasks,
        enable_stutter_mode_tasks, /*must do this in boot state and before SMC is started */
        enable_dynamic_state_management_tasks,
        enable_clock_power_gatings_tasks,
        enable_disable_bapm_tasks,
        initialize_thermal_controller_tasks,
-       reset_boot_state_tasks,
+       get_2d_performance_state_tasks,
+       set_performance_state_tasks,
        adjust_power_state_tasks,
        enable_disable_fps_tasks,
        notify_hw_power_source_tasks,
index 51dedf84623c6b7473e3c753143e95fa7791e1e8..89f31bc5b68b9e061d31a2fb2494c7e4f60d276f 100644 (file)
@@ -2389,6 +2389,7 @@ static int fiji_populate_smc_vce_level(struct pp_hwmgr *hwmgr,
 
        for(count = 0; count < table->VceLevelCount; count++) {
                table->VceLevel[count].Frequency = mm_table->entries[count].eclk;
+               table->VceLevel[count].MinVoltage = 0;
                table->VceLevel[count].MinVoltage |=
                                (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT;
                table->VceLevel[count].MinVoltage |=
@@ -2465,6 +2466,7 @@ static int fiji_populate_smc_samu_level(struct pp_hwmgr *hwmgr,
 
        for (count = 0; count < table->SamuLevelCount; count++) {
                /* not sure whether we need evclk or not */
+               table->SamuLevel[count].MinVoltage = 0;
                table->SamuLevel[count].Frequency = mm_table->entries[count].samclock;
                table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
                                VOLTAGE_SCALE) << VDDC_SHIFT;
@@ -2562,6 +2564,7 @@ static int fiji_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
        table->UvdBootLevel = 0;
 
        for (count = 0; count < table->UvdLevelCount; count++) {
+               table->UvdLevel[count].MinVoltage = 0;
                table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk;
                table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk;
                table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
@@ -2900,6 +2903,8 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr)
        if(FIJI_VOLTAGE_CONTROL_NONE != data->voltage_control)
                fiji_populate_smc_voltage_tables(hwmgr, table);
 
+       table->SystemFlags = 0;
+
        if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
                        PHM_PlatformCaps_AutomaticDCTransition))
                table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
@@ -2997,6 +3002,7 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr)
        table->MemoryThermThrottleEnable = 1;
        table->PCIeBootLinkLevel = 0;      /* 0:Gen1 1:Gen2 2:Gen3*/
        table->PCIeGenInterval = 1;
+       table->VRConfig = 0;
 
        result = fiji_populate_vr_config(hwmgr, table);
        PP_ASSERT_WITH_CODE(0 == result,
@@ -5195,6 +5201,67 @@ static int fiji_print_clock_levels(struct pp_hwmgr *hwmgr,
        return size;
 }
 
+static inline bool fiji_are_power_levels_equal(const struct fiji_performance_level *pl1,
+                                                          const struct fiji_performance_level *pl2)
+{
+       return ((pl1->memory_clock == pl2->memory_clock) &&
+                 (pl1->engine_clock == pl2->engine_clock) &&
+                 (pl1->pcie_gen == pl2->pcie_gen) &&
+                 (pl1->pcie_lane == pl2->pcie_lane));
+}
+
+int fiji_check_states_equal(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *pstate1, const struct pp_hw_power_state *pstate2, bool *equal)
+{
+       const struct fiji_power_state *psa = cast_const_phw_fiji_power_state(pstate1);
+       const struct fiji_power_state *psb = cast_const_phw_fiji_power_state(pstate2);
+       int i;
+
+       if (equal == NULL || psa == NULL || psb == NULL)
+               return -EINVAL;
+
+       /* If the two states don't even have the same number of performance levels they cannot be the same state. */
+       if (psa->performance_level_count != psb->performance_level_count) {
+               *equal = false;
+               return 0;
+       }
+
+       for (i = 0; i < psa->performance_level_count; i++) {
+               if (!fiji_are_power_levels_equal(&(psa->performance_levels[i]), &(psb->performance_levels[i]))) {
+                       /* If we have found even one performance level pair that is different the states are different. */
+                       *equal = false;
+                       return 0;
+               }
+       }
+
+       /* If all performance levels are the same try to use the UVD clocks to break the tie.*/
+       *equal = ((psa->uvd_clks.vclk == psb->uvd_clks.vclk) && (psa->uvd_clks.dclk == psb->uvd_clks.dclk));
+       *equal &= ((psa->vce_clks.evclk == psb->vce_clks.evclk) && (psa->vce_clks.ecclk == psb->vce_clks.ecclk));
+       *equal &= (psa->sclk_threshold == psb->sclk_threshold);
+       *equal &= (psa->acp_clk == psb->acp_clk);
+
+       return 0;
+}
+
+bool fiji_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr)
+{
+       struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
+       bool is_update_required = false;
+       struct cgs_display_info info = {0,0,NULL};
+
+       cgs_get_active_displays_info(hwmgr->device, &info);
+
+       if (data->display_timing.num_existing_displays != info.display_count)
+               is_update_required = true;
+/* TO DO NEED TO GET DEEP SLEEP CLOCK FROM DAL
+       if (phm_cap_enabled(hwmgr->hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) {
+               cgs_get_min_clock_settings(hwmgr->device, &min_clocks);
+               if(min_clocks.engineClockInSR != data->display_timing.minClockInSR)
+                       is_update_required = true;
+*/
+       return is_update_required;
+}
+
+
 static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
        .backend_init = &fiji_hwmgr_backend_init,
        .backend_fini = &tonga_hwmgr_backend_fini,
@@ -5230,6 +5297,8 @@ static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
        .register_internal_thermal_interrupt = fiji_register_internal_thermal_interrupt,
        .set_fan_control_mode = fiji_set_fan_control_mode,
        .get_fan_control_mode = fiji_get_fan_control_mode,
+       .check_states_equal = fiji_check_states_equal,
+       .check_smc_update_required_for_display_configuration = fiji_check_smc_update_required_for_display_configuration,
        .get_pp_table = fiji_get_pp_table,
        .set_pp_table = fiji_set_pp_table,
        .force_clock_level = fiji_force_clock_level,
index be31bed2538ade909b95b4cc95c6c24602466c35..fa208ada689219f4eb072ebb5e655e0a03cc9ab7 100644 (file)
@@ -58,6 +58,9 @@ void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr)
 
        phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VpuRecoveryInProgress);
 
+       phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM);
+       phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEDPM);
+
        if (acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST) &&
                acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION))
                phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
@@ -130,18 +133,25 @@ int phm_set_power_state(struct pp_hwmgr *hwmgr,
 
 int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr)
 {
+       int ret = 1;
+       bool enabled;
        PHM_FUNC_CHECK(hwmgr);
 
        if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
                PHM_PlatformCaps_TablelessHardwareInterface)) {
                if (NULL != hwmgr->hwmgr_func->dynamic_state_management_enable)
-                       return hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr);
+                       ret = hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr);
        } else {
-               return phm_dispatch_table(hwmgr,
+               ret = phm_dispatch_table(hwmgr,
                                &(hwmgr->enable_dynamic_state_management),
                                NULL, NULL);
        }
-       return 0;
+
+       enabled = ret == 0 ? true : false;
+
+       cgs_notify_dpm_enabled(hwmgr->device, enabled);
+
+       return ret;
 }
 
 int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level)
index 56b829f9769952e08aee6938bc26af6d74c3ccb5..3ac1ae4d8cafb69993035ab505727c3d127cc962 100644 (file)
@@ -57,14 +57,13 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
                DRM_ERROR("failed to map control registers area\n");
                ret = PTR_ERR(hdlcd->mmio);
                hdlcd->mmio = NULL;
-               goto fail;
+               return ret;
        }
 
        version = hdlcd_read(hdlcd, HDLCD_REG_VERSION);
        if ((version & HDLCD_PRODUCT_MASK) != HDLCD_PRODUCT_ID) {
                DRM_ERROR("unknown product id: 0x%x\n", version);
-               ret = -EINVAL;
-               goto fail;
+               return -EINVAL;
        }
        DRM_INFO("found ARM HDLCD version r%dp%d\n",
                (version & HDLCD_VERSION_MAJOR_MASK) >> 8,
@@ -73,7 +72,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
        /* Get the optional framebuffer memory resource */
        ret = of_reserved_mem_device_init(drm->dev);
        if (ret && ret != -ENODEV)
-               goto fail;
+               return ret;
 
        ret = dma_set_mask_and_coherent(drm->dev, DMA_BIT_MASK(32));
        if (ret)
@@ -101,8 +100,6 @@ irq_fail:
        drm_crtc_cleanup(&hdlcd->crtc);
 setup_fail:
        of_reserved_mem_device_release(drm->dev);
-fail:
-       devm_clk_put(drm->dev, hdlcd->clk);
 
        return ret;
 }
@@ -412,7 +409,6 @@ err_unload:
        pm_runtime_put_sync(drm->dev);
        pm_runtime_disable(drm->dev);
        of_reserved_mem_device_release(drm->dev);
-       devm_clk_put(dev, hdlcd->clk);
 err_free:
        drm_dev_unref(drm);
 
@@ -436,10 +432,6 @@ static void hdlcd_drm_unbind(struct device *dev)
        pm_runtime_put_sync(drm->dev);
        pm_runtime_disable(drm->dev);
        of_reserved_mem_device_release(drm->dev);
-       if (!IS_ERR(hdlcd->clk)) {
-               devm_clk_put(drm->dev, hdlcd->clk);
-               hdlcd->clk = NULL;
-       }
        drm_mode_config_cleanup(drm);
        drm_dev_unregister(drm);
        drm_dev_unref(drm);
index 2a95d10e9d928d45877d5491c0b94e6ec18711d3..a24631fdf4add310de0eeadc7001c6a12a711866 100644 (file)
@@ -225,8 +225,6 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
        if (!iores)
                return -ENXIO;
 
-       platform_set_drvdata(pdev, hdmi);
-
        encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
        /*
         * If we failed to find the CRTC(s) which this encoder is
@@ -245,7 +243,16 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
        drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs,
                         DRM_MODE_ENCODER_TMDS, NULL);
 
-       return dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data);
+       ret = dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data);
+
+       /*
+        * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
+        * which would have called the encoder cleanup.  Do it manually.
+        */
+       if (ret)
+               drm_encoder_cleanup(encoder);
+
+       return ret;
 }
 
 static void dw_hdmi_imx_unbind(struct device *dev, struct device *master,
index 9876e0f0c3e1833592308f1a8a38de5c3e44f2b0..e26dcdec2aba0e51233910c82f1788e49ea6f2ce 100644 (file)
@@ -326,7 +326,6 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
 {
        struct imx_drm_device *imxdrm = drm->dev_private;
        struct imx_drm_crtc *imx_drm_crtc;
-       int ret;
 
        /*
         * The vblank arrays are dimensioned by MAX_CRTC - we can't
@@ -351,10 +350,6 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
 
        *new_crtc = imx_drm_crtc;
 
-       ret = drm_mode_crtc_set_gamma_size(imx_drm_crtc->crtc, 256);
-       if (ret)
-               goto err_register;
-
        drm_crtc_helper_add(crtc,
                        imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs);
 
@@ -362,11 +357,6 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
                        imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs, NULL);
 
        return 0;
-
-err_register:
-       imxdrm->crtc[--imxdrm->pipes] = NULL;
-       kfree(imx_drm_crtc);
-       return ret;
 }
 EXPORT_SYMBOL_GPL(imx_drm_add_crtc);
 
index 588827844f30c7717b4afbb900de196411752990..681ec6eb77d916fc3be6a47d783fab54ed1f07fb 100644 (file)
@@ -72,22 +72,101 @@ static inline int calc_bandwidth(int width, int height, unsigned int vref)
 int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb,
                       int x, int y)
 {
-       struct drm_gem_cma_object *cma_obj;
-       unsigned long eba;
-       int active;
-
-       cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
-       if (!cma_obj) {
-               DRM_DEBUG_KMS("entry is null.\n");
-               return -EFAULT;
+       struct drm_gem_cma_object *cma_obj[3];
+       unsigned long eba, ubo, vbo;
+       int active, i;
+
+       for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
+               cma_obj[i] = drm_fb_cma_get_gem_obj(fb, i);
+               if (!cma_obj[i]) {
+                       DRM_DEBUG_KMS("plane %d entry is null.\n", i);
+                       return -EFAULT;
+               }
        }
 
-       dev_dbg(ipu_plane->base.dev->dev, "phys = %pad, x = %d, y = %d",
-               &cma_obj->paddr, x, y);
-
-       eba = cma_obj->paddr + fb->offsets[0] +
+       eba = cma_obj[0]->paddr + fb->offsets[0] +
              fb->pitches[0] * y + (fb->bits_per_pixel >> 3) * x;
 
+       if (eba & 0x7) {
+               DRM_DEBUG_KMS("base address must be a multiple of 8.\n");
+               return -EINVAL;
+       }
+
+       if (fb->pitches[0] < 1 || fb->pitches[0] > 16384) {
+               DRM_DEBUG_KMS("pitches out of range.\n");
+               return -EINVAL;
+       }
+
+       if (ipu_plane->enabled && fb->pitches[0] != ipu_plane->stride[0]) {
+               DRM_DEBUG_KMS("pitches must not change while plane is enabled.\n");
+               return -EINVAL;
+       }
+
+       ipu_plane->stride[0] = fb->pitches[0];
+
+       switch (fb->pixel_format) {
+       case DRM_FORMAT_YUV420:
+       case DRM_FORMAT_YVU420:
+               /*
+                * Multiplanar formats have to meet the following restrictions:
+                * - The (up to) three plane addresses are EBA, EBA+UBO, EBA+VBO
+                * - EBA, UBO and VBO are a multiple of 8
+                * - UBO and VBO are unsigned and not larger than 0xfffff8
+                * - Only EBA may be changed while scanout is active
+                * - The strides of U and V planes must be identical.
+                */
+               ubo = cma_obj[1]->paddr + fb->offsets[1] +
+                     fb->pitches[1] * y / 2 + x / 2 - eba;
+               vbo = cma_obj[2]->paddr + fb->offsets[2] +
+                     fb->pitches[2] * y / 2 + x / 2 - eba;
+
+               if ((ubo & 0x7) || (vbo & 0x7)) {
+                       DRM_DEBUG_KMS("U/V buffer offsets must be a multiple of 8.\n");
+                       return -EINVAL;
+               }
+
+               if ((ubo > 0xfffff8) || (vbo > 0xfffff8)) {
+                       DRM_DEBUG_KMS("U/V buffer offsets must be positive and not larger than 0xfffff8.\n");
+                       return -EINVAL;
+               }
+
+               if (ipu_plane->enabled && ((ipu_plane->u_offset != ubo) ||
+                                          (ipu_plane->v_offset != vbo))) {
+                       DRM_DEBUG_KMS("U/V buffer offsets must not change while plane is enabled.\n");
+                       return -EINVAL;
+               }
+
+               if (fb->pitches[1] != fb->pitches[2]) {
+                       DRM_DEBUG_KMS("U/V pitches must be identical.\n");
+                       return -EINVAL;
+               }
+
+               if (fb->pitches[1] < 1 || fb->pitches[1] > 16384) {
+                       DRM_DEBUG_KMS("U/V pitches out of range.\n");
+                       return -EINVAL;
+               }
+
+               if (ipu_plane->enabled &&
+                   (ipu_plane->stride[1] != fb->pitches[1])) {
+                       DRM_DEBUG_KMS("U/V pitches must not change while plane is enabled.\n");
+                       return -EINVAL;
+               }
+
+               ipu_plane->u_offset = ubo;
+               ipu_plane->v_offset = vbo;
+               ipu_plane->stride[1] = fb->pitches[1];
+
+               dev_dbg(ipu_plane->base.dev->dev,
+                       "phys = %pad %pad %pad, x = %d, y = %d",
+                       &cma_obj[0]->paddr, &cma_obj[1]->paddr,
+                       &cma_obj[2]->paddr, x, y);
+               break;
+       default:
+               dev_dbg(ipu_plane->base.dev->dev, "phys = %pad, x = %d, y = %d",
+                       &cma_obj[0]->paddr, x, y);
+               break;
+       }
+
        if (ipu_plane->enabled) {
                active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch);
                ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba);
@@ -201,12 +280,6 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc,
                }
        }
 
-       ret = ipu_dmfc_init_channel(ipu_plane->dmfc, crtc_w);
-       if (ret) {
-               dev_err(dev, "initializing dmfc channel failed with %d\n", ret);
-               return ret;
-       }
-
        ret = ipu_dmfc_alloc_bandwidth(ipu_plane->dmfc,
                        calc_bandwidth(crtc_w, crtc_h,
                                       calc_vref(mode)), 64);
@@ -215,6 +288,8 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc,
                return ret;
        }
 
+       ipu_dmfc_config_wait4eot(ipu_plane->dmfc, crtc_w);
+
        ipu_cpmem_zero(ipu_plane->ipu_ch);
        ipu_cpmem_set_resolution(ipu_plane->ipu_ch, src_w, src_h);
        ret = ipu_cpmem_set_fmt(ipu_plane->ipu_ch, fb->pixel_format);
@@ -233,6 +308,18 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc,
        if (interlaced)
                ipu_cpmem_interlaced_scan(ipu_plane->ipu_ch, fb->pitches[0]);
 
+       if (fb->pixel_format == DRM_FORMAT_YUV420) {
+               ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch,
+                                             ipu_plane->stride[1],
+                                             ipu_plane->u_offset,
+                                             ipu_plane->v_offset);
+       } else if (fb->pixel_format == DRM_FORMAT_YVU420) {
+               ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch,
+                                             ipu_plane->stride[1],
+                                             ipu_plane->v_offset,
+                                             ipu_plane->u_offset);
+       }
+
        ipu_plane->w = src_w;
        ipu_plane->h = src_h;
 
index 3a443b413c60caa9734883f7aaa95a69bb7f3e29..4448fd4ad4eb503422a750f374c6b20a64b9f643 100644 (file)
@@ -29,6 +29,10 @@ struct ipu_plane {
        int                     w;
        int                     h;
 
+       unsigned int            u_offset;
+       unsigned int            v_offset;
+       unsigned int            stride[2];
+
        bool                    enabled;
 };
 
index 16641cec18a28dbb1a5af0dd344313eea56b7646..b5370cb56e3c2c4fbb539ffd9f0156c569af38c1 100644 (file)
@@ -11,6 +11,7 @@ struct nvkm_device_tegra {
 
        struct reset_control *rst;
        struct clk *clk;
+       struct clk *clk_ref;
        struct clk *clk_pwr;
 
        struct regulator *vdd;
@@ -36,6 +37,10 @@ struct nvkm_device_tegra_func {
         * bypassed). A value of 0 means an IOMMU is never used.
         */
        u8 iommu_bit;
+       /*
+        * Whether the chip requires a reference clock
+        */
+       bool require_ref_clk;
 };
 
 int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *,
index 2dfe58af12e4ee05103d14946dc4a0d001f7f9c6..4c4cc2260257cc1f8fb84f954ab6449d6f11c277 100644 (file)
@@ -55,6 +55,11 @@ static const struct nvkm_device_tegra_func gk20a_platform_data = {
        .iommu_bit = 34,
 };
 
+static const struct nvkm_device_tegra_func gm20b_platform_data = {
+       .iommu_bit = 34,
+       .require_ref_clk = true,
+};
+
 static const struct of_device_id nouveau_platform_match[] = {
        {
                .compatible = "nvidia,gk20a",
@@ -62,7 +67,7 @@ static const struct of_device_id nouveau_platform_match[] = {
        },
        {
                .compatible = "nvidia,gm20b",
-               .data = &gk20a_platform_data,
+               .data = &gm20b_platform_data,
        },
        { }
 };
index 9afa5f3e3c1c2d23e57ba076025bc8de1c2d2e25..ec12efb4689a7ea8a50fd7ee8626f5df4440f0a3 100644 (file)
@@ -35,6 +35,11 @@ nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev)
        ret = clk_prepare_enable(tdev->clk);
        if (ret)
                goto err_clk;
+       if (tdev->clk_ref) {
+               ret = clk_prepare_enable(tdev->clk_ref);
+               if (ret)
+                       goto err_clk_ref;
+       }
        ret = clk_prepare_enable(tdev->clk_pwr);
        if (ret)
                goto err_clk_pwr;
@@ -57,6 +62,9 @@ nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev)
 err_clamp:
        clk_disable_unprepare(tdev->clk_pwr);
 err_clk_pwr:
+       if (tdev->clk_ref)
+               clk_disable_unprepare(tdev->clk_ref);
+err_clk_ref:
        clk_disable_unprepare(tdev->clk);
 err_clk:
        regulator_disable(tdev->vdd);
@@ -71,6 +79,8 @@ nvkm_device_tegra_power_down(struct nvkm_device_tegra *tdev)
        udelay(10);
 
        clk_disable_unprepare(tdev->clk_pwr);
+       if (tdev->clk_ref)
+               clk_disable_unprepare(tdev->clk_ref);
        clk_disable_unprepare(tdev->clk);
        udelay(10);
 
@@ -274,6 +284,13 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
                goto free;
        }
 
+       if (func->require_ref_clk)
+               tdev->clk_ref = devm_clk_get(&pdev->dev, "ref");
+       if (IS_ERR(tdev->clk_ref)) {
+               ret = PTR_ERR(tdev->clk_ref);
+               goto free;
+       }
+
        tdev->clk_pwr = devm_clk_get(&pdev->dev, "pwr");
        if (IS_ERR(tdev->clk_pwr)) {
                ret = PTR_ERR(tdev->clk_pwr);
index cf61e0856f4af2faa699118cf08bbf097cc24763..b80b08f71cb46e8d69d7bd94f6d951008267500e 100644 (file)
@@ -275,13 +275,15 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
                if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
                        atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
                atombios_blank_crtc(crtc, ATOM_DISABLE);
-               drm_vblank_on(dev, radeon_crtc->crtc_id);
+               if (dev->num_crtcs > radeon_crtc->crtc_id)
+                       drm_vblank_on(dev, radeon_crtc->crtc_id);
                radeon_crtc_load_lut(crtc);
                break;
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
-               drm_vblank_off(dev, radeon_crtc->crtc_id);
+               if (dev->num_crtcs > radeon_crtc->crtc_id)
+                       drm_vblank_off(dev, radeon_crtc->crtc_id);
                if (radeon_crtc->enabled)
                        atombios_blank_crtc(crtc, ATOM_ENABLE);
                if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
index 979f3bf65f2c474f231a26eb47af963d4436be0f..1e9304d1c88fd4e844ee9c5bd36300ed992e0f29 100644 (file)
@@ -291,6 +291,8 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
        if (r) {
                return r;
        }
+       rdev->ddev->vblank_disable_allowed = true;
+
        /* enable msi */
        rdev->msi_enabled = 0;
 
index 24152dfef19985bccc02b869853dd66f77d12e9e..478d4099b0d0e2b2d995d47bb74322ab46adf73b 100644 (file)
@@ -331,13 +331,15 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
                                                                         RADEON_CRTC_DISP_REQ_EN_B));
                        WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl));
                }
-               drm_vblank_on(dev, radeon_crtc->crtc_id);
+               if (dev->num_crtcs > radeon_crtc->crtc_id)
+                       drm_vblank_on(dev, radeon_crtc->crtc_id);
                radeon_crtc_load_lut(crtc);
                break;
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
-               drm_vblank_off(dev, radeon_crtc->crtc_id);
+               if (dev->num_crtcs > radeon_crtc->crtc_id)
+                       drm_vblank_off(dev, radeon_crtc->crtc_id);
                if (radeon_crtc->crtc_id)
                        WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask));
                else {
index 883a314cd83ae5841dc2fd14ba03bd9228297a09..6494a4d2817149e06e1ab241ccb10552d52dc553 100644 (file)
@@ -395,60 +395,48 @@ void ipu_cpmem_set_yuv_interleaved(struct ipuv3_channel *ch, u32 pixel_format)
 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_interleaved);
 
 void ipu_cpmem_set_yuv_planar_full(struct ipuv3_channel *ch,
-                                  u32 pixel_format, int stride,
-                                  int u_offset, int v_offset)
+                                  unsigned int uv_stride,
+                                  unsigned int u_offset, unsigned int v_offset)
 {
-       switch (pixel_format) {
-       case V4L2_PIX_FMT_YUV420:
-       case V4L2_PIX_FMT_YUV422P:
-               ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, (stride / 2) - 1);
-               ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_offset / 8);
-               ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_offset / 8);
-               break;
-       case V4L2_PIX_FMT_YVU420:
-               ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, (stride / 2) - 1);
-               ipu_ch_param_write_field(ch, IPU_FIELD_UBO, v_offset / 8);
-               ipu_ch_param_write_field(ch, IPU_FIELD_VBO, u_offset / 8);
-               break;
-       case V4L2_PIX_FMT_NV12:
-       case V4L2_PIX_FMT_NV16:
-               ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, stride - 1);
-               ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_offset / 8);
-               ipu_ch_param_write_field(ch, IPU_FIELD_VBO, u_offset / 8);
-               break;
-       }
+       ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, uv_stride - 1);
+       ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_offset / 8);
+       ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_offset / 8);
 }
 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full);
 
 void ipu_cpmem_set_yuv_planar(struct ipuv3_channel *ch,
                              u32 pixel_format, int stride, int height)
 {
-       int u_offset, v_offset;
+       int fourcc, u_offset, v_offset;
        int uv_stride = 0;
 
-       switch (pixel_format) {
-       case V4L2_PIX_FMT_YUV420:
-       case V4L2_PIX_FMT_YVU420:
+       fourcc = v4l2_pix_fmt_to_drm_fourcc(pixel_format);
+       switch (fourcc) {
+       case DRM_FORMAT_YUV420:
                uv_stride = stride / 2;
                u_offset = stride * height;
                v_offset = u_offset + (uv_stride * height / 2);
-               ipu_cpmem_set_yuv_planar_full(ch, pixel_format, stride,
-                                             u_offset, v_offset);
                break;
-       case V4L2_PIX_FMT_YUV422P:
+       case DRM_FORMAT_YVU420:
+               uv_stride = stride / 2;
+               v_offset = stride * height;
+               u_offset = v_offset + (uv_stride * height / 2);
+               break;
+       case DRM_FORMAT_YUV422:
                uv_stride = stride / 2;
                u_offset = stride * height;
                v_offset = u_offset + (uv_stride * height);
-               ipu_cpmem_set_yuv_planar_full(ch, pixel_format, stride,
-                                             u_offset, v_offset);
                break;
-       case V4L2_PIX_FMT_NV12:
-       case V4L2_PIX_FMT_NV16:
+       case DRM_FORMAT_NV12:
+       case DRM_FORMAT_NV16:
+               uv_stride = stride;
                u_offset = stride * height;
-               ipu_cpmem_set_yuv_planar_full(ch, pixel_format, stride,
-                                             u_offset, 0);
+               v_offset = 0;
                break;
+       default:
+               return;
        }
+       ipu_cpmem_set_yuv_planar_full(ch, uv_stride, u_offset, v_offset);
 }
 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar);
 
@@ -684,17 +672,25 @@ int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image)
 
        switch (pix->pixelformat) {
        case V4L2_PIX_FMT_YUV420:
-       case V4L2_PIX_FMT_YVU420:
                offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
                u_offset = U_OFFSET(pix, image->rect.left,
                                    image->rect.top) - offset;
                v_offset = V_OFFSET(pix, image->rect.left,
                                    image->rect.top) - offset;
 
-               ipu_cpmem_set_yuv_planar_full(ch, pix->pixelformat,
-                                             pix->bytesperline,
+               ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
                                              u_offset, v_offset);
                break;
+       case V4L2_PIX_FMT_YVU420:
+               offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
+               u_offset = U_OFFSET(pix, image->rect.left,
+                                   image->rect.top) - offset;
+               v_offset = V_OFFSET(pix, image->rect.left,
+                                   image->rect.top) - offset;
+
+               ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
+                                             v_offset, u_offset);
+               break;
        case V4L2_PIX_FMT_YUV422P:
                offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
                u_offset = U2_OFFSET(pix, image->rect.left,
@@ -702,8 +698,7 @@ int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image)
                v_offset = V2_OFFSET(pix, image->rect.left,
                                     image->rect.top) - offset;
 
-               ipu_cpmem_set_yuv_planar_full(ch, pix->pixelformat,
-                                             pix->bytesperline,
+               ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
                                              u_offset, v_offset);
                break;
        case V4L2_PIX_FMT_NV12:
@@ -712,8 +707,7 @@ int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image)
                                     image->rect.top) - offset;
                v_offset = 0;
 
-               ipu_cpmem_set_yuv_planar_full(ch, pix->pixelformat,
-                                             pix->bytesperline,
+               ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline,
                                              u_offset, v_offset);
                break;
        case V4L2_PIX_FMT_NV16:
@@ -722,8 +716,7 @@ int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image)
                                      image->rect.top) - offset;
                v_offset = 0;
 
-               ipu_cpmem_set_yuv_planar_full(ch, pix->pixelformat,
-                                             pix->bytesperline,
+               ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline,
                                              u_offset, v_offset);
                break;
        case V4L2_PIX_FMT_UYVY:
index 042c3958e2a099224b25cafd194e076b7150f67c..837b1ec228005ebf0b36a865d4f992588229dc0a 100644 (file)
@@ -350,11 +350,13 @@ out:
 }
 EXPORT_SYMBOL_GPL(ipu_dmfc_alloc_bandwidth);
 
-int ipu_dmfc_init_channel(struct dmfc_channel *dmfc, int width)
+void ipu_dmfc_config_wait4eot(struct dmfc_channel *dmfc, int width)
 {
        struct ipu_dmfc_priv *priv = dmfc->priv;
        u32 dmfc_gen1;
 
+       mutex_lock(&priv->mutex);
+
        dmfc_gen1 = readl(priv->base + DMFC_GENERAL1);
 
        if ((dmfc->slots * 64 * 4) / width > dmfc->data->max_fifo_lines)
@@ -364,9 +366,9 @@ int ipu_dmfc_init_channel(struct dmfc_channel *dmfc, int width)
 
        writel(dmfc_gen1, priv->base + DMFC_GENERAL1);
 
-       return 0;
+       mutex_unlock(&priv->mutex);
 }
-EXPORT_SYMBOL_GPL(ipu_dmfc_init_channel);
+EXPORT_SYMBOL_GPL(ipu_dmfc_config_wait4eot);
 
 struct dmfc_channel *ipu_dmfc_get(struct ipu_soc *ipu, int ipu_channel)
 {
index bdb8cc89cacc73ea6442c9cf84de4180ded70772..4f9c5c6deaed189f6be5a34145a2ec5cf3fa40b7 100644 (file)
@@ -1979,6 +1979,9 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
index 5c0e43ed5c53ca28e554b7d833b093f545b8b440..c6eaff5f88451f770cf036e71b9167a0202351e7 100644 (file)
 #define USB_DEVICE_ID_SIDEWINDER_GV    0x003b
 #define USB_DEVICE_ID_MS_OFFICE_KB     0x0048
 #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d
+#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K 0x00b4
 #define USB_DEVICE_ID_MS_NE4K          0x00db
 #define USB_DEVICE_ID_MS_NE4K_JP       0x00dc
 #define USB_DEVICE_ID_MS_LK6K          0x00f9
 #define USB_DEVICE_ID_MS_PRESENTER_8K_USB      0x0713
 #define USB_DEVICE_ID_MS_NE7K          0x071d
 #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K      0x0730
+#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1 0x0732
+#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_600  0x0750
 #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500    0x076c
 #define USB_DEVICE_ID_MS_COMFORT_KEYBOARD 0x00e3
 #define USB_DEVICE_ID_MS_SURFACE_PRO_2   0x0799
index 0125e356bd8d29c0ad51b22d604f1df00f0f2cd7..1ac4ff4d57a659fc89c6a2bf36b83ba2d679fdcc 100644 (file)
@@ -184,21 +184,31 @@ static int lenovo_send_cmd_cptkbd(struct hid_device *hdev,
                        unsigned char byte2, unsigned char byte3)
 {
        int ret;
-       unsigned char buf[] = {0x18, byte2, byte3};
+       unsigned char *buf;
+
+       buf = kzalloc(3, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       buf[0] = 0x18;
+       buf[1] = byte2;
+       buf[2] = byte3;
 
        switch (hdev->product) {
        case USB_DEVICE_ID_LENOVO_CUSBKBD:
-               ret = hid_hw_raw_request(hdev, 0x13, buf, sizeof(buf),
+               ret = hid_hw_raw_request(hdev, 0x13, buf, 3,
                                        HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
                break;
        case USB_DEVICE_ID_LENOVO_CBTKBD:
-               ret = hid_hw_output_report(hdev, buf, sizeof(buf));
+               ret = hid_hw_output_report(hdev, buf, 3);
                break;
        default:
                ret = -EINVAL;
                break;
        }
 
+       kfree(buf);
+
        return ret < 0 ? ret : 0; /* BT returns 0, USB returns sizeof(buf) */
 }
 
index 75cd3bc59c549a2be01c8092412dafd24abf8c61..e924d555536cf7fb1b221af4c15e51112df107c8 100644 (file)
@@ -272,6 +272,12 @@ static const struct hid_device_id ms_devices[] = {
                .driver_data = MS_PRESENTER },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K),
                .driver_data = MS_ERGONOMY | MS_RDESC_3K },
+       { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K),
+               .driver_data = MS_ERGONOMY },
+       { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600),
+               .driver_data = MS_ERGONOMY },
+       { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1),
+               .driver_data = MS_ERGONOMY },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0),
                .driver_data = MS_NOGET },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500),
index 25d3c4330bf69bbca32efb3883628f3af6a28875..c741f5e50a6681cd0b6267fc04c5ca11f1b0a1b5 100644 (file)
@@ -1169,6 +1169,7 @@ static void mt_release_contacts(struct hid_device *hid)
                                                           MT_TOOL_FINGER,
                                                           false);
                        }
+                       input_mt_sync_frame(input_dev);
                        input_sync(input_dev);
                }
        }
index 4390eee2ce84977427e7c3759f9e481895037858..c830ed39348f7cdba2b06b9dda01616e9405335a 100644 (file)
@@ -2049,9 +2049,11 @@ static void wiimod_mp_in_mp(struct wiimote_data *wdata, const __u8 *ext)
         *   -----+------------------------------+-----+-----+
         * The single bits Yaw, Roll, Pitch in the lower right corner specify
         * whether the wiimote is rotating fast (0) or slow (1). Speed for slow
-        * roation is 440 deg/s and for fast rotation 2000 deg/s. To get a
-        * linear scale we multiply by 2000/440 = ~4.5454 which is 18 for fast
-        * and 9 for slow.
+        * roation is 8192/440 units / deg/s and for fast rotation 8192/2000
+        * units / deg/s. To get a linear scale for fast rotation we multiply
+        * by 2000/440 = ~4.5454 and scale both fast and slow by 9 to match the
+        * previous scale reported by this driver.
+        * This leaves a linear scale with 8192*9/440 (~167.564) units / deg/s.
         * If the wiimote is not rotating the sensor reports 2^13 = 8192.
         * Ext specifies whether an extension is connected to the motionp.
         * which is parsed by wiimote-core.
@@ -2070,15 +2072,15 @@ static void wiimod_mp_in_mp(struct wiimote_data *wdata, const __u8 *ext)
        z -= 8192;
 
        if (!(ext[3] & 0x02))
-               x *= 18;
+               x = (x * 2000 * 9) / 440;
        else
                x *= 9;
        if (!(ext[4] & 0x02))
-               y *= 18;
+               y = (y * 2000 * 9) / 440;
        else
                y *= 9;
        if (!(ext[3] & 0x01))
-               z *= 18;
+               z = (z * 2000 * 9) / 440;
        else
                z *= 9;
 
index ad71160b9ea4341309030db0aea3aa2213ad71d3..ae83af649a607f67239f1a64bf45dd4b5770cc7d 100644 (file)
@@ -951,14 +951,6 @@ static int usbhid_output_report(struct hid_device *hid, __u8 *buf, size_t count)
        return ret;
 }
 
-static void usbhid_restart_queues(struct usbhid_device *usbhid)
-{
-       if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl))
-               usbhid_restart_out_queue(usbhid);
-       if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
-               usbhid_restart_ctrl_queue(usbhid);
-}
-
 static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
 {
        struct usbhid_device *usbhid = hid->driver_data;
@@ -1404,6 +1396,37 @@ static void hid_cease_io(struct usbhid_device *usbhid)
        usb_kill_urb(usbhid->urbout);
 }
 
+static void hid_restart_io(struct hid_device *hid)
+{
+       struct usbhid_device *usbhid = hid->driver_data;
+       int clear_halt = test_bit(HID_CLEAR_HALT, &usbhid->iofl);
+       int reset_pending = test_bit(HID_RESET_PENDING, &usbhid->iofl);
+
+       spin_lock_irq(&usbhid->lock);
+       clear_bit(HID_SUSPENDED, &usbhid->iofl);
+       usbhid_mark_busy(usbhid);
+
+       if (clear_halt || reset_pending)
+               schedule_work(&usbhid->reset_work);
+       usbhid->retry_delay = 0;
+       spin_unlock_irq(&usbhid->lock);
+
+       if (reset_pending || !test_bit(HID_STARTED, &usbhid->iofl))
+               return;
+
+       if (!clear_halt) {
+               if (hid_start_in(hid) < 0)
+                       hid_io_error(hid);
+       }
+
+       spin_lock_irq(&usbhid->lock);
+       if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl))
+               usbhid_restart_out_queue(usbhid);
+       if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
+               usbhid_restart_ctrl_queue(usbhid);
+       spin_unlock_irq(&usbhid->lock);
+}
+
 /* Treat USB reset pretty much the same as suspend/resume */
 static int hid_pre_reset(struct usb_interface *intf)
 {
@@ -1453,14 +1476,14 @@ static int hid_post_reset(struct usb_interface *intf)
                return 1;
        }
 
+       /* No need to do another reset or clear a halted endpoint */
        spin_lock_irq(&usbhid->lock);
        clear_bit(HID_RESET_PENDING, &usbhid->iofl);
+       clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
        spin_unlock_irq(&usbhid->lock);
        hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
-       status = hid_start_in(hid);
-       if (status < 0)
-               hid_io_error(hid);
-       usbhid_restart_queues(usbhid);
+
+       hid_restart_io(hid);
 
        return 0;
 }
@@ -1483,25 +1506,9 @@ void usbhid_put_power(struct hid_device *hid)
 #ifdef CONFIG_PM
 static int hid_resume_common(struct hid_device *hid, bool driver_suspended)
 {
-       struct usbhid_device *usbhid = hid->driver_data;
-       int status;
-
-       spin_lock_irq(&usbhid->lock);
-       clear_bit(HID_SUSPENDED, &usbhid->iofl);
-       usbhid_mark_busy(usbhid);
-
-       if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
-                       test_bit(HID_RESET_PENDING, &usbhid->iofl))
-               schedule_work(&usbhid->reset_work);
-       usbhid->retry_delay = 0;
-
-       usbhid_restart_queues(usbhid);
-       spin_unlock_irq(&usbhid->lock);
-
-       status = hid_start_in(hid);
-       if (status < 0)
-               hid_io_error(hid);
+       int status = 0;
 
+       hid_restart_io(hid);
        if (driver_suspended && hid->driver && hid->driver->resume)
                status = hid->driver->resume(hid);
        return status;
@@ -1570,12 +1577,8 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
 static int hid_resume(struct usb_interface *intf)
 {
        struct hid_device *hid = usb_get_intfdata (intf);
-       struct usbhid_device *usbhid = hid->driver_data;
        int status;
 
-       if (!test_bit(HID_STARTED, &usbhid->iofl))
-               return 0;
-
        status = hid_resume_common(hid, true);
        dev_dbg(&intf->dev, "resume status %d\n", status);
        return 0;
@@ -1584,10 +1587,8 @@ static int hid_resume(struct usb_interface *intf)
 static int hid_reset_resume(struct usb_interface *intf)
 {
        struct hid_device *hid = usb_get_intfdata(intf);
-       struct usbhid_device *usbhid = hid->driver_data;
        int status;
 
-       clear_bit(HID_SUSPENDED, &usbhid->iofl);
        status = hid_post_reset(intf);
        if (status >= 0 && hid->driver && hid->driver->reset_resume) {
                int ret = hid->driver->reset_resume(hid);
index 68a560957871c5a497e4e3d0229ca03dc359d8da..ccf1883318c37ff401c08a147d365ab2fbb0d5df 100644 (file)
@@ -152,6 +152,25 @@ static void wacom_feature_mapping(struct hid_device *hdev,
                hid_data->inputmode = field->report->id;
                hid_data->inputmode_index = usage->usage_index;
                break;
+
+       case HID_UP_DIGITIZER:
+               if (field->report->id == 0x0B &&
+                   (field->application == WACOM_G9_DIGITIZER ||
+                    field->application == WACOM_G11_DIGITIZER)) {
+                       wacom->wacom_wac.mode_report = field->report->id;
+                       wacom->wacom_wac.mode_value = 0;
+               }
+               break;
+
+       case WACOM_G9_PAGE:
+       case WACOM_G11_PAGE:
+               if (field->report->id == 0x03 &&
+                   (field->application == WACOM_G9_TOUCHSCREEN ||
+                    field->application == WACOM_G11_TOUCHSCREEN)) {
+                       wacom->wacom_wac.mode_report = field->report->id;
+                       wacom->wacom_wac.mode_value = 0;
+               }
+               break;
        }
 }
 
@@ -322,26 +341,41 @@ static int wacom_hid_set_device_mode(struct hid_device *hdev)
        return 0;
 }
 
-static int wacom_set_device_mode(struct hid_device *hdev, int report_id,
-               int length, int mode)
+static int wacom_set_device_mode(struct hid_device *hdev,
+                                struct wacom_wac *wacom_wac)
 {
-       unsigned char *rep_data;
+       u8 *rep_data;
+       struct hid_report *r;
+       struct hid_report_enum *re;
+       int length;
        int error = -ENOMEM, limit = 0;
 
-       rep_data = kzalloc(length, GFP_KERNEL);
+       if (wacom_wac->mode_report < 0)
+               return 0;
+
+       re = &(hdev->report_enum[HID_FEATURE_REPORT]);
+       r = re->report_id_hash[wacom_wac->mode_report];
+       if (!r)
+               return -EINVAL;
+
+       rep_data = hid_alloc_report_buf(r, GFP_KERNEL);
        if (!rep_data)
-               return error;
+               return -ENOMEM;
+
+       length = hid_report_len(r);
 
        do {
-               rep_data[0] = report_id;
-               rep_data[1] = mode;
+               rep_data[0] = wacom_wac->mode_report;
+               rep_data[1] = wacom_wac->mode_value;
 
                error = wacom_set_report(hdev, HID_FEATURE_REPORT, rep_data,
                                         length, 1);
                if (error >= 0)
                        error = wacom_get_report(hdev, HID_FEATURE_REPORT,
                                                 rep_data, length, 1);
-       } while (error >= 0 && rep_data[1] != mode && limit++ < WAC_MSG_RETRIES);
+       } while (error >= 0 &&
+                rep_data[1] != wacom_wac->mode_report &&
+                limit++ < WAC_MSG_RETRIES);
 
        kfree(rep_data);
 
@@ -411,32 +445,41 @@ static int wacom_bt_query_tablet_data(struct hid_device *hdev, u8 speed,
 static int wacom_query_tablet_data(struct hid_device *hdev,
                struct wacom_features *features)
 {
+       struct wacom *wacom = hid_get_drvdata(hdev);
+       struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+
        if (hdev->bus == BUS_BLUETOOTH)
                return wacom_bt_query_tablet_data(hdev, 1, features);
 
-       if (features->type == HID_GENERIC)
-               return wacom_hid_set_device_mode(hdev);
-
-       if (features->device_type & WACOM_DEVICETYPE_TOUCH) {
-               if (features->type > TABLETPC) {
-                       /* MT Tablet PC touch */
-                       return wacom_set_device_mode(hdev, 3, 4, 4);
-               }
-               else if (features->type == WACOM_24HDT) {
-                       return wacom_set_device_mode(hdev, 18, 3, 2);
-               }
-               else if (features->type == WACOM_27QHDT) {
-                       return wacom_set_device_mode(hdev, 131, 3, 2);
-               }
-               else if (features->type == BAMBOO_PAD) {
-                       return wacom_set_device_mode(hdev, 2, 2, 2);
-               }
-       } else if (features->device_type & WACOM_DEVICETYPE_PEN) {
-               if (features->type <= BAMBOO_PT) {
-                       return wacom_set_device_mode(hdev, 2, 2, 2);
+       if (features->type != HID_GENERIC) {
+               if (features->device_type & WACOM_DEVICETYPE_TOUCH) {
+                       if (features->type > TABLETPC) {
+                               /* MT Tablet PC touch */
+                               wacom_wac->mode_report = 3;
+                               wacom_wac->mode_value = 4;
+                       } else if (features->type == WACOM_24HDT) {
+                               wacom_wac->mode_report = 18;
+                               wacom_wac->mode_value = 2;
+                       } else if (features->type == WACOM_27QHDT) {
+                               wacom_wac->mode_report = 131;
+                               wacom_wac->mode_value = 2;
+                       } else if (features->type == BAMBOO_PAD) {
+                               wacom_wac->mode_report = 2;
+                               wacom_wac->mode_value = 2;
+                       }
+               } else if (features->device_type & WACOM_DEVICETYPE_PEN) {
+                       if (features->type <= BAMBOO_PT) {
+                               wacom_wac->mode_report = 2;
+                               wacom_wac->mode_value = 2;
+                       }
                }
        }
 
+       wacom_set_device_mode(hdev, wacom_wac);
+
+       if (features->type == HID_GENERIC)
+               return wacom_hid_set_device_mode(hdev);
+
        return 0;
 }
 
@@ -1817,6 +1860,9 @@ static int wacom_probe(struct hid_device *hdev,
                goto fail_type;
        }
 
+       wacom_wac->hid_data.inputmode = -1;
+       wacom_wac->mode_report = -1;
+
        wacom->usbdev = dev;
        wacom->intf = intf;
        mutex_init(&wacom->lock);
index bd198bbd4df0841b5a3596c09ecac822ecda40e5..02c4efea241c02eb6270d19b40cc90256b04721a 100644 (file)
@@ -2425,6 +2425,17 @@ void wacom_setup_device_quirks(struct wacom *wacom)
                }
        }
 
+       /*
+        * Hack for the Bamboo One:
+        * the device presents a PAD/Touch interface as most Bamboos and even
+        * sends ghosts PAD data on it. However, later, we must disable this
+        * ghost interface, and we can not detect it unless we set it here
+        * to WACOM_DEVICETYPE_PAD or WACOM_DEVICETYPE_TOUCH.
+        */
+       if (features->type == BAMBOO_PEN &&
+           features->pktlen == WACOM_PKGLEN_BBTOUCH3)
+               features->device_type |= WACOM_DEVICETYPE_PAD;
+
        /*
         * Raw Wacom-mode pen and touch events both come from interface
         * 0, whose HID descriptor has an application usage of 0xFF0D
index 25baa7f295997f65759d8da1c6dc239c01258156..e2084d914c14aa3902b42e2cb852517c31327256 100644 (file)
 #define WACOM_DEVICETYPE_WL_MONITOR     0x0008
 
 #define WACOM_VENDORDEFINED_PEN                0xff0d0001
+#define WACOM_G9_PAGE                  0xff090000
+#define WACOM_G9_DIGITIZER             (WACOM_G9_PAGE | 0x02)
+#define WACOM_G9_TOUCHSCREEN           (WACOM_G9_PAGE | 0x11)
+#define WACOM_G11_PAGE                 0xff110000
+#define WACOM_G11_DIGITIZER            (WACOM_G11_PAGE | 0x02)
+#define WACOM_G11_TOUCHSCREEN          (WACOM_G11_PAGE | 0x11)
 
 #define WACOM_PEN_FIELD(f)     (((f)->logical == HID_DG_STYLUS) || \
                                 ((f)->physical == HID_DG_STYLUS) || \
@@ -238,6 +244,8 @@ struct wacom_wac {
        int ps_connected;
        u8 bt_features;
        u8 bt_high_speed;
+       int mode_report;
+       int mode_value;
        struct hid_data hid_data;
 };
 
index f325663c27c532645a1901a385ac6d52543e5ba5..ba14a863b451f943ea862bb94d2f808554a397d0 100644 (file)
@@ -771,11 +771,16 @@ static int jz4780_i2c_probe(struct platform_device *pdev)
        ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
                                   &clk_freq);
        if (ret) {
-               dev_err(&pdev->dev, "clock-frequency not specified in DT");
+               dev_err(&pdev->dev, "clock-frequency not specified in DT\n");
                goto err;
        }
 
        i2c->speed = clk_freq / 1000;
+       if (i2c->speed == 0) {
+               ret = -EINVAL;
+               dev_err(&pdev->dev, "clock-frequency minimum is 1000\n");
+               goto err;
+       }
        jz4780_i2c_set_speed(i2c);
 
        dev_info(&pdev->dev, "Bus frequency is %d KHz\n", i2c->speed);
index 0f2f8484e8ec1f51ca8e265bd160d3cbee5c7885..e584d88ee337f66e158644076f7b9a2b0018177e 100644 (file)
@@ -525,22 +525,16 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
        return 0;
 }
 
-
-/* uevent helps with hotplug: modprobe -q $(MODALIAS) */
 static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
-       struct i2c_client       *client = to_i2c_client(dev);
+       struct i2c_client *client = to_i2c_client(dev);
        int rc;
 
        rc = acpi_device_uevent_modalias(dev, env);
        if (rc != -ENODEV)
                return rc;
 
-       if (add_uevent_var(env, "MODALIAS=%s%s",
-                          I2C_MODULE_PREFIX, client->name))
-               return -ENOMEM;
-       dev_dbg(dev, "uevent\n");
-       return 0;
+       return add_uevent_var(env, "MODALIAS=%s%s", I2C_MODULE_PREFIX, client->name);
 }
 
 /* i2c bus recovery routines */
index 7748a0a5ddb9f1cabba4f5318078afdddc614bc9..8de073aed001482461b3ad12398c00fa9417fc95 100644 (file)
@@ -140,22 +140,34 @@ static int i2c_demux_change_master(struct i2c_demux_pinctrl_priv *priv, u32 new_
        return i2c_demux_activate_master(priv, new_chan);
 }
 
-static ssize_t cur_master_show(struct device *dev, struct device_attribute *attr,
-                          char *buf)
+static ssize_t available_masters_show(struct device *dev,
+                                     struct device_attribute *attr,
+                                     char *buf)
 {
        struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
        int count = 0, i;
 
        for (i = 0; i < priv->num_chan && count < PAGE_SIZE; i++)
-               count += scnprintf(buf + count, PAGE_SIZE - count, "%c %d - %s\n",
-                                i == priv->cur_chan ? '*' : ' ', i,
-                                priv->chan[i].parent_np->full_name);
+               count += scnprintf(buf + count, PAGE_SIZE - count, "%d:%s%c",
+                                  i, priv->chan[i].parent_np->full_name,
+                                  i == priv->num_chan - 1 ? '\n' : ' ');
 
        return count;
 }
+static DEVICE_ATTR_RO(available_masters);
 
-static ssize_t cur_master_store(struct device *dev, struct device_attribute *attr,
-                           const char *buf, size_t count)
+static ssize_t current_master_show(struct device *dev,
+                                  struct device_attribute *attr,
+                                  char *buf)
+{
+       struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d\n", priv->cur_chan);
+}
+
+static ssize_t current_master_store(struct device *dev,
+                                   struct device_attribute *attr,
+                                   const char *buf, size_t count)
 {
        struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
        unsigned int val;
@@ -172,7 +184,7 @@ static ssize_t cur_master_store(struct device *dev, struct device_attribute *att
 
        return ret < 0 ? ret : count;
 }
-static DEVICE_ATTR_RW(cur_master);
+static DEVICE_ATTR_RW(current_master);
 
 static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
 {
@@ -218,12 +230,18 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
        /* switch to first parent as active master */
        i2c_demux_activate_master(priv, 0);
 
-       err = device_create_file(&pdev->dev, &dev_attr_cur_master);
+       err = device_create_file(&pdev->dev, &dev_attr_available_masters);
        if (err)
                goto err_rollback;
 
+       err = device_create_file(&pdev->dev, &dev_attr_current_master);
+       if (err)
+               goto err_rollback_available;
+
        return 0;
 
+err_rollback_available:
+       device_remove_file(&pdev->dev, &dev_attr_available_masters);
 err_rollback:
        for (j = 0; j < i; j++) {
                of_node_put(priv->chan[j].parent_np);
@@ -238,7 +256,8 @@ static int i2c_demux_pinctrl_remove(struct platform_device *pdev)
        struct i2c_demux_pinctrl_priv *priv = platform_get_drvdata(pdev);
        int i;
 
-       device_remove_file(&pdev->dev, &dev_attr_cur_master);
+       device_remove_file(&pdev->dev, &dev_attr_current_master);
+       device_remove_file(&pdev->dev, &dev_attr_available_masters);
 
        i2c_demux_deactivate_master(priv);
 
index ba947df5a8c7d09af2c36a23d5b6a1d5f4df8bb3..c6935de425fa22ed2b0d08e7d55b5ae02ccde0c6 100644 (file)
@@ -660,6 +660,35 @@ static struct cpuidle_state skl_cstates[] = {
                .enter = NULL }
 };
 
+static struct cpuidle_state skx_cstates[] = {
+       {
+               .name = "C1-SKX",
+               .desc = "MWAIT 0x00",
+               .flags = MWAIT2flg(0x00),
+               .exit_latency = 2,
+               .target_residency = 2,
+               .enter = &intel_idle,
+               .enter_freeze = intel_idle_freeze, },
+       {
+               .name = "C1E-SKX",
+               .desc = "MWAIT 0x01",
+               .flags = MWAIT2flg(0x01),
+               .exit_latency = 10,
+               .target_residency = 20,
+               .enter = &intel_idle,
+               .enter_freeze = intel_idle_freeze, },
+       {
+               .name = "C6-SKX",
+               .desc = "MWAIT 0x20",
+               .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
+               .exit_latency = 133,
+               .target_residency = 600,
+               .enter = &intel_idle,
+               .enter_freeze = intel_idle_freeze, },
+       {
+               .enter = NULL }
+};
+
 static struct cpuidle_state atom_cstates[] = {
        {
                .name = "C1E-ATM",
@@ -818,8 +847,11 @@ static int cpu_hotplug_notify(struct notifier_block *n,
                 * driver in this case
                 */
                dev = per_cpu_ptr(intel_idle_cpuidle_devices, hotcpu);
-               if (!dev->registered)
-                       intel_idle_cpu_init(hotcpu);
+               if (dev->registered)
+                       break;
+
+               if (intel_idle_cpu_init(hotcpu))
+                       return NOTIFY_BAD;
 
                break;
        }
@@ -904,6 +936,10 @@ static const struct idle_cpu idle_cpu_skl = {
        .disable_promotion_to_c1e = true,
 };
 
+static const struct idle_cpu idle_cpu_skx = {
+       .state_table = skx_cstates,
+       .disable_promotion_to_c1e = true,
+};
 
 static const struct idle_cpu idle_cpu_avn = {
        .state_table = avn_cstates,
@@ -945,6 +981,9 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
        ICPU(0x56, idle_cpu_bdw),
        ICPU(0x4e, idle_cpu_skl),
        ICPU(0x5e, idle_cpu_skl),
+       ICPU(0x8e, idle_cpu_skl),
+       ICPU(0x9e, idle_cpu_skl),
+       ICPU(0x55, idle_cpu_skx),
        ICPU(0x57, idle_cpu_knl),
        {}
 };
@@ -987,22 +1026,15 @@ static int __init intel_idle_probe(void)
        icpu = (const struct idle_cpu *)id->driver_data;
        cpuidle_state_table = icpu->state_table;
 
-       if (boot_cpu_has(X86_FEATURE_ARAT))     /* Always Reliable APIC Timer */
-               lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
-       else
-               on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
-
        pr_debug(PREFIX "v" INTEL_IDLE_VERSION
                " model 0x%X\n", boot_cpu_data.x86_model);
 
-       pr_debug(PREFIX "lapic_timer_reliable_states 0x%x\n",
-               lapic_timer_reliable_states);
        return 0;
 }
 
 /*
  * intel_idle_cpuidle_devices_uninit()
- * unregister, free cpuidle_devices
+ * Unregisters the cpuidle devices.
  */
 static void intel_idle_cpuidle_devices_uninit(void)
 {
@@ -1013,9 +1045,6 @@ static void intel_idle_cpuidle_devices_uninit(void)
                dev = per_cpu_ptr(intel_idle_cpuidle_devices, i);
                cpuidle_unregister_device(dev);
        }
-
-       free_percpu(intel_idle_cpuidle_devices);
-       return;
 }
 
 /*
@@ -1111,7 +1140,7 @@ static void intel_idle_state_table_update(void)
  * intel_idle_cpuidle_driver_init()
  * allocate, initialize cpuidle_states
  */
-static int __init intel_idle_cpuidle_driver_init(void)
+static void __init intel_idle_cpuidle_driver_init(void)
 {
        int cstate;
        struct cpuidle_driver *drv = &intel_idle_driver;
@@ -1163,18 +1192,10 @@ static int __init intel_idle_cpuidle_driver_init(void)
                drv->state_count += 1;
        }
 
-       if (icpu->auto_demotion_disable_flags)
-               on_each_cpu(auto_demotion_disable, NULL, 1);
-
        if (icpu->byt_auto_demotion_disable_flag) {
                wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0);
                wrmsrl(MSR_MC6_DEMOTION_POLICY_CONFIG, 0);
        }
-
-       if (icpu->disable_promotion_to_c1e)     /* each-cpu is redundant */
-               on_each_cpu(c1e_promotion_disable, NULL, 1);
-
-       return 0;
 }
 
 
@@ -1193,7 +1214,6 @@ static int intel_idle_cpu_init(int cpu)
 
        if (cpuidle_register_device(dev)) {
                pr_debug(PREFIX "cpuidle_register_device %d failed!\n", cpu);
-               intel_idle_cpuidle_devices_uninit();
                return -EIO;
        }
 
@@ -1218,40 +1238,51 @@ static int __init intel_idle_init(void)
        if (retval)
                return retval;
 
+       intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device);
+       if (intel_idle_cpuidle_devices == NULL)
+               return -ENOMEM;
+
        intel_idle_cpuidle_driver_init();
        retval = cpuidle_register_driver(&intel_idle_driver);
        if (retval) {
                struct cpuidle_driver *drv = cpuidle_get_driver();
                printk(KERN_DEBUG PREFIX "intel_idle yielding to %s",
                        drv ? drv->name : "none");
+               free_percpu(intel_idle_cpuidle_devices);
                return retval;
        }
 
-       intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device);
-       if (intel_idle_cpuidle_devices == NULL)
-               return -ENOMEM;
-
        cpu_notifier_register_begin();
 
        for_each_online_cpu(i) {
                retval = intel_idle_cpu_init(i);
                if (retval) {
+                       intel_idle_cpuidle_devices_uninit();
                        cpu_notifier_register_done();
                        cpuidle_unregister_driver(&intel_idle_driver);
+                       free_percpu(intel_idle_cpuidle_devices);
                        return retval;
                }
        }
        __register_cpu_notifier(&cpu_hotplug_notifier);
 
+       if (boot_cpu_has(X86_FEATURE_ARAT))     /* Always Reliable APIC Timer */
+               lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
+       else
+               on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
+
        cpu_notifier_register_done();
 
+       pr_debug(PREFIX "lapic_timer_reliable_states 0x%x\n",
+               lapic_timer_reliable_states);
+
        return 0;
 }
 
 static void __exit intel_idle_exit(void)
 {
-       intel_idle_cpuidle_devices_uninit();
-       cpuidle_unregister_driver(&intel_idle_driver);
+       struct cpuidle_device *dev;
+       int i;
 
        cpu_notifier_register_begin();
 
@@ -1259,9 +1290,15 @@ static void __exit intel_idle_exit(void)
                on_each_cpu(__setup_broadcast_timer, (void *)false, 1);
        __unregister_cpu_notifier(&cpu_hotplug_notifier);
 
+       for_each_possible_cpu(i) {
+               dev = per_cpu_ptr(intel_idle_cpuidle_devices, i);
+               cpuidle_unregister_device(dev);
+       }
+
        cpu_notifier_register_done();
 
-       return;
+       cpuidle_unregister_driver(&intel_idle_driver);
+       free_percpu(intel_idle_cpuidle_devices);
 }
 
 module_init(intel_idle_init);
index c73331f7782b8af4b91c94c26dd29195ddc45d9a..2072a31e813ba01fc0c15274ab60de324201564b 100644 (file)
@@ -547,7 +547,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
 {
        int ret;
        int axis = chan->scan_index;
-       unsigned int raw_val;
+       __le16 raw_val;
 
        mutex_lock(&data->mutex);
        ret = bmc150_accel_set_power_state(data, true);
@@ -557,14 +557,14 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
        }
 
        ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
-                              &raw_val, 2);
+                              &raw_val, sizeof(raw_val));
        if (ret < 0) {
                dev_err(data->dev, "Error reading axis %d\n", axis);
                bmc150_accel_set_power_state(data, false);
                mutex_unlock(&data->mutex);
                return ret;
        }
-       *val = sign_extend32(raw_val >> chan->scan_type.shift,
+       *val = sign_extend32(le16_to_cpu(raw_val) >> chan->scan_type.shift,
                             chan->scan_type.realbits - 1);
        ret = bmc150_accel_set_power_state(data, false);
        mutex_unlock(&data->mutex);
@@ -988,6 +988,7 @@ static const struct iio_event_spec bmc150_accel_event = {
                .realbits = (bits),                                     \
                .storagebits = 16,                                      \
                .shift = 16 - (bits),                                   \
+               .endianness = IIO_LE,                                   \
        },                                                              \
        .event_spec = &bmc150_accel_event,                              \
        .num_event_specs = 1                                            \
index af4aea7b20f950bea5c359247841d00eff0d2a02..82c718c515a01fd1c34eb25e5f9ecfac7e8a1a0a 100644 (file)
@@ -134,6 +134,7 @@ config AT91_ADC
 config AT91_SAMA5D2_ADC
        tristate "Atmel AT91 SAMA5D2 ADC"
        depends on ARCH_AT91 || COMPILE_TEST
+       depends on HAS_IOMEM
        help
          Say yes here to build support for Atmel SAMA5D2 ADC which is
          available on SAMA5D2 SoC family.
index 929508e5266c000864d1095860b7b16f87baf51b..998dc3caad4c15cabe58f7922a594e6976de23ec 100644 (file)
@@ -1386,7 +1386,7 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
        },
        [max11644] = {
                .bits = 12,
-               .int_vref_mv = 2048,
+               .int_vref_mv = 4096,
                .mode_list = max11644_mode_list,
                .num_modes = ARRAY_SIZE(max11644_mode_list),
                .default_mode = s0to1,
@@ -1396,7 +1396,7 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
        },
        [max11645] = {
                .bits = 12,
-               .int_vref_mv = 4096,
+               .int_vref_mv = 2048,
                .mode_list = max11644_mode_list,
                .num_modes = ARRAY_SIZE(max11644_mode_list),
                .default_mode = s0to1,
@@ -1406,7 +1406,7 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
        },
        [max11646] = {
                .bits = 10,
-               .int_vref_mv = 2048,
+               .int_vref_mv = 4096,
                .mode_list = max11644_mode_list,
                .num_modes = ARRAY_SIZE(max11644_mode_list),
                .default_mode = s0to1,
@@ -1416,7 +1416,7 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
        },
        [max11647] = {
                .bits = 10,
-               .int_vref_mv = 4096,
+               .int_vref_mv = 2048,
                .mode_list = max11644_mode_list,
                .num_modes = ARRAY_SIZE(max11644_mode_list),
                .default_mode = s0to1,
@@ -1680,6 +1680,10 @@ static const struct i2c_device_id max1363_id[] = {
        { "max11615", max11615 },
        { "max11616", max11616 },
        { "max11617", max11617 },
+       { "max11644", max11644 },
+       { "max11645", max11645 },
+       { "max11646", max11646 },
+       { "max11647", max11647 },
        {}
 };
 
index bbce3b09ac45abdbc3491fee51d74bcfbab9eb87..4dac567e75b4f00c61ea11d9c1dbc3b663e56a25 100644 (file)
@@ -452,7 +452,7 @@ static int bmg160_get_temp(struct bmg160_data *data, int *val)
 static int bmg160_get_axis(struct bmg160_data *data, int axis, int *val)
 {
        int ret;
-       unsigned int raw_val;
+       __le16 raw_val;
 
        mutex_lock(&data->mutex);
        ret = bmg160_set_power_state(data, true);
@@ -462,7 +462,7 @@ static int bmg160_get_axis(struct bmg160_data *data, int axis, int *val)
        }
 
        ret = regmap_bulk_read(data->regmap, BMG160_AXIS_TO_REG(axis), &raw_val,
-                              2);
+                              sizeof(raw_val));
        if (ret < 0) {
                dev_err(data->dev, "Error reading axis %d\n", axis);
                bmg160_set_power_state(data, false);
@@ -470,7 +470,7 @@ static int bmg160_get_axis(struct bmg160_data *data, int axis, int *val)
                return ret;
        }
 
-       *val = sign_extend32(raw_val, 15);
+       *val = sign_extend32(le16_to_cpu(raw_val), 15);
        ret = bmg160_set_power_state(data, false);
        mutex_unlock(&data->mutex);
        if (ret < 0)
@@ -733,6 +733,7 @@ static const struct iio_event_spec bmg160_event = {
                .sign = 's',                                            \
                .realbits = 16,                                 \
                .storagebits = 16,                                      \
+               .endianness = IIO_LE,                                   \
        },                                                              \
        .event_spec = &bmg160_event,                                    \
        .num_event_specs = 1                                            \
@@ -780,7 +781,7 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p)
                        mutex_unlock(&data->mutex);
                        goto err;
                }
-               data->buffer[i++] = ret;
+               data->buffer[i++] = val;
        }
        mutex_unlock(&data->mutex);
 
index 09db89359544840b5f9ba7b98a8b81a046388459..90ab8a2d2846f8a8591ee6b1615dce2c984020ef 100644 (file)
@@ -238,12 +238,13 @@ static irqreturn_t max30100_interrupt_handler(int irq, void *private)
 
        mutex_lock(&data->lock);
 
-       while (cnt-- || (cnt = max30100_fifo_count(data) > 0)) {
+       while (cnt || (cnt = max30100_fifo_count(data) > 0)) {
                ret = max30100_read_measurement(data);
                if (ret)
                        break;
 
                iio_push_to_buffers(data->indio_dev, data->buffer);
+               cnt--;
        }
 
        mutex_unlock(&data->lock);
index a7f557af43895bfcf3b60e1298bee529246f0d35..847455a2d6bb0275bdc9636eb23f1f7e00bdc653 100644 (file)
@@ -9,9 +9,8 @@ config INV_MPU6050_IIO
 
 config INV_MPU6050_I2C
        tristate "Invensense MPU6050 devices (I2C)"
-       depends on I2C
+       depends on I2C_MUX
        select INV_MPU6050_IIO
-       select I2C_MUX
        select REGMAP_I2C
        help
          This driver supports the Invensense MPU6050 devices.
index b976332d45d3469361d7801201fce65dbd93e583..90462fcf543698bab68378f5a0cb4b8d7262ef2c 100644 (file)
@@ -653,6 +653,7 @@ static int iio_verify_update(struct iio_dev *indio_dev,
        unsigned int modes;
 
        memset(config, 0, sizeof(*config));
+       config->watermark = ~0;
 
        /*
         * If there is just one buffer and we are removing it there is nothing
index f6a07dc32ae486a045b97cfb4406783a9aa05ab8..a6af56ad10e1d828668f62471218da3f3875aa0e 100644 (file)
@@ -769,7 +769,7 @@ static void apds9960_read_gesture_fifo(struct apds9960_data *data)
        mutex_lock(&data->lock);
        data->gesture_mode_running = 1;
 
-       while (cnt-- || (cnt = apds9660_fifo_is_empty(data) > 0)) {
+       while (cnt || (cnt = apds9660_fifo_is_empty(data) > 0)) {
                ret = regmap_bulk_read(data->regmap, APDS9960_REG_GFIFO_BASE,
                                      &data->buffer, 4);
 
@@ -777,6 +777,7 @@ static void apds9960_read_gesture_fifo(struct apds9960_data *data)
                        goto err_read;
 
                iio_push_to_buffers(data->indio_dev, data->buffer);
+               cnt--;
        }
 
 err_read:
index 06a4d9c3558196ec54d1d04200e62b14753c4c62..9daca46819222bedb73e166eda7d1607af6277c8 100644 (file)
@@ -44,6 +44,7 @@ static inline int st_magn_allocate_ring(struct iio_dev *indio_dev)
 static inline void st_magn_deallocate_ring(struct iio_dev *indio_dev)
 {
 }
+#define ST_MAGN_TRIGGER_SET_STATE NULL
 #endif /* CONFIG_IIO_BUFFER */
 
 #endif /* ST_MAGN_H */
index 92745d755272df6b097e5cbdf0131ecc5ff046f8..38f917a6c7784101247c6a59af14b21a73d85d0a 100644 (file)
@@ -1992,7 +1992,6 @@ static int i40iw_addr_resolve_neigh(struct i40iw_device *iwdev,
 /**
  * i40iw_get_dst_ipv6
  */
-#if IS_ENABLED(CONFIG_IPV6)
 static struct dst_entry *i40iw_get_dst_ipv6(struct sockaddr_in6 *src_addr,
                                            struct sockaddr_in6 *dst_addr)
 {
@@ -2008,7 +2007,6 @@ static struct dst_entry *i40iw_get_dst_ipv6(struct sockaddr_in6 *src_addr,
        dst = ip6_route_output(&init_net, NULL, &fl6);
        return dst;
 }
-#endif
 
 /**
  * i40iw_addr_resolve_neigh_ipv6 - resolve neighbor ipv6 address
@@ -2016,7 +2014,6 @@ static struct dst_entry *i40iw_get_dst_ipv6(struct sockaddr_in6 *src_addr,
  * @dst_ip: remote ip address
  * @arpindex: if there is an arp entry
  */
-#if IS_ENABLED(CONFIG_IPV6)
 static int i40iw_addr_resolve_neigh_ipv6(struct i40iw_device *iwdev,
                                         u32 *src,
                                         u32 *dest,
@@ -2089,7 +2086,6 @@ static int i40iw_addr_resolve_neigh_ipv6(struct i40iw_device *iwdev,
        dst_release(dst);
        return rc;
 }
-#endif
 
 /**
  * i40iw_ipv4_is_loopback - check if loopback
@@ -2190,13 +2186,13 @@ static struct i40iw_cm_node *i40iw_make_cm_node(
                                                            cm_info->loc_addr[0],
                                                            cm_info->rem_addr[0],
                                                            oldarpindex);
-#if IS_ENABLED(CONFIG_IPV6)
-               else
+               else if (IS_ENABLED(CONFIG_IPV6))
                        arpindex = i40iw_addr_resolve_neigh_ipv6(iwdev,
                                                                 cm_info->loc_addr,
                                                                 cm_info->rem_addr,
                                                                 oldarpindex);
-#endif
+               else
+                       arpindex = -EINVAL;
        }
        if (arpindex < 0) {
                i40iw_pr_err("cm_node arpindex\n");
index f16c818ad2e62f6cd507b80b096a06d3c0e73164..b46c25542a7c6285d6c5088f2006889d59eaf10f 100644 (file)
@@ -776,15 +776,6 @@ void mlx5_ib_qp_disable_pagefaults(struct mlx5_ib_qp *qp);
 void mlx5_ib_qp_enable_pagefaults(struct mlx5_ib_qp *qp);
 void mlx5_ib_invalidate_range(struct ib_umem *umem, unsigned long start,
                              unsigned long end);
-int mlx5_ib_get_vf_config(struct ib_device *device, int vf,
-                         u8 port, struct ifla_vf_info *info);
-int mlx5_ib_set_vf_link_state(struct ib_device *device, int vf,
-                             u8 port, int state);
-int mlx5_ib_get_vf_stats(struct ib_device *device, int vf,
-                        u8 port, struct ifla_vf_stats *stats);
-int mlx5_ib_set_vf_guid(struct ib_device *device, int vf, u8 port,
-                       u64 guid, int type);
-
 #else /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */
 static inline void mlx5_ib_internal_fill_odp_caps(struct mlx5_ib_dev *dev)
 {
@@ -801,6 +792,15 @@ static inline void mlx5_ib_qp_enable_pagefaults(struct mlx5_ib_qp *qp)  {}
 
 #endif /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */
 
+int mlx5_ib_get_vf_config(struct ib_device *device, int vf,
+                         u8 port, struct ifla_vf_info *info);
+int mlx5_ib_set_vf_link_state(struct ib_device *device, int vf,
+                             u8 port, int state);
+int mlx5_ib_get_vf_stats(struct ib_device *device, int vf,
+                        u8 port, struct ifla_vf_stats *stats);
+int mlx5_ib_set_vf_guid(struct ib_device *device, int vf, u8 port,
+                       u64 guid, int type);
+
 __be16 mlx5_get_roce_udp_sport(struct mlx5_ib_dev *dev, u8 port_num,
                               int index);
 
index 0bd3cb2f3c671a21fefd57dbc4851a24daa61e82..8b42401d4795646019f4498ed909b306630f19ec 100644 (file)
@@ -1264,26 +1264,40 @@ free_mem:
  */
 static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch)
 {
-       struct se_session *se_sess;
        struct srpt_send_ioctx *ioctx;
-       int tag;
+       unsigned long flags;
 
        BUG_ON(!ch);
-       se_sess = ch->sess;
 
-       tag = percpu_ida_alloc(&se_sess->sess_tag_pool, TASK_RUNNING);
-       if (tag < 0) {
-               pr_err("Unable to obtain tag for srpt_send_ioctx\n");
-               return NULL;
+       ioctx = NULL;
+       spin_lock_irqsave(&ch->spinlock, flags);
+       if (!list_empty(&ch->free_list)) {
+               ioctx = list_first_entry(&ch->free_list,
+                                        struct srpt_send_ioctx, free_list);
+               list_del(&ioctx->free_list);
        }
-       ioctx = &((struct srpt_send_ioctx *)se_sess->sess_cmd_map)[tag];
-       memset(ioctx, 0, sizeof(struct srpt_send_ioctx));
-       ioctx->ch = ch;
+       spin_unlock_irqrestore(&ch->spinlock, flags);
+
+       if (!ioctx)
+               return ioctx;
+
+       BUG_ON(ioctx->ch != ch);
        spin_lock_init(&ioctx->spinlock);
        ioctx->state = SRPT_STATE_NEW;
+       ioctx->n_rbuf = 0;
+       ioctx->rbufs = NULL;
+       ioctx->n_rdma = 0;
+       ioctx->n_rdma_wrs = 0;
+       ioctx->rdma_wrs = NULL;
+       ioctx->mapped_sg_count = 0;
        init_completion(&ioctx->tx_done);
-
-       ioctx->cmd.map_tag = tag;
+       ioctx->queue_status_only = false;
+       /*
+        * transport_init_se_cmd() does not initialize all fields, so do it
+        * here.
+        */
+       memset(&ioctx->cmd, 0, sizeof(ioctx->cmd));
+       memset(&ioctx->sense_data, 0, sizeof(ioctx->sense_data));
 
        return ioctx;
 }
@@ -2021,7 +2035,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
        struct ib_cm_rep_param *rep_param;
        struct srpt_rdma_ch *ch, *tmp_ch;
        u32 it_iu_len;
-       int ret = 0;
+       int i, ret = 0;
        unsigned char *p;
 
        WARN_ON_ONCE(irqs_disabled());
@@ -2143,6 +2157,12 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
        if (!ch->ioctx_ring)
                goto free_ch;
 
+       INIT_LIST_HEAD(&ch->free_list);
+       for (i = 0; i < ch->rq_size; i++) {
+               ch->ioctx_ring[i]->ch = ch;
+               list_add_tail(&ch->ioctx_ring[i]->free_list, &ch->free_list);
+       }
+
        ret = srpt_create_ch_ib(ch);
        if (ret) {
                rej->reason = cpu_to_be32(
@@ -2173,8 +2193,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
        p = &ch->sess_name[0];
 
 try_again:
-       ch->sess = target_alloc_session(&sport->port_tpg_1, ch->rq_size,
-                                       sizeof(struct srpt_send_ioctx),
+       ch->sess = target_alloc_session(&sport->port_tpg_1, 0, 0,
                                        TARGET_PROT_NORMAL, p, ch, NULL);
        if (IS_ERR(ch->sess)) {
                pr_info("Rejected login because no ACL has been"
@@ -2881,7 +2900,7 @@ static void srpt_release_cmd(struct se_cmd *se_cmd)
        struct srpt_send_ioctx *ioctx = container_of(se_cmd,
                                struct srpt_send_ioctx, cmd);
        struct srpt_rdma_ch *ch = ioctx->ch;
-       struct se_session *se_sess = ch->sess;
+       unsigned long flags;
 
        WARN_ON(ioctx->state != SRPT_STATE_DONE);
        WARN_ON(ioctx->mapped_sg_count != 0);
@@ -2892,7 +2911,9 @@ static void srpt_release_cmd(struct se_cmd *se_cmd)
                ioctx->n_rbuf = 0;
        }
 
-       percpu_ida_free(&se_sess->sess_tag_pool, se_cmd->map_tag);
+       spin_lock_irqsave(&ch->spinlock, flags);
+       list_add(&ioctx->free_list, &ch->free_list);
+       spin_unlock_irqrestore(&ch->spinlock, flags);
 }
 
 /**
index ca288f019315cda7142169ddbe5269772a7f398c..af9b8b527340c80f4c8af515cc4aa641a5c5b426 100644 (file)
@@ -179,6 +179,7 @@ struct srpt_recv_ioctx {
  * struct srpt_send_ioctx - SRPT send I/O context.
  * @ioctx:       See above.
  * @ch:          Channel pointer.
+ * @free_list:   Node in srpt_rdma_ch.free_list.
  * @n_rbuf:      Number of data buffers in the received SRP command.
  * @rbufs:       Pointer to SRP data buffer array.
  * @single_rbuf: SRP data buffer if the command has only a single buffer.
@@ -201,6 +202,7 @@ struct srpt_send_ioctx {
        struct srp_direct_buf   *rbufs;
        struct srp_direct_buf   single_rbuf;
        struct scatterlist      *sg;
+       struct list_head        free_list;
        spinlock_t              spinlock;
        enum srpt_command_state state;
        struct se_cmd           cmd;
index 72d6182666cbd24ba785fc59572c655b6f0c2c8f..58f2fe687a24ddd29ac6d786862eefc33098d795 100644 (file)
@@ -403,7 +403,7 @@ static int __finalise_sg(struct device *dev, struct scatterlist *sg, int nents,
                unsigned int s_length = sg_dma_len(s);
                unsigned int s_dma_len = s->length;
 
-               s->offset = s_offset;
+               s->offset += s_offset;
                s->length = s_length;
                sg_dma_address(s) = dma_addr + s_offset;
                dma_addr += s_dma_len;
@@ -422,7 +422,7 @@ static void __invalidate_sg(struct scatterlist *sg, int nents)
 
        for_each_sg(sg, s, nents, i) {
                if (sg_dma_address(s) != DMA_ERROR_CODE)
-                       s->offset = sg_dma_address(s);
+                       s->offset += sg_dma_address(s);
                if (sg_dma_len(s))
                        s->length = sg_dma_len(s);
                sg_dma_address(s) = DMA_ERROR_CODE;
index a2e1b7f14df29cc78b625ec88455438d0fa1fe07..e1852e845d21f1f8014f7e51789d0e8682c5c8e8 100644 (file)
@@ -2458,7 +2458,7 @@ static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
        }
 
        /* register PCI DMA alias device */
-       if (req_id != dma_alias && dev_is_pci(dev)) {
+       if (dev_is_pci(dev) && req_id != dma_alias) {
                tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
                                               dma_alias & 0xff, NULL, domain);
 
index bfd4f7c3b1d8a9da9ce6cd2bce3decd8e27e0fca..b9df1411c8942c18b266b11e1cf572ecf9bcad15 100644 (file)
@@ -848,7 +848,8 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
        if (!group->default_domain) {
                group->default_domain = __iommu_domain_alloc(dev->bus,
                                                             IOMMU_DOMAIN_DMA);
-               group->domain = group->default_domain;
+               if (!group->domain)
+                       group->domain = group->default_domain;
        }
 
        ret = iommu_group_add_device(group, dev);
index a6f593a0a29eda65c1f383dbe1700c13a8e9be27..5710a06c30498e1b40f4c645f56f1c9b2a49eb4e 100644 (file)
@@ -315,8 +315,8 @@ static bool rk_iommu_is_stall_active(struct rk_iommu *iommu)
        int i;
 
        for (i = 0; i < iommu->num_mmu; i++)
-               active &= rk_iommu_read(iommu->bases[i], RK_MMU_STATUS) &
-                                       RK_MMU_STATUS_STALL_ACTIVE;
+               active &= !!(rk_iommu_read(iommu->bases[i], RK_MMU_STATUS) &
+                                          RK_MMU_STATUS_STALL_ACTIVE);
 
        return active;
 }
@@ -327,8 +327,8 @@ static bool rk_iommu_is_paging_enabled(struct rk_iommu *iommu)
        int i;
 
        for (i = 0; i < iommu->num_mmu; i++)
-               enable &= rk_iommu_read(iommu->bases[i], RK_MMU_STATUS) &
-                                       RK_MMU_STATUS_PAGING_ENABLED;
+               enable &= !!(rk_iommu_read(iommu->bases[i], RK_MMU_STATUS) &
+                                          RK_MMU_STATUS_PAGING_ENABLED);
 
        return enable;
 }
index 0ddf638d60f3645c4a083b37027625dfd850b97f..043828d541f794b331fdaef51e2649a58a472525 100644 (file)
@@ -361,8 +361,6 @@ static int __init acpi_pcc_probe(void)
                struct acpi_generic_address *db_reg;
                struct acpi_pcct_hw_reduced *pcct_ss;
                pcc_mbox_channels[i].con_priv = pcct_entry;
-               pcct_entry = (struct acpi_subtable_header *)
-                       ((unsigned long) pcct_entry + pcct_entry->length);
 
                /* If doorbell is in system memory cache the virt address */
                pcct_ss = (struct acpi_pcct_hw_reduced *)pcct_entry;
@@ -370,6 +368,8 @@ static int __init acpi_pcc_probe(void)
                if (db_reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
                        pcc_doorbell_vaddr[i] = acpi_os_ioremap(db_reg->address,
                                                        db_reg->bit_width/8);
+               pcct_entry = (struct acpi_subtable_header *)
+                       ((unsigned long) pcct_entry + pcct_entry->length);
        }
 
        pcc_mbox_ctrl.num_chans = count;
index bef71751aade88d7277f2ae4573c921f17446304..3fe86b54d50be37e88f83504cff5de90820b5fb7 100644 (file)
@@ -1673,6 +1673,9 @@ static void bitmap_free(struct bitmap *bitmap)
        if (!bitmap) /* there was no bitmap */
                return;
 
+       if (bitmap->sysfs_can_clear)
+               sysfs_put(bitmap->sysfs_can_clear);
+
        if (mddev_is_clustered(bitmap->mddev) && bitmap->mddev->cluster_info &&
                bitmap->cluster_slot == md_cluster_ops->slot_number(bitmap->mddev))
                md_cluster_stop(bitmap->mddev);
@@ -1712,15 +1715,13 @@ void bitmap_destroy(struct mddev *mddev)
        if (mddev->thread)
                mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
 
-       if (bitmap->sysfs_can_clear)
-               sysfs_put(bitmap->sysfs_can_clear);
-
        bitmap_free(bitmap);
 }
 
 /*
  * initialize the bitmap structure
  * if this returns an error, bitmap_destroy must be called to do clean up
+ * once mddev->bitmap is set
  */
 struct bitmap *bitmap_create(struct mddev *mddev, int slot)
 {
@@ -1865,8 +1866,10 @@ int bitmap_copy_from_slot(struct mddev *mddev, int slot,
        struct bitmap_counts *counts;
        struct bitmap *bitmap = bitmap_create(mddev, slot);
 
-       if (IS_ERR(bitmap))
+       if (IS_ERR(bitmap)) {
+               bitmap_free(bitmap);
                return PTR_ERR(bitmap);
+       }
 
        rv = bitmap_init_from_disk(bitmap, 0);
        if (rv)
@@ -2170,14 +2173,14 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
                                else {
                                        mddev->bitmap = bitmap;
                                        rv = bitmap_load(mddev);
-                                       if (rv) {
-                                               bitmap_destroy(mddev);
+                                       if (rv)
                                                mddev->bitmap_info.offset = 0;
-                                       }
                                }
                                mddev->pers->quiesce(mddev, 0);
-                               if (rv)
+                               if (rv) {
+                                       bitmap_destroy(mddev);
                                        return rv;
+                               }
                        }
                }
        }
index c068f171b4eb1140ed7956d8f73f6096c14961a1..194580fba7fd8b7a965ea87f9856cada61e15be6 100644 (file)
@@ -718,6 +718,7 @@ static void super_written(struct bio *bio)
 
        if (atomic_dec_and_test(&mddev->pending_writes))
                wake_up(&mddev->sb_wait);
+       rdev_dec_pending(rdev, mddev);
        bio_put(bio);
 }
 
@@ -732,6 +733,8 @@ void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
         */
        struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, mddev);
 
+       atomic_inc(&rdev->nr_pending);
+
        bio->bi_bdev = rdev->meta_bdev ? rdev->meta_bdev : rdev->bdev;
        bio->bi_iter.bi_sector = sector;
        bio_add_page(bio, page, size, 0);
@@ -6883,7 +6886,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
 
        case ADD_NEW_DISK:
                /* We can support ADD_NEW_DISK on read-only arrays
-                * on if we are re-adding a preexisting device.
+                * only if we are re-adding a preexisting device.
                 * So require mddev->pers and MD_DISK_SYNC.
                 */
                if (mddev->pers) {
index 39fb21e048e642dd2bf6d6729a9e8c0cd61310a9..a7f2b9c9f8a06fa84aa5f46d6c44c5760894502b 100644 (file)
@@ -570,7 +570,7 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect
                        if (best_dist_disk < 0) {
                                if (is_badblock(rdev, this_sector, sectors,
                                                &first_bad, &bad_sectors)) {
-                                       if (first_bad < this_sector)
+                                       if (first_bad <= this_sector)
                                                /* Cannot use this */
                                                continue;
                                        best_good_sectors = first_bad - this_sector;
index 62aa5d0efceecc81c79f36806c91386a37502ff7..79e19017343edb0eeffc1e8ac1ddcbe165994bc3 100644 (file)
@@ -390,6 +390,7 @@ static int byt_sd_probe_slot(struct sdhci_pci_slot *slot)
        slot->cd_idx = 0;
        slot->cd_override_level = true;
        if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BXT_SD ||
+           slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BXTM_SD ||
            slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_APL_SD)
                slot->host->mmc_host_ops.get_cd = bxt_get_cd;
 
@@ -1171,6 +1172,30 @@ static const struct pci_device_id pci_ids[] = {
                .driver_data    = (kernel_ulong_t)&sdhci_intel_byt_sd,
        },
 
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BXTM_EMMC,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_intel_byt_emmc,
+       },
+
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BXTM_SDIO,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_intel_byt_sdio,
+       },
+
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BXTM_SD,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_intel_byt_sd,
+       },
+
        {
                .vendor         = PCI_VENDOR_ID_INTEL,
                .device         = PCI_DEVICE_ID_INTEL_APL_EMMC,
index d1a0b4db60db41d67ad7d0e34652f2d13d2d3507..89e7151684a1fea26c35f27fee1c5ae2332e4eb8 100644 (file)
@@ -28,6 +28,9 @@
 #define PCI_DEVICE_ID_INTEL_BXT_SD     0x0aca
 #define PCI_DEVICE_ID_INTEL_BXT_EMMC   0x0acc
 #define PCI_DEVICE_ID_INTEL_BXT_SDIO   0x0ad0
+#define PCI_DEVICE_ID_INTEL_BXTM_SD    0x1aca
+#define PCI_DEVICE_ID_INTEL_BXTM_EMMC  0x1acc
+#define PCI_DEVICE_ID_INTEL_BXTM_SDIO  0x1ad0
 #define PCI_DEVICE_ID_INTEL_APL_SD     0x5aca
 #define PCI_DEVICE_ID_INTEL_APL_EMMC   0x5acc
 #define PCI_DEVICE_ID_INTEL_APL_SDIO   0x5ad0
index aca439d3ca83fde1b0e63832c15d4eb5fdf9a971..30132500aa1c83aec0c501354d7b9fb4c1fae1a7 100644 (file)
@@ -309,8 +309,30 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
                __func__, uhs, ctrl_2);
 }
 
+static void pxav3_set_power(struct sdhci_host *host, unsigned char mode,
+                           unsigned short vdd)
+{
+       struct mmc_host *mmc = host->mmc;
+       u8 pwr = host->pwr;
+
+       sdhci_set_power(host, mode, vdd);
+
+       if (host->pwr == pwr)
+               return;
+
+       if (host->pwr == 0)
+               vdd = 0;
+
+       if (!IS_ERR(mmc->supply.vmmc)) {
+               spin_unlock_irq(&host->lock);
+               mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+               spin_lock_irq(&host->lock);
+       }
+}
+
 static const struct sdhci_ops pxav3_sdhci_ops = {
        .set_clock = sdhci_set_clock,
+       .set_power = pxav3_set_power,
        .platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
        .get_max_clock = sdhci_pltfm_clk_get_max_clock,
        .set_bus_width = sdhci_set_bus_width,
index 8670f162dec7452153625f589a3d24aec22e889d..6bd3d1794966d13b921751e32a5c670b56799770 100644 (file)
@@ -1210,10 +1210,24 @@ clock_set:
 }
 EXPORT_SYMBOL_GPL(sdhci_set_clock);
 
-static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
-                           unsigned short vdd)
+static void sdhci_set_power_reg(struct sdhci_host *host, unsigned char mode,
+                               unsigned short vdd)
 {
        struct mmc_host *mmc = host->mmc;
+
+       spin_unlock_irq(&host->lock);
+       mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+       spin_lock_irq(&host->lock);
+
+       if (mode != MMC_POWER_OFF)
+               sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
+       else
+               sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
+}
+
+void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
+                    unsigned short vdd)
+{
        u8 pwr = 0;
 
        if (mode != MMC_POWER_OFF) {
@@ -1245,7 +1259,6 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
                sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
                if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
                        sdhci_runtime_pm_bus_off(host);
-               vdd = 0;
        } else {
                /*
                 * Spec says that we should clear the power reg before setting
@@ -1276,12 +1289,20 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
                if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
                        mdelay(10);
        }
+}
+EXPORT_SYMBOL_GPL(sdhci_set_power);
 
-       if (!IS_ERR(mmc->supply.vmmc)) {
-               spin_unlock_irq(&host->lock);
-               mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
-               spin_lock_irq(&host->lock);
-       }
+static void __sdhci_set_power(struct sdhci_host *host, unsigned char mode,
+                             unsigned short vdd)
+{
+       struct mmc_host *mmc = host->mmc;
+
+       if (host->ops->set_power)
+               host->ops->set_power(host, mode, vdd);
+       else if (!IS_ERR(mmc->supply.vmmc))
+               sdhci_set_power_reg(host, mode, vdd);
+       else
+               sdhci_set_power(host, mode, vdd);
 }
 
 /*****************************************************************************\
@@ -1431,7 +1452,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
                }
        }
 
-       sdhci_set_power(host, ios->power_mode, ios->vdd);
+       __sdhci_set_power(host, ios->power_mode, ios->vdd);
 
        if (host->ops->platform_send_init_74_clocks)
                host->ops->platform_send_init_74_clocks(host, ios->power_mode);
index 3bd28033dbd94aa021cbea850ffac71d763edd2b..0f39f4f84d10f2f9a49541701cecb9b105e56100 100644 (file)
@@ -529,6 +529,8 @@ struct sdhci_ops {
 #endif
 
        void    (*set_clock)(struct sdhci_host *host, unsigned int clock);
+       void    (*set_power)(struct sdhci_host *host, unsigned char mode,
+                            unsigned short vdd);
 
        int             (*enable_dma)(struct sdhci_host *host);
        unsigned int    (*get_max_clock)(struct sdhci_host *host);
@@ -660,6 +662,8 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
 }
 
 void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
+void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
+                    unsigned short vdd);
 void sdhci_set_bus_width(struct sdhci_host *host, int width);
 void sdhci_reset(struct sdhci_host *host, u8 mask);
 void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
index 06bc2d2e7a7315ceb0f544aac1fcaec1af51fbc6..a2cdfc1261dc77092049575f5519d7160a1c8f29 100644 (file)
@@ -166,6 +166,7 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN
        CH_PCI_ID_TABLE_FENTRY(0x5099), /* Custom 2x40G QSFP */
        CH_PCI_ID_TABLE_FENTRY(0x509a), /* Custom T520-CR */
        CH_PCI_ID_TABLE_FENTRY(0x509b), /* Custom T540-CR LOM */
+       CH_PCI_ID_TABLE_FENTRY(0x509c), /* Custom T520-CR*/
 
        /* T6 adapters:
         */
index 3fc7bde699ba58e2720b4b4039b31fd4cfdeb706..ae90d4f12b70c7d4b20a7f9f484a351932419547 100644 (file)
@@ -3106,7 +3106,7 @@ static int e1000_maybe_stop_tx(struct net_device *netdev,
        return __e1000_maybe_stop_tx(netdev, size);
 }
 
-#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1)
+#define TXD_USE_COUNT(S, X) (((S) + ((1 << (X)) - 1)) >> (X))
 static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
                                    struct net_device *netdev)
 {
@@ -3256,12 +3256,29 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
                             nr_frags, mss);
 
        if (count) {
+               /* The descriptors needed is higher than other Intel drivers
+                * due to a number of workarounds.  The breakdown is below:
+                * Data descriptors: MAX_SKB_FRAGS + 1
+                * Context Descriptor: 1
+                * Keep head from touching tail: 2
+                * Workarounds: 3
+                */
+               int desc_needed = MAX_SKB_FRAGS + 7;
+
                netdev_sent_queue(netdev, skb->len);
                skb_tx_timestamp(skb);
 
                e1000_tx_queue(adapter, tx_ring, tx_flags, count);
+
+               /* 82544 potentially requires twice as many data descriptors
+                * in order to guarantee buffers don't end on evenly-aligned
+                * dwords
+                */
+               if (adapter->pcix_82544)
+                       desc_needed += MAX_SKB_FRAGS + 1;
+
                /* Make sure there is space in the ring for the next send. */
-               e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
+               e1000_maybe_stop_tx(netdev, tx_ring, desc_needed);
 
                if (!skb->xmit_more ||
                    netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) {
index 67006431726aa03c41f38c5e54bf9009e3bf9aa2..344912957cabb8391dc0a2d46baa16ccb6d3ffc7 100644 (file)
@@ -8559,6 +8559,7 @@ static int i40e_sw_init(struct i40e_pf *pf)
                             I40E_FLAG_OUTER_UDP_CSUM_CAPABLE |
                             I40E_FLAG_WB_ON_ITR_CAPABLE |
                             I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE |
+                            I40E_FLAG_NO_PCI_LINK_CHECK |
                             I40E_FLAG_100M_SGMII_CAPABLE |
                             I40E_FLAG_USE_SET_LLDP_MIB |
                             I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
index 78464fa7fe1f2ecfe93fbaa00e9b300f550cfded..fcbd4be562e2b9ef7e873482d7f00c27c1d3c3d9 100644 (file)
@@ -288,10 +288,6 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
            (priv->pcs == STMMAC_PCS_RTBI))
                goto out;
 
-       /* Never init EEE in case of a switch is attached */
-       if (priv->phydev->is_pseudo_fixed_link)
-               goto out;
-
        /* MAC core supports the EEE feature. */
        if (priv->dma_cap.eee) {
                int tx_lpi_timer = priv->tx_lpi_timer;
@@ -771,10 +767,16 @@ static void stmmac_adjust_link(struct net_device *dev)
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       /* At this stage, it could be needed to setup the EEE or adjust some
-        * MAC related HW registers.
-        */
-       priv->eee_enabled = stmmac_eee_init(priv);
+       if (phydev->is_pseudo_fixed_link)
+               /* Stop PHY layer to call the hook to adjust the link in case
+                * of a switch is attached to the stmmac driver.
+                */
+               phydev->irq = PHY_IGNORE_INTERRUPT;
+       else
+               /* At this stage, init the EEE if supported.
+                * Never called in case of fixed_link.
+                */
+               priv->eee_enabled = stmmac_eee_init(priv);
 }
 
 /**
@@ -865,10 +867,6 @@ static int stmmac_init_phy(struct net_device *dev)
                return -ENODEV;
        }
 
-       /* If attached to a switch, there is no reason to poll phy handler */
-       if (phydev->is_pseudo_fixed_link)
-               phydev->irq = PHY_IGNORE_INTERRUPT;
-
        pr_debug("stmmac_init_phy:  %s: attached to PHY (UID 0x%x)"
                 " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
 
index 510e90a6bb2618186044afab466036927b3ce6c0..2c9e45f50edb299714f2c2fead0e78b4092b5904 100644 (file)
@@ -1015,7 +1015,6 @@ static void tun_net_init(struct net_device *dev)
                /* Zero header length */
                dev->type = ARPHRD_NONE;
                dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
-               dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
                break;
 
        case IFF_TAP:
@@ -1027,7 +1026,6 @@ static void tun_net_init(struct net_device *dev)
 
                eth_hw_addr_random(dev);
 
-               dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
                break;
        }
 }
@@ -1481,6 +1479,8 @@ static void tun_setup(struct net_device *dev)
 
        dev->ethtool_ops = &tun_ethtool_ops;
        dev->destructor = tun_free_netdev;
+       /* We prefer our own queue length */
+       dev->tx_queue_len = TUN_READQ_SIZE;
 }
 
 /* Trivial set of netlink ops to allow deleting tun or tap
index fc82743aefb6574f6a1e47ecd68e1d0b1557507f..19f822d7f65274cb3e4a737240b0bdbfd12a8548 100644 (file)
@@ -407,7 +407,7 @@ static const struct nd_cmd_desc __nd_cmd_dimm_descs[] = {
        [ND_CMD_IMPLEMENTED] = { },
        [ND_CMD_SMART] = {
                .out_num = 2,
-               .out_sizes = { 4, 8, },
+               .out_sizes = { 4, 128, },
        },
        [ND_CMD_SMART_THRESHOLD] = {
                .out_num = 2,
index 79646d0c3277d61ad0b6d901b8d3da5809f2c9bf..182a93fe37128d87d53b3c77d121ca28bb3ec8fd 100644 (file)
@@ -417,8 +417,8 @@ static void __add_badblock_range(struct badblocks *bb, u64 ns_offset, u64 len)
                set_badblock(bb, start_sector, num_sectors);
 }
 
-static void namespace_add_poison(struct list_head *poison_list,
-               struct badblocks *bb, struct resource *res)
+static void badblocks_populate(struct list_head *poison_list,
+               struct badblocks *bb, const struct resource *res)
 {
        struct nd_poison *pl;
 
@@ -460,36 +460,35 @@ static void namespace_add_poison(struct list_head *poison_list,
 }
 
 /**
- * nvdimm_namespace_add_poison() - Convert a list of poison ranges to badblocks
- * @ndns:      the namespace containing poison ranges
- * @bb:                badblocks instance to populate
- * @offset:    offset at the start of the namespace before 'sector 0'
+ * nvdimm_badblocks_populate() - Convert a list of poison ranges to badblocks
+ * @region: parent region of the range to interrogate
+ * @bb: badblocks instance to populate
+ * @res: resource range to consider
  *
- * The poison list generated during NFIT initialization may contain multiple,
- * possibly overlapping ranges in the SPA (System Physical Address) space.
- * Compare each of these ranges to the namespace currently being initialized,
- * and add badblocks to the gendisk for all matching sub-ranges
+ * The poison list generated during bus initialization may contain
+ * multiple, possibly overlapping physical address ranges.  Compare each
+ * of these ranges to the resource range currently being initialized,
+ * and add badblocks entries for all matching sub-ranges
  */
-void nvdimm_namespace_add_poison(struct nd_namespace_common *ndns,
-               struct badblocks *bb, resource_size_t offset)
+void nvdimm_badblocks_populate(struct nd_region *nd_region,
+               struct badblocks *bb, const struct resource *res)
 {
-       struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
-       struct nd_region *nd_region = to_nd_region(ndns->dev.parent);
        struct nvdimm_bus *nvdimm_bus;
        struct list_head *poison_list;
-       struct resource res = {
-               .start = nsio->res.start + offset,
-               .end = nsio->res.end,
-       };
 
-       nvdimm_bus = to_nvdimm_bus(nd_region->dev.parent);
+       if (!is_nd_pmem(&nd_region->dev)) {
+               dev_WARN_ONCE(&nd_region->dev, 1,
+                               "%s only valid for pmem regions\n", __func__);
+               return;
+       }
+       nvdimm_bus = walk_to_nvdimm_bus(&nd_region->dev);
        poison_list = &nvdimm_bus->poison_list;
 
        nvdimm_bus_lock(&nvdimm_bus->dev);
-       namespace_add_poison(poison_list, bb, &res);
+       badblocks_populate(poison_list, bb, res);
        nvdimm_bus_unlock(&nvdimm_bus->dev);
 }
-EXPORT_SYMBOL_GPL(nvdimm_namespace_add_poison);
+EXPORT_SYMBOL_GPL(nvdimm_badblocks_populate);
 
 static int add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length)
 {
index 1799bd97a9ce5783a3cb73883a6328c8bf11fc02..875c524fafb0ed2235a9724517601bf45107c80a 100644 (file)
@@ -266,8 +266,8 @@ int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns);
 int nvdimm_namespace_detach_btt(struct nd_namespace_common *ndns);
 const char *nvdimm_namespace_disk_name(struct nd_namespace_common *ndns,
                char *name);
-void nvdimm_namespace_add_poison(struct nd_namespace_common *ndns,
-               struct badblocks *bb, resource_size_t offset);
+void nvdimm_badblocks_populate(struct nd_region *nd_region,
+               struct badblocks *bb, const struct resource *res);
 int nd_blk_region_init(struct nd_region *nd_region);
 void __nd_iostat_start(struct bio *bio, unsigned long *start);
 static inline bool nd_iostat_start(struct bio *bio, unsigned long *start)
index 254d3bc13f70e22dccbf19709d3e35de8cf78315..e071e214febadae71d2d369319b76cd5b6b1a851 100644 (file)
@@ -376,7 +376,7 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn)
        } else {
                /* from init we validate */
                if (memcmp(nd_pfn->uuid, pfn_sb->uuid, 16) != 0)
-                       return -EINVAL;
+                       return -ENODEV;
        }
 
        if (nd_pfn->align > nvdimm_namespace_capacity(ndns)) {
index 12c86fa80c5f36423b4ca2dc33a60bc1abd2ff0c..8e09c544d892eadfff181bc67c6f9f135adefcaa 100644 (file)
@@ -244,7 +244,9 @@ static void pmem_detach_disk(struct pmem_device *pmem)
 static int pmem_attach_disk(struct device *dev,
                struct nd_namespace_common *ndns, struct pmem_device *pmem)
 {
+       struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
        int nid = dev_to_node(dev);
+       struct resource bb_res;
        struct gendisk *disk;
 
        blk_queue_make_request(pmem->pmem_queue, pmem_make_request);
@@ -271,8 +273,17 @@ static int pmem_attach_disk(struct device *dev,
        devm_exit_badblocks(dev, &pmem->bb);
        if (devm_init_badblocks(dev, &pmem->bb))
                return -ENOMEM;
-       nvdimm_namespace_add_poison(ndns, &pmem->bb, pmem->data_offset);
-
+       bb_res.start = nsio->res.start + pmem->data_offset;
+       bb_res.end = nsio->res.end;
+       if (is_nd_pfn(dev)) {
+               struct nd_pfn *nd_pfn = to_nd_pfn(dev);
+               struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
+
+               bb_res.start += __le32_to_cpu(pfn_sb->start_pad);
+               bb_res.end -= __le32_to_cpu(pfn_sb->end_trunc);
+       }
+       nvdimm_badblocks_populate(to_nd_region(dev->parent), &pmem->bb,
+                       &bb_res);
        disk->bb = &pmem->bb;
        add_disk(disk);
        revalidate_disk(disk);
@@ -553,7 +564,7 @@ static int nd_pmem_probe(struct device *dev)
        ndns->rw_bytes = pmem_rw_bytes;
        if (devm_init_badblocks(dev, &pmem->bb))
                return -ENOMEM;
-       nvdimm_namespace_add_poison(ndns, &pmem->bb, 0);
+       nvdimm_badblocks_populate(nd_region, &pmem->bb, &nsio->res);
 
        if (is_nd_btt(dev)) {
                /* btt allocates its own request_queue */
@@ -595,14 +606,25 @@ static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
 {
        struct pmem_device *pmem = dev_get_drvdata(dev);
        struct nd_namespace_common *ndns = pmem->ndns;
+       struct nd_region *nd_region = to_nd_region(dev->parent);
+       struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
+       struct resource res = {
+               .start = nsio->res.start + pmem->data_offset,
+               .end = nsio->res.end,
+       };
 
        if (event != NVDIMM_REVALIDATE_POISON)
                return;
 
-       if (is_nd_btt(dev))
-               nvdimm_namespace_add_poison(ndns, &pmem->bb, 0);
-       else
-               nvdimm_namespace_add_poison(ndns, &pmem->bb, pmem->data_offset);
+       if (is_nd_pfn(dev)) {
+               struct nd_pfn *nd_pfn = to_nd_pfn(dev);
+               struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
+
+               res.start += __le32_to_cpu(pfn_sb->start_pad);
+               res.end -= __le32_to_cpu(pfn_sb->end_trunc);
+       }
+
+       nvdimm_badblocks_populate(nd_region, &pmem->bb, &res);
 }
 
 MODULE_ALIAS("pmem");
index cdfd01f0adb84f96a1bacf391a28419fe6564d4d..8fad0a7044d3d332b8733eaff65d2fb33dd46e61 100644 (file)
@@ -1091,6 +1091,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = {
        RAPL_CPU(0x3f, rapl_defaults_hsw_server),/* Haswell servers */
        RAPL_CPU(0x4f, rapl_defaults_hsw_server),/* Broadwell servers */
        RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */
+       RAPL_CPU(0x46, rapl_defaults_core),/* Haswell */
        RAPL_CPU(0x47, rapl_defaults_core),/* Broadwell-H */
        RAPL_CPU(0x4E, rapl_defaults_core),/* Skylake */
        RAPL_CPU(0x4C, rapl_defaults_cht),/* Braswell/Cherryview */
index 21a67ed047e8741889ee2a254989f55d095ddbd8..ff6caab8cc8b7c7105d465963b4f84579d1c771e 100644 (file)
@@ -452,10 +452,11 @@ static int aac_slave_configure(struct scsi_device *sdev)
                else if (depth < 2)
                        depth = 2;
                scsi_change_queue_depth(sdev, depth);
-       } else
+       } else {
                scsi_change_queue_depth(sdev, 1);
 
                sdev->tagged_supported = 1;
+       }
 
        return 0;
 }
index 35968bdb48666e9603de837aefecd687ed5cbcea..8fb9643fe6e31f90cb774407dbb617d39a0dd913 100644 (file)
@@ -289,7 +289,7 @@ static void context_reset(struct afu_cmd *cmd)
                atomic64_set(&afu->room, room);
                if (room)
                        goto write_rrin;
-               udelay(nretry);
+               udelay(1 << nretry);
        } while (nretry++ < MC_ROOM_RETRY_CNT);
 
        pr_err("%s: no cmd_room to send reset\n", __func__);
@@ -303,7 +303,7 @@ write_rrin:
                if (rrin != 0x1)
                        break;
                /* Double delay each time */
-               udelay(2 << nretry);
+               udelay(1 << nretry);
        } while (nretry++ < MC_ROOM_RETRY_CNT);
 }
 
@@ -338,7 +338,7 @@ retry:
                        atomic64_set(&afu->room, room);
                        if (room)
                                goto write_ioarrin;
-                       udelay(nretry);
+                       udelay(1 << nretry);
                } while (nretry++ < MC_ROOM_RETRY_CNT);
 
                dev_err(dev, "%s: no cmd_room to send 0x%X\n",
@@ -352,7 +352,7 @@ retry:
                 * afu->room.
                 */
                if (nretry++ < MC_ROOM_RETRY_CNT) {
-                       udelay(nretry);
+                       udelay(1 << nretry);
                        goto retry;
                }
 
@@ -683,28 +683,23 @@ static void stop_afu(struct cxlflash_cfg *cfg)
 }
 
 /**
- * term_mc() - terminates the master context
+ * term_intr() - disables all AFU interrupts
  * @cfg:       Internal structure associated with the host.
  * @level:     Depth of allocation, where to begin waterfall tear down.
  *
  * Safe to call with AFU/MC in partially allocated/initialized state.
  */
-static void term_mc(struct cxlflash_cfg *cfg, enum undo_level level)
+static void term_intr(struct cxlflash_cfg *cfg, enum undo_level level)
 {
-       int rc = 0;
        struct afu *afu = cfg->afu;
        struct device *dev = &cfg->dev->dev;
 
        if (!afu || !cfg->mcctx) {
-               dev_err(dev, "%s: returning from term_mc with NULL afu or MC\n",
-                      __func__);
+               dev_err(dev, "%s: returning with NULL afu or MC\n", __func__);
                return;
        }
 
        switch (level) {
-       case UNDO_START:
-               rc = cxl_stop_context(cfg->mcctx);
-               BUG_ON(rc);
        case UNMAP_THREE:
                cxl_unmap_afu_irq(cfg->mcctx, 3, afu);
        case UNMAP_TWO:
@@ -713,9 +708,34 @@ static void term_mc(struct cxlflash_cfg *cfg, enum undo_level level)
                cxl_unmap_afu_irq(cfg->mcctx, 1, afu);
        case FREE_IRQ:
                cxl_free_afu_irqs(cfg->mcctx);
-       case RELEASE_CONTEXT:
-               cfg->mcctx = NULL;
+               /* fall through */
+       case UNDO_NOOP:
+               /* No action required */
+               break;
+       }
+}
+
+/**
+ * term_mc() - terminates the master context
+ * @cfg:       Internal structure associated with the host.
+ * @level:     Depth of allocation, where to begin waterfall tear down.
+ *
+ * Safe to call with AFU/MC in partially allocated/initialized state.
+ */
+static void term_mc(struct cxlflash_cfg *cfg)
+{
+       int rc = 0;
+       struct afu *afu = cfg->afu;
+       struct device *dev = &cfg->dev->dev;
+
+       if (!afu || !cfg->mcctx) {
+               dev_err(dev, "%s: returning with NULL afu or MC\n", __func__);
+               return;
        }
+
+       rc = cxl_stop_context(cfg->mcctx);
+       WARN_ON(rc);
+       cfg->mcctx = NULL;
 }
 
 /**
@@ -726,10 +746,20 @@ static void term_mc(struct cxlflash_cfg *cfg, enum undo_level level)
  */
 static void term_afu(struct cxlflash_cfg *cfg)
 {
+       /*
+        * Tear down is carefully orchestrated to ensure
+        * no interrupts can come in when the problem state
+        * area is unmapped.
+        *
+        * 1) Disable all AFU interrupts
+        * 2) Unmap the problem state area
+        * 3) Stop the master context
+        */
+       term_intr(cfg, UNMAP_THREE);
        if (cfg->afu)
                stop_afu(cfg);
 
-       term_mc(cfg, UNDO_START);
+       term_mc(cfg);
 
        pr_debug("%s: returning\n", __func__);
 }
@@ -1597,41 +1627,24 @@ static int start_afu(struct cxlflash_cfg *cfg)
 }
 
 /**
- * init_mc() - create and register as the master context
+ * init_intr() - setup interrupt handlers for the master context
  * @cfg:       Internal structure associated with the host.
  *
  * Return: 0 on success, -errno on failure
  */
-static int init_mc(struct cxlflash_cfg *cfg)
+static enum undo_level init_intr(struct cxlflash_cfg *cfg,
+                                struct cxl_context *ctx)
 {
-       struct cxl_context *ctx;
-       struct device *dev = &cfg->dev->dev;
        struct afu *afu = cfg->afu;
+       struct device *dev = &cfg->dev->dev;
        int rc = 0;
-       enum undo_level level;
-
-       ctx = cxl_get_context(cfg->dev);
-       if (unlikely(!ctx))
-               return -ENOMEM;
-       cfg->mcctx = ctx;
-
-       /* Set it up as a master with the CXL */
-       cxl_set_master(ctx);
-
-       /* During initialization reset the AFU to start from a clean slate */
-       rc = cxl_afu_reset(cfg->mcctx);
-       if (unlikely(rc)) {
-               dev_err(dev, "%s: initial AFU reset failed rc=%d\n",
-                       __func__, rc);
-               level = RELEASE_CONTEXT;
-               goto out;
-       }
+       enum undo_level level = UNDO_NOOP;
 
        rc = cxl_allocate_afu_irqs(ctx, 3);
        if (unlikely(rc)) {
                dev_err(dev, "%s: call to allocate_afu_irqs failed rc=%d!\n",
                        __func__, rc);
-               level = RELEASE_CONTEXT;
+               level = UNDO_NOOP;
                goto out;
        }
 
@@ -1661,8 +1674,47 @@ static int init_mc(struct cxlflash_cfg *cfg)
                level = UNMAP_TWO;
                goto out;
        }
+out:
+       return level;
+}
 
-       rc = 0;
+/**
+ * init_mc() - create and register as the master context
+ * @cfg:       Internal structure associated with the host.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int init_mc(struct cxlflash_cfg *cfg)
+{
+       struct cxl_context *ctx;
+       struct device *dev = &cfg->dev->dev;
+       int rc = 0;
+       enum undo_level level;
+
+       ctx = cxl_get_context(cfg->dev);
+       if (unlikely(!ctx)) {
+               rc = -ENOMEM;
+               goto ret;
+       }
+       cfg->mcctx = ctx;
+
+       /* Set it up as a master with the CXL */
+       cxl_set_master(ctx);
+
+       /* During initialization reset the AFU to start from a clean slate */
+       rc = cxl_afu_reset(cfg->mcctx);
+       if (unlikely(rc)) {
+               dev_err(dev, "%s: initial AFU reset failed rc=%d\n",
+                       __func__, rc);
+               goto ret;
+       }
+
+       level = init_intr(cfg, ctx);
+       if (unlikely(level)) {
+               dev_err(dev, "%s: setting up interrupts failed rc=%d\n",
+                       __func__, rc);
+               goto out;
+       }
 
        /* This performs the equivalent of the CXL_IOCTL_START_WORK.
         * The CXL_IOCTL_GET_PROCESS_ELEMENT is implicit in the process
@@ -1678,7 +1730,7 @@ ret:
        pr_debug("%s: returning rc=%d\n", __func__, rc);
        return rc;
 out:
-       term_mc(cfg, level);
+       term_intr(cfg, level);
        goto ret;
 }
 
@@ -1751,7 +1803,8 @@ out:
 err2:
        kref_put(&afu->mapcount, afu_unmap);
 err1:
-       term_mc(cfg, UNDO_START);
+       term_intr(cfg, UNMAP_THREE);
+       term_mc(cfg);
        goto out;
 }
 
@@ -2488,8 +2541,7 @@ static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev,
                if (unlikely(rc))
                        dev_err(dev, "%s: Failed to mark user contexts!(%d)\n",
                                __func__, rc);
-               stop_afu(cfg);
-               term_mc(cfg, UNDO_START);
+               term_afu(cfg);
                return PCI_ERS_RESULT_NEED_RESET;
        case pci_channel_io_perm_failure:
                cfg->state = STATE_FAILTERM;
index 0faed422c7f47eec6ac8f474cb85f7e61dd6ed1d..eb9d8f730b38ec34e86c777d560f3762b48bf3d5 100644 (file)
 #define WWPN_BUF_LEN   (WWPN_LEN + 1)
 
 enum undo_level {
-       RELEASE_CONTEXT = 0,
+       UNDO_NOOP = 0,
        FREE_IRQ,
        UNMAP_ONE,
        UNMAP_TWO,
-       UNMAP_THREE,
-       UNDO_START
+       UNMAP_THREE
 };
 
 struct dev_dependent_vals {
index a404a41e871c23b18aa4ea10d83af322f9107b40..8eaed0522aa36e83ddbe259a4fe2293c5ac61579 100644 (file)
@@ -1112,9 +1112,9 @@ static void alua_bus_detach(struct scsi_device *sdev)
        h->sdev = NULL;
        spin_unlock(&h->pg_lock);
        if (pg) {
-               spin_lock(&pg->lock);
+               spin_lock_irq(&pg->lock);
                list_del_rcu(&h->node);
-               spin_unlock(&pg->lock);
+               spin_unlock_irq(&pg->lock);
                kref_put(&pg->kref, release_port_group);
        }
        sdev->handler_data = NULL;
index e4db5fb3239af700ad60fdf2e21cdb35267cc861..8c44b9c424afec43c10daeba23c16e96b20e127b 100644 (file)
@@ -5030,7 +5030,7 @@ _base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, int sleep_flag,
 static int
 _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
 {
-       int r, i;
+       int r, i, index;
        unsigned long   flags;
        u32 reply_address;
        u16 smid;
@@ -5039,8 +5039,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
        struct _event_ack_list *delayed_event_ack, *delayed_event_ack_next;
        u8 hide_flag;
        struct adapter_reply_queue *reply_q;
-       long reply_post_free;
-       u32 reply_post_free_sz, index = 0;
+       Mpi2ReplyDescriptorsUnion_t *reply_post_free_contig;
 
        dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
            __func__));
@@ -5124,27 +5123,27 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
                _base_assign_reply_queues(ioc);
 
        /* initialize Reply Post Free Queue */
-       reply_post_free_sz = ioc->reply_post_queue_depth *
-           sizeof(Mpi2DefaultReplyDescriptor_t);
-       reply_post_free = (long)ioc->reply_post[index].reply_post_free;
+       index = 0;
+       reply_post_free_contig = ioc->reply_post[0].reply_post_free;
        list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
+               /*
+                * If RDPQ is enabled, switch to the next allocation.
+                * Otherwise advance within the contiguous region.
+                */
+               if (ioc->rdpq_array_enable) {
+                       reply_q->reply_post_free =
+                               ioc->reply_post[index++].reply_post_free;
+               } else {
+                       reply_q->reply_post_free = reply_post_free_contig;
+                       reply_post_free_contig += ioc->reply_post_queue_depth;
+               }
+
                reply_q->reply_post_host_index = 0;
-               reply_q->reply_post_free = (Mpi2ReplyDescriptorsUnion_t *)
-                   reply_post_free;
                for (i = 0; i < ioc->reply_post_queue_depth; i++)
                        reply_q->reply_post_free[i].Words =
                            cpu_to_le64(ULLONG_MAX);
                if (!_base_is_controller_msix_enabled(ioc))
                        goto skip_init_reply_post_free_queue;
-               /*
-                * If RDPQ is enabled, switch to the next allocation.
-                * Otherwise advance within the contiguous region.
-                */
-               if (ioc->rdpq_array_enable)
-                       reply_post_free = (long)
-                           ioc->reply_post[++index].reply_post_free;
-               else
-                       reply_post_free += reply_post_free_sz;
        }
  skip_init_reply_post_free_queue:
 
index b1bf42b93fccb23249e4341e3ce56f6b8c84c5d5..1deb6adc411f795833a444a84b1e80e9f9629c4d 100644 (file)
@@ -784,8 +784,9 @@ void scsi_attach_vpd(struct scsi_device *sdev)
        int pg83_supported = 0;
        unsigned char __rcu *vpd_buf, *orig_vpd_buf = NULL;
 
-       if (sdev->skip_vpd_pages)
+       if (!scsi_device_supports_vpd(sdev))
                return;
+
 retry_pg0:
        vpd_buf = kmalloc(vpd_len, GFP_KERNEL);
        if (!vpd_buf)
index 92ffd2406f97d72fdf08f12ffb07ef2d53627409..2b642b145be1b8a6be08e7eb3829eb6ee357eb4f 100644 (file)
@@ -81,6 +81,7 @@ const char *scsi_host_state_name(enum scsi_host_state state)
        return name;
 }
 
+#ifdef CONFIG_SCSI_DH
 static const struct {
        unsigned char   value;
        char            *name;
@@ -94,7 +95,7 @@ static const struct {
        { SCSI_ACCESS_STATE_TRANSITIONING, "transitioning" },
 };
 
-const char *scsi_access_state_name(unsigned char state)
+static const char *scsi_access_state_name(unsigned char state)
 {
        int i;
        char *name = NULL;
@@ -107,6 +108,7 @@ const char *scsi_access_state_name(unsigned char state)
        }
        return name;
 }
+#endif
 
 static int check_set(unsigned long long *val, char *src)
 {
@@ -226,7 +228,7 @@ show_shost_state(struct device *dev, struct device_attribute *attr, char *buf)
 }
 
 /* DEVICE_ATTR(state) clashes with dev_attr_state for sdev */
-struct device_attribute dev_attr_hstate =
+static struct device_attribute dev_attr_hstate =
        __ATTR(state, S_IRUGO | S_IWUSR, show_shost_state, store_shost_state);
 
 static ssize_t
@@ -401,7 +403,7 @@ static struct attribute *scsi_sysfs_shost_attrs[] = {
        NULL
 };
 
-struct attribute_group scsi_shost_attr_group = {
+static struct attribute_group scsi_shost_attr_group = {
        .attrs =        scsi_sysfs_shost_attrs,
 };
 
index 1bd0753f678aeb702eb0d9f5731f5420bc878915..f52b74cf8d1e691a10676f00c2012f809cc940f8 100644 (file)
@@ -1275,18 +1275,19 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
        struct scsi_device *sdp = sdkp->device;
        struct Scsi_Host *host = sdp->host;
+       sector_t capacity = logical_to_sectors(sdp, sdkp->capacity);
        int diskinfo[4];
 
        /* default to most commonly used values */
-        diskinfo[0] = 0x40;    /* 1 << 6 */
-               diskinfo[1] = 0x20;     /* 1 << 5 */
-               diskinfo[2] = sdkp->capacity >> 11;
-       
+       diskinfo[0] = 0x40;     /* 1 << 6 */
+       diskinfo[1] = 0x20;     /* 1 << 5 */
+       diskinfo[2] = capacity >> 11;
+
        /* override with calculated, extended default, or driver values */
        if (host->hostt->bios_param)
-               host->hostt->bios_param(sdp, bdev, sdkp->capacity, diskinfo);
+               host->hostt->bios_param(sdp, bdev, capacity, diskinfo);
        else
-               scsicam_bios_param(bdev, sdkp->capacity, diskinfo);
+               scsicam_bios_param(bdev, capacity, diskinfo);
 
        geo->heads = diskinfo[0];
        geo->sectors = diskinfo[1];
@@ -2337,14 +2338,6 @@ got_data:
        if (sdkp->capacity > 0xffffffff)
                sdp->use_16_for_rw = 1;
 
-       /* Rescale capacity to 512-byte units */
-       if (sector_size == 4096)
-               sdkp->capacity <<= 3;
-       else if (sector_size == 2048)
-               sdkp->capacity <<= 2;
-       else if (sector_size == 1024)
-               sdkp->capacity <<= 1;
-
        blk_queue_physical_block_size(sdp->request_queue,
                                      sdkp->physical_block_size);
        sdkp->device->sector_size = sector_size;
@@ -2795,28 +2788,6 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
                sdkp->ws10 = 1;
 }
 
-static int sd_try_extended_inquiry(struct scsi_device *sdp)
-{
-       /* Attempt VPD inquiry if the device blacklist explicitly calls
-        * for it.
-        */
-       if (sdp->try_vpd_pages)
-               return 1;
-       /*
-        * Although VPD inquiries can go to SCSI-2 type devices,
-        * some USB ones crash on receiving them, and the pages
-        * we currently ask for are for SPC-3 and beyond
-        */
-       if (sdp->scsi_level > SCSI_SPC_2 && !sdp->skip_vpd_pages)
-               return 1;
-       return 0;
-}
-
-static inline u32 logical_to_sectors(struct scsi_device *sdev, u32 blocks)
-{
-       return blocks << (ilog2(sdev->sector_size) - 9);
-}
-
 /**
  *     sd_revalidate_disk - called the first time a new disk is seen,
  *     performs disk spin up, read_capacity, etc.
@@ -2856,7 +2827,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
        if (sdkp->media_present) {
                sd_read_capacity(sdkp, buffer);
 
-               if (sd_try_extended_inquiry(sdp)) {
+               if (scsi_device_supports_vpd(sdp)) {
                        sd_read_block_provisioning(sdkp);
                        sd_read_block_limits(sdkp);
                        sd_read_block_characteristics(sdkp);
@@ -2900,7 +2871,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
        /* Combine with controller limits */
        q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q));
 
-       set_capacity(disk, sdkp->capacity);
+       set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity));
        sd_config_write_same(sdkp);
        kfree(buffer);
 
index 5f2a84aff29fb9cbd003e5bbe6996355a5c07075..654630bb7d0edeb48438654e47d8a60151d2c87b 100644 (file)
@@ -65,7 +65,7 @@ struct scsi_disk {
        struct device   dev;
        struct gendisk  *disk;
        atomic_t        openers;
-       sector_t        capacity;       /* size in 512-byte sectors */
+       sector_t        capacity;       /* size in logical blocks */
        u32             max_xfer_blocks;
        u32             opt_xfer_blocks;
        u32             max_ws_blocks;
@@ -146,6 +146,11 @@ static inline int scsi_medium_access_command(struct scsi_cmnd *scmd)
        return 0;
 }
 
+static inline sector_t logical_to_sectors(struct scsi_device *sdev, sector_t blocks)
+{
+       return blocks << (ilog2(sdev->sector_size) - 9);
+}
+
 /*
  * A DIF-capable target device can be formatted with different
  * protection schemes.  Currently 0 through 3 are defined:
index cf84581287b91251d3b6d116d920fc0a098b6819..5bac28a3944e2da485d191c83bc0a0bf637f23ba 100644 (file)
@@ -30,6 +30,8 @@ source "drivers/staging/wlan-ng/Kconfig"
 
 source "drivers/staging/comedi/Kconfig"
 
+source "drivers/staging/olpc_dcon/Kconfig"
+
 source "drivers/staging/rtl8192u/Kconfig"
 
 source "drivers/staging/rtl8192e/Kconfig"
index 7d6448d2046499c6335f55c4122649c01d64fd8f..a954242b0f2c2036dff9f6180b8491505d9f90e0 100644 (file)
@@ -4,6 +4,7 @@ obj-y                           += media/
 obj-$(CONFIG_SLICOSS)          += slicoss/
 obj-$(CONFIG_PRISM2_USB)       += wlan-ng/
 obj-$(CONFIG_COMEDI)           += comedi/
+obj-$(CONFIG_FB_OLPC_DCON)     += olpc_dcon/
 obj-$(CONFIG_RTL8192U)         += rtl8192u/
 obj-$(CONFIG_RTL8192E)         += rtl8192e/
 obj-$(CONFIG_R8712U)           += rtl8712/
diff --git a/drivers/staging/olpc_dcon/Kconfig b/drivers/staging/olpc_dcon/Kconfig
new file mode 100644 (file)
index 0000000..d277f04
--- /dev/null
@@ -0,0 +1,35 @@
+config FB_OLPC_DCON
+       tristate "One Laptop Per Child Display CONtroller support"
+       depends on OLPC && FB
+       depends on I2C
+       depends on (GPIO_CS5535 || GPIO_CS5535=n)
+       select BACKLIGHT_CLASS_DEVICE
+       ---help---
+         In order to support very low power operation, the XO laptop uses a
+         secondary Display CONtroller, or DCON.  This secondary controller
+         is present in the video pipeline between the primary display
+         controller (integrate into the processor or chipset) and the LCD
+         panel.  It allows the main processor/display controller to be
+         completely powered off while still retaining an image on the display.
+         This controller is only available on OLPC platforms.  Unless you have
+         one of these platforms, you will want to say 'N'.
+
+config FB_OLPC_DCON_1
+       bool "OLPC XO-1 DCON support"
+       depends on FB_OLPC_DCON && GPIO_CS5535
+       default y
+       ---help---
+         Enable support for the DCON in XO-1 model laptops.  The kernel
+         communicates with the DCON using model-specific code.  If you
+         have an XO-1 (or if you're unsure what model you have), you should
+         say 'Y'.
+
+config FB_OLPC_DCON_1_5
+       bool "OLPC XO-1.5 DCON support"
+       depends on FB_OLPC_DCON && ACPI
+       default y
+       ---help---
+         Enable support for the DCON in XO-1.5 model laptops.  The kernel
+         communicates with the DCON using model-specific code.  If you
+         have an XO-1.5 (or if you're unsure what model you have), you
+         should say 'Y'.
diff --git a/drivers/staging/olpc_dcon/Makefile b/drivers/staging/olpc_dcon/Makefile
new file mode 100644 (file)
index 0000000..36c7e67
--- /dev/null
@@ -0,0 +1,6 @@
+olpc-dcon-objs += olpc_dcon.o
+olpc-dcon-$(CONFIG_FB_OLPC_DCON_1)     += olpc_dcon_xo_1.o
+olpc-dcon-$(CONFIG_FB_OLPC_DCON_1_5)   += olpc_dcon_xo_1_5.o
+obj-$(CONFIG_FB_OLPC_DCON)     += olpc-dcon.o
+
+
diff --git a/drivers/staging/olpc_dcon/TODO b/drivers/staging/olpc_dcon/TODO
new file mode 100644 (file)
index 0000000..61c2e65
--- /dev/null
@@ -0,0 +1,9 @@
+TODO:
+       - see if vx855 gpio API can be made similar enough to cs5535 so we can
+         share more code
+       - allow simultaneous XO-1 and XO-1.5 support
+
+Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
+copy:
+       Daniel Drake <dsd@laptop.org>
+       Jens Frederich <jfrederich@gmail.com>
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c
new file mode 100644 (file)
index 0000000..f45b2ef
--- /dev/null
@@ -0,0 +1,813 @@
+/*
+ * Mainly by David Woodhouse, somewhat modified by Jordan Crouse
+ *
+ * Copyright © 2006-2007  Red Hat, Inc.
+ * Copyright © 2006-2007  Advanced Micro Devices, Inc.
+ * Copyright © 2009       VIA Technology, Inc.
+ * Copyright (c) 2010-2011  Andres Salomon <dilinger@queued.net>
+ *
+ * This program is free software.  You can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/backlight.h>
+#include <linux/device.h>
+#include <linux/uaccess.h>
+#include <linux/ctype.h>
+#include <linux/reboot.h>
+#include <linux/olpc-ec.h>
+#include <asm/tsc.h>
+#include <asm/olpc.h>
+
+#include "olpc_dcon.h"
+
+/* Module definitions */
+
+static ushort resumeline = 898;
+module_param(resumeline, ushort, 0444);
+
+static struct dcon_platform_data *pdata;
+
+/* I2C structures */
+
+/* Platform devices */
+static struct platform_device *dcon_device;
+
+static unsigned short normal_i2c[] = { 0x0d, I2C_CLIENT_END };
+
+static s32 dcon_write(struct dcon_priv *dcon, u8 reg, u16 val)
+{
+       return i2c_smbus_write_word_data(dcon->client, reg, val);
+}
+
+static s32 dcon_read(struct dcon_priv *dcon, u8 reg)
+{
+       return i2c_smbus_read_word_data(dcon->client, reg);
+}
+
+/* ===== API functions - these are called by a variety of users ==== */
+
+static int dcon_hw_init(struct dcon_priv *dcon, int is_init)
+{
+       u16 ver;
+       int rc = 0;
+
+       ver = dcon_read(dcon, DCON_REG_ID);
+       if ((ver >> 8) != 0xDC) {
+               pr_err("DCON ID not 0xDCxx: 0x%04x instead.\n", ver);
+               rc = -ENXIO;
+               goto err;
+       }
+
+       if (is_init) {
+               pr_info("Discovered DCON version %x\n", ver & 0xFF);
+               rc = pdata->init(dcon);
+               if (rc != 0) {
+                       pr_err("Unable to init.\n");
+                       goto err;
+               }
+       }
+
+       if (ver < 0xdc02) {
+               dev_err(&dcon->client->dev,
+                               "DCON v1 is unsupported, giving up..\n");
+               rc = -ENODEV;
+               goto err;
+       }
+
+       /* SDRAM setup/hold time */
+       dcon_write(dcon, 0x3a, 0xc040);
+       dcon_write(dcon, DCON_REG_MEM_OPT_A, 0x0000);  /* clear option bits */
+       dcon_write(dcon, DCON_REG_MEM_OPT_A,
+                               MEM_DLL_CLOCK_DELAY | MEM_POWER_DOWN);
+       dcon_write(dcon, DCON_REG_MEM_OPT_B, MEM_SOFT_RESET);
+
+       /* Colour swizzle, AA, no passthrough, backlight */
+       if (is_init) {
+               dcon->disp_mode = MODE_PASSTHRU | MODE_BL_ENABLE |
+                               MODE_CSWIZZLE | MODE_COL_AA;
+       }
+       dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode);
+
+       /* Set the scanline to interrupt on during resume */
+       dcon_write(dcon, DCON_REG_SCAN_INT, resumeline);
+
+err:
+       return rc;
+}
+
+/*
+ * The smbus doesn't always come back due to what is believed to be
+ * hardware (power rail) bugs.  For older models where this is known to
+ * occur, our solution is to attempt to wait for the bus to stabilize;
+ * if it doesn't happen, cut power to the dcon, repower it, and wait
+ * for the bus to stabilize.  Rinse, repeat until we have a working
+ * smbus.  For newer models, we simply BUG(); we want to know if this
+ * still happens despite the power fixes that have been made!
+ */
+static int dcon_bus_stabilize(struct dcon_priv *dcon, int is_powered_down)
+{
+       unsigned long timeout;
+       u8 pm;
+       int x;
+
+power_up:
+       if (is_powered_down) {
+               pm = 1;
+               x = olpc_ec_cmd(EC_DCON_POWER_MODE, &pm, 1, NULL, 0);
+               if (x) {
+                       pr_warn("unable to force dcon to power up: %d!\n", x);
+                       return x;
+               }
+               usleep_range(10000, 11000);  /* we'll be conservative */
+       }
+
+       pdata->bus_stabilize_wiggle();
+
+       for (x = -1, timeout = 50; timeout && x < 0; timeout--) {
+               usleep_range(1000, 1100);
+               x = dcon_read(dcon, DCON_REG_ID);
+       }
+       if (x < 0) {
+               pr_err("unable to stabilize dcon's smbus, reasserting power and praying.\n");
+               BUG_ON(olpc_board_at_least(olpc_board(0xc2)));
+               pm = 0;
+               olpc_ec_cmd(EC_DCON_POWER_MODE, &pm, 1, NULL, 0);
+               msleep(100);
+               is_powered_down = 1;
+               goto power_up;  /* argh, stupid hardware.. */
+       }
+
+       if (is_powered_down)
+               return dcon_hw_init(dcon, 0);
+       return 0;
+}
+
+static void dcon_set_backlight(struct dcon_priv *dcon, u8 level)
+{
+       dcon->bl_val = level;
+       dcon_write(dcon, DCON_REG_BRIGHT, dcon->bl_val);
+
+       /* Purposely turn off the backlight when we go to level 0 */
+       if (dcon->bl_val == 0) {
+               dcon->disp_mode &= ~MODE_BL_ENABLE;
+               dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode);
+       } else if (!(dcon->disp_mode & MODE_BL_ENABLE)) {
+               dcon->disp_mode |= MODE_BL_ENABLE;
+               dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode);
+       }
+}
+
+/* Set the output type to either color or mono */
+static int dcon_set_mono_mode(struct dcon_priv *dcon, bool enable_mono)
+{
+       if (dcon->mono == enable_mono)
+               return 0;
+
+       dcon->mono = enable_mono;
+
+       if (enable_mono) {
+               dcon->disp_mode &= ~(MODE_CSWIZZLE | MODE_COL_AA);
+               dcon->disp_mode |= MODE_MONO_LUMA;
+       } else {
+               dcon->disp_mode &= ~(MODE_MONO_LUMA);
+               dcon->disp_mode |= MODE_CSWIZZLE | MODE_COL_AA;
+       }
+
+       dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode);
+       return 0;
+}
+
+/* For now, this will be really stupid - we need to address how
+ * DCONLOAD works in a sleep and account for it accordingly
+ */
+
+static void dcon_sleep(struct dcon_priv *dcon, bool sleep)
+{
+       int x;
+
+       /* Turn off the backlight and put the DCON to sleep */
+
+       if (dcon->asleep == sleep)
+               return;
+
+       if (!olpc_board_at_least(olpc_board(0xc2)))
+               return;
+
+       if (sleep) {
+               u8 pm = 0;
+
+               x = olpc_ec_cmd(EC_DCON_POWER_MODE, &pm, 1, NULL, 0);
+               if (x)
+                       pr_warn("unable to force dcon to power down: %d!\n", x);
+               else
+                       dcon->asleep = sleep;
+       } else {
+               /* Only re-enable the backlight if the backlight value is set */
+               if (dcon->bl_val != 0)
+                       dcon->disp_mode |= MODE_BL_ENABLE;
+               x = dcon_bus_stabilize(dcon, 1);
+               if (x)
+                       pr_warn("unable to reinit dcon hardware: %d!\n", x);
+               else
+                       dcon->asleep = sleep;
+
+               /* Restore backlight */
+               dcon_set_backlight(dcon, dcon->bl_val);
+       }
+
+       /* We should turn off some stuff in the framebuffer - but what? */
+}
+
+/* the DCON seems to get confused if we change DCONLOAD too
+ * frequently -- i.e., approximately faster than frame time.
+ * normally we don't change it this fast, so in general we won't
+ * delay here.
+ */
+static void dcon_load_holdoff(struct dcon_priv *dcon)
+{
+       ktime_t delta_t, now;
+
+       while (1) {
+               now = ktime_get();
+               delta_t = ktime_sub(now, dcon->load_time);
+               if (ktime_to_ns(delta_t) > NSEC_PER_MSEC * 20)
+                       break;
+               mdelay(4);
+       }
+}
+
+static bool dcon_blank_fb(struct dcon_priv *dcon, bool blank)
+{
+       int err;
+
+       console_lock();
+       if (!lock_fb_info(dcon->fbinfo)) {
+               console_unlock();
+               dev_err(&dcon->client->dev, "unable to lock framebuffer\n");
+               return false;
+       }
+
+       dcon->ignore_fb_events = true;
+       err = fb_blank(dcon->fbinfo,
+                       blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
+       dcon->ignore_fb_events = false;
+       unlock_fb_info(dcon->fbinfo);
+       console_unlock();
+
+       if (err) {
+               dev_err(&dcon->client->dev, "couldn't %sblank framebuffer\n",
+                               blank ? "" : "un");
+               return false;
+       }
+       return true;
+}
+
+/* Set the source of the display (CPU or DCON) */
+static void dcon_source_switch(struct work_struct *work)
+{
+       struct dcon_priv *dcon = container_of(work, struct dcon_priv,
+                       switch_source);
+       int source = dcon->pending_src;
+
+       if (dcon->curr_src == source)
+               return;
+
+       dcon_load_holdoff(dcon);
+
+       dcon->switched = false;
+
+       switch (source) {
+       case DCON_SOURCE_CPU:
+               pr_info("dcon_source_switch to CPU\n");
+               /* Enable the scanline interrupt bit */
+               if (dcon_write(dcon, DCON_REG_MODE,
+                               dcon->disp_mode | MODE_SCAN_INT))
+                       pr_err("couldn't enable scanline interrupt!\n");
+               else
+                       /* Wait up to one second for the scanline interrupt */
+                       wait_event_timeout(dcon->waitq, dcon->switched, HZ);
+
+               if (!dcon->switched)
+                       pr_err("Timeout entering CPU mode; expect a screen glitch.\n");
+
+               /* Turn off the scanline interrupt */
+               if (dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode))
+                       pr_err("couldn't disable scanline interrupt!\n");
+
+               /*
+                * Ideally we'd like to disable interrupts here so that the
+                * fb unblanking and DCON turn on happen at a known time value;
+                * however, we can't do that right now with fb_blank
+                * messing with semaphores.
+                *
+                * For now, we just hope..
+                */
+               if (!dcon_blank_fb(dcon, false)) {
+                       pr_err("Failed to enter CPU mode\n");
+                       dcon->pending_src = DCON_SOURCE_DCON;
+                       return;
+               }
+
+               /* And turn off the DCON */
+               pdata->set_dconload(1);
+               dcon->load_time = ktime_get();
+
+               pr_info("The CPU has control\n");
+               break;
+       case DCON_SOURCE_DCON:
+       {
+               ktime_t delta_t;
+
+               pr_info("dcon_source_switch to DCON\n");
+
+               /* Clear DCONLOAD - this implies that the DCON is in control */
+               pdata->set_dconload(0);
+               dcon->load_time = ktime_get();
+
+               wait_event_timeout(dcon->waitq, dcon->switched, HZ/2);
+
+               if (!dcon->switched) {
+                       pr_err("Timeout entering DCON mode; expect a screen glitch.\n");
+               } else {
+                       /* sometimes the DCON doesn't follow its own rules,
+                        * and doesn't wait for two vsync pulses before
+                        * ack'ing the frame load with an IRQ.  the result
+                        * is that the display shows the *previously*
+                        * loaded frame.  we can detect this by looking at
+                        * the time between asserting DCONLOAD and the IRQ --
+                        * if it's less than 20msec, then the DCON couldn't
+                        * have seen two VSYNC pulses.  in that case we
+                        * deassert and reassert, and hope for the best.
+                        * see http://dev.laptop.org/ticket/9664
+                        */
+                       delta_t = ktime_sub(dcon->irq_time, dcon->load_time);
+                       if (dcon->switched && ktime_to_ns(delta_t)
+                           < NSEC_PER_MSEC * 20) {
+                               pr_err("missed loading, retrying\n");
+                               pdata->set_dconload(1);
+                               mdelay(41);
+                               pdata->set_dconload(0);
+                               dcon->load_time = ktime_get();
+                               mdelay(41);
+                       }
+               }
+
+               dcon_blank_fb(dcon, true);
+               pr_info("The DCON has control\n");
+               break;
+       }
+       default:
+               BUG();
+       }
+
+       dcon->curr_src = source;
+}
+
+static void dcon_set_source(struct dcon_priv *dcon, int arg)
+{
+       if (dcon->pending_src == arg)
+               return;
+
+       dcon->pending_src = arg;
+
+       if (dcon->curr_src != arg)
+               schedule_work(&dcon->switch_source);
+}
+
+static void dcon_set_source_sync(struct dcon_priv *dcon, int arg)
+{
+       dcon_set_source(dcon, arg);
+       flush_scheduled_work();
+}
+
+static ssize_t dcon_mode_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       struct dcon_priv *dcon = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%4.4X\n", dcon->disp_mode);
+}
+
+static ssize_t dcon_sleep_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       struct dcon_priv *dcon = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d\n", dcon->asleep);
+}
+
+static ssize_t dcon_freeze_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       struct dcon_priv *dcon = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d\n", dcon->curr_src == DCON_SOURCE_DCON ? 1 : 0);
+}
+
+static ssize_t dcon_mono_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       struct dcon_priv *dcon = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d\n", dcon->mono);
+}
+
+static ssize_t dcon_resumeline_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%d\n", resumeline);
+}
+
+static ssize_t dcon_mono_store(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long enable_mono;
+       int rc;
+
+       rc = kstrtoul(buf, 10, &enable_mono);
+       if (rc)
+               return rc;
+
+       dcon_set_mono_mode(dev_get_drvdata(dev), enable_mono ? true : false);
+
+       return count;
+}
+
+static ssize_t dcon_freeze_store(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct dcon_priv *dcon = dev_get_drvdata(dev);
+       unsigned long output;
+       int ret;
+
+       ret = kstrtoul(buf, 10, &output);
+       if (ret)
+               return ret;
+
+       pr_info("dcon_freeze_store: %lu\n", output);
+
+       switch (output) {
+       case 0:
+               dcon_set_source(dcon, DCON_SOURCE_CPU);
+               break;
+       case 1:
+               dcon_set_source_sync(dcon, DCON_SOURCE_DCON);
+               break;
+       case 2:  /* normally unused */
+               dcon_set_source(dcon, DCON_SOURCE_DCON);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return count;
+}
+
+static ssize_t dcon_resumeline_store(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned short rl;
+       int rc;
+
+       rc = kstrtou16(buf, 10, &rl);
+       if (rc)
+               return rc;
+
+       resumeline = rl;
+       dcon_write(dev_get_drvdata(dev), DCON_REG_SCAN_INT, resumeline);
+
+       return count;
+}
+
+static ssize_t dcon_sleep_store(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long output;
+       int ret;
+
+       ret = kstrtoul(buf, 10, &output);
+       if (ret)
+               return ret;
+
+       dcon_sleep(dev_get_drvdata(dev), output ? true : false);
+       return count;
+}
+
+static struct device_attribute dcon_device_files[] = {
+       __ATTR(mode, 0444, dcon_mode_show, NULL),
+       __ATTR(sleep, 0644, dcon_sleep_show, dcon_sleep_store),
+       __ATTR(freeze, 0644, dcon_freeze_show, dcon_freeze_store),
+       __ATTR(monochrome, 0644, dcon_mono_show, dcon_mono_store),
+       __ATTR(resumeline, 0644, dcon_resumeline_show, dcon_resumeline_store),
+};
+
+static int dcon_bl_update(struct backlight_device *dev)
+{
+       struct dcon_priv *dcon = bl_get_data(dev);
+       u8 level = dev->props.brightness & 0x0F;
+
+       if (dev->props.power != FB_BLANK_UNBLANK)
+               level = 0;
+
+       if (level != dcon->bl_val)
+               dcon_set_backlight(dcon, level);
+
+       /* power down the DCON when the screen is blanked */
+       if (!dcon->ignore_fb_events)
+               dcon_sleep(dcon, !!(dev->props.state & BL_CORE_FBBLANK));
+
+       return 0;
+}
+
+static int dcon_bl_get(struct backlight_device *dev)
+{
+       struct dcon_priv *dcon = bl_get_data(dev);
+
+       return dcon->bl_val;
+}
+
+static const struct backlight_ops dcon_bl_ops = {
+       .update_status = dcon_bl_update,
+       .get_brightness = dcon_bl_get,
+};
+
+static struct backlight_properties dcon_bl_props = {
+       .max_brightness = 15,
+       .type = BACKLIGHT_RAW,
+       .power = FB_BLANK_UNBLANK,
+};
+
+static int dcon_reboot_notify(struct notifier_block *nb,
+                             unsigned long foo, void *bar)
+{
+       struct dcon_priv *dcon = container_of(nb, struct dcon_priv, reboot_nb);
+
+       if (!dcon || !dcon->client)
+               return NOTIFY_DONE;
+
+       /* Turn off the DCON. Entirely. */
+       dcon_write(dcon, DCON_REG_MODE, 0x39);
+       dcon_write(dcon, DCON_REG_MODE, 0x32);
+       return NOTIFY_DONE;
+}
+
+static int unfreeze_on_panic(struct notifier_block *nb,
+                            unsigned long e, void *p)
+{
+       pdata->set_dconload(1);
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block dcon_panic_nb = {
+       .notifier_call = unfreeze_on_panic,
+};
+
+static int dcon_detect(struct i2c_client *client, struct i2c_board_info *info)
+{
+       strlcpy(info->type, "olpc_dcon", I2C_NAME_SIZE);
+
+       return 0;
+}
+
+static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+       struct dcon_priv *dcon;
+       int rc, i, j;
+
+       if (!pdata)
+               return -ENXIO;
+
+       dcon = kzalloc(sizeof(*dcon), GFP_KERNEL);
+       if (!dcon)
+               return -ENOMEM;
+
+       dcon->client = client;
+       init_waitqueue_head(&dcon->waitq);
+       INIT_WORK(&dcon->switch_source, dcon_source_switch);
+       dcon->reboot_nb.notifier_call = dcon_reboot_notify;
+       dcon->reboot_nb.priority = -1;
+
+       i2c_set_clientdata(client, dcon);
+
+       if (num_registered_fb < 1) {
+               dev_err(&client->dev, "DCON driver requires a registered fb\n");
+               rc = -EIO;
+               goto einit;
+       }
+       dcon->fbinfo = registered_fb[0];
+
+       rc = dcon_hw_init(dcon, 1);
+       if (rc)
+               goto einit;
+
+       /* Add the DCON device */
+
+       dcon_device = platform_device_alloc("dcon", -1);
+
+       if (!dcon_device) {
+               pr_err("Unable to create the DCON device\n");
+               rc = -ENOMEM;
+               goto eirq;
+       }
+       rc = platform_device_add(dcon_device);
+       platform_set_drvdata(dcon_device, dcon);
+
+       if (rc) {
+               pr_err("Unable to add the DCON device\n");
+               goto edev;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(dcon_device_files); i++) {
+               rc = device_create_file(&dcon_device->dev,
+                                       &dcon_device_files[i]);
+               if (rc) {
+                       dev_err(&dcon_device->dev, "Cannot create sysfs file\n");
+                       goto ecreate;
+               }
+       }
+
+       dcon->bl_val = dcon_read(dcon, DCON_REG_BRIGHT) & 0x0F;
+
+       /* Add the backlight device for the DCON */
+       dcon_bl_props.brightness = dcon->bl_val;
+       dcon->bl_dev = backlight_device_register("dcon-bl", &dcon_device->dev,
+               dcon, &dcon_bl_ops, &dcon_bl_props);
+       if (IS_ERR(dcon->bl_dev)) {
+               dev_err(&client->dev, "cannot register backlight dev (%ld)\n",
+                               PTR_ERR(dcon->bl_dev));
+               dcon->bl_dev = NULL;
+       }
+
+       register_reboot_notifier(&dcon->reboot_nb);
+       atomic_notifier_chain_register(&panic_notifier_list, &dcon_panic_nb);
+
+       return 0;
+
+ ecreate:
+       for (j = 0; j < i; j++)
+               device_remove_file(&dcon_device->dev, &dcon_device_files[j]);
+ edev:
+       platform_device_unregister(dcon_device);
+       dcon_device = NULL;
+ eirq:
+       free_irq(DCON_IRQ, dcon);
+ einit:
+       kfree(dcon);
+       return rc;
+}
+
+static int dcon_remove(struct i2c_client *client)
+{
+       struct dcon_priv *dcon = i2c_get_clientdata(client);
+
+       unregister_reboot_notifier(&dcon->reboot_nb);
+       atomic_notifier_chain_unregister(&panic_notifier_list, &dcon_panic_nb);
+
+       free_irq(DCON_IRQ, dcon);
+
+       backlight_device_unregister(dcon->bl_dev);
+
+       if (dcon_device)
+               platform_device_unregister(dcon_device);
+       cancel_work_sync(&dcon->switch_source);
+
+       kfree(dcon);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int dcon_suspend(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct dcon_priv *dcon = i2c_get_clientdata(client);
+
+       if (!dcon->asleep) {
+               /* Set up the DCON to have the source */
+               dcon_set_source_sync(dcon, DCON_SOURCE_DCON);
+       }
+
+       return 0;
+}
+
+static int dcon_resume(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct dcon_priv *dcon = i2c_get_clientdata(client);
+
+       if (!dcon->asleep) {
+               dcon_bus_stabilize(dcon, 0);
+               dcon_set_source(dcon, DCON_SOURCE_CPU);
+       }
+
+       return 0;
+}
+
+#else
+
+#define dcon_suspend NULL
+#define dcon_resume NULL
+
+#endif /* CONFIG_PM */
+
+irqreturn_t dcon_interrupt(int irq, void *id)
+{
+       struct dcon_priv *dcon = id;
+       u8 status;
+
+       if (pdata->read_status(&status))
+               return IRQ_NONE;
+
+       switch (status & 3) {
+       case 3:
+               pr_debug("DCONLOAD_MISSED interrupt\n");
+               break;
+
+       case 2: /* switch to DCON mode */
+       case 1: /* switch to CPU mode */
+               dcon->switched = true;
+               dcon->irq_time = ktime_get();
+               wake_up(&dcon->waitq);
+               break;
+
+       case 0:
+               /* workaround resume case:  the DCON (on 1.5) doesn't
+                * ever assert status 0x01 when switching to CPU mode
+                * during resume.  this is because DCONLOAD is de-asserted
+                * _immediately_ upon exiting S3, so the actual release
+                * of the DCON happened long before this point.
+                * see http://dev.laptop.org/ticket/9869
+                */
+               if (dcon->curr_src != dcon->pending_src && !dcon->switched) {
+                       dcon->switched = true;
+                       dcon->irq_time = ktime_get();
+                       wake_up(&dcon->waitq);
+                       pr_debug("switching w/ status 0/0\n");
+               } else {
+                       pr_debug("scanline interrupt w/CPU\n");
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+static const struct dev_pm_ops dcon_pm_ops = {
+       .suspend = dcon_suspend,
+       .resume = dcon_resume,
+};
+
+static const struct i2c_device_id dcon_idtable[] = {
+       { "olpc_dcon",  0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, dcon_idtable);
+
+static struct i2c_driver dcon_driver = {
+       .driver = {
+               .name   = "olpc_dcon",
+               .pm = &dcon_pm_ops,
+       },
+       .class = I2C_CLASS_DDC | I2C_CLASS_HWMON,
+       .id_table = dcon_idtable,
+       .probe = dcon_probe,
+       .remove = dcon_remove,
+       .detect = dcon_detect,
+       .address_list = normal_i2c,
+};
+
+static int __init olpc_dcon_init(void)
+{
+#ifdef CONFIG_FB_OLPC_DCON_1_5
+       /* XO-1.5 */
+       if (olpc_board_at_least(olpc_board(0xd0)))
+               pdata = &dcon_pdata_xo_1_5;
+#endif
+#ifdef CONFIG_FB_OLPC_DCON_1
+       if (!pdata)
+               pdata = &dcon_pdata_xo_1;
+#endif
+
+       return i2c_add_driver(&dcon_driver);
+}
+
+static void __exit olpc_dcon_exit(void)
+{
+       i2c_del_driver(&dcon_driver);
+}
+
+module_init(olpc_dcon_init);
+module_exit(olpc_dcon_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h
new file mode 100644 (file)
index 0000000..215e7ec
--- /dev/null
@@ -0,0 +1,111 @@
+#ifndef OLPC_DCON_H_
+#define OLPC_DCON_H_
+
+#include <linux/notifier.h>
+#include <linux/workqueue.h>
+
+/* DCON registers */
+
+#define DCON_REG_ID             0
+#define DCON_REG_MODE           1
+
+#define MODE_PASSTHRU  (1<<0)
+#define MODE_SLEEP     (1<<1)
+#define MODE_SLEEP_AUTO        (1<<2)
+#define MODE_BL_ENABLE (1<<3)
+#define MODE_BLANK     (1<<4)
+#define MODE_CSWIZZLE  (1<<5)
+#define MODE_COL_AA    (1<<6)
+#define MODE_MONO_LUMA (1<<7)
+#define MODE_SCAN_INT  (1<<8)
+#define MODE_CLOCKDIV  (1<<9)
+#define MODE_DEBUG     (1<<14)
+#define MODE_SELFTEST  (1<<15)
+
+#define DCON_REG_HRES          0x2
+#define DCON_REG_HTOTAL                0x3
+#define DCON_REG_HSYNC_WIDTH   0x4
+#define DCON_REG_VRES          0x5
+#define DCON_REG_VTOTAL                0x6
+#define DCON_REG_VSYNC_WIDTH   0x7
+#define DCON_REG_TIMEOUT       0x8
+#define DCON_REG_SCAN_INT      0x9
+#define DCON_REG_BRIGHT                0xa
+#define DCON_REG_MEM_OPT_A     0x41
+#define DCON_REG_MEM_OPT_B     0x42
+
+/* Load Delay Locked Loop (DLL) settings for clock delay */
+#define MEM_DLL_CLOCK_DELAY    (1<<0)
+/* Memory controller power down function */
+#define MEM_POWER_DOWN         (1<<8)
+/* Memory controller software reset */
+#define MEM_SOFT_RESET         (1<<0)
+
+/* Status values */
+
+#define DCONSTAT_SCANINT       0
+#define DCONSTAT_SCANINT_DCON  1
+#define DCONSTAT_DISPLAYLOAD   2
+#define DCONSTAT_MISSED                3
+
+/* Source values */
+
+#define DCON_SOURCE_DCON        0
+#define DCON_SOURCE_CPU         1
+
+/* Interrupt */
+#define DCON_IRQ                6
+
+struct dcon_priv {
+       struct i2c_client *client;
+       struct fb_info *fbinfo;
+       struct backlight_device *bl_dev;
+
+       wait_queue_head_t waitq;
+       struct work_struct switch_source;
+       struct notifier_block reboot_nb;
+
+       /* Shadow register for the DCON_REG_MODE register */
+       u8 disp_mode;
+
+       /* The current backlight value - this saves us some smbus traffic */
+       u8 bl_val;
+
+       /* Current source, initialized at probe time */
+       int curr_src;
+
+       /* Desired source */
+       int pending_src;
+
+       /* Variables used during switches */
+       bool switched;
+       ktime_t irq_time;
+       ktime_t load_time;
+
+       /* Current output type; true == mono, false == color */
+       bool mono;
+       bool asleep;
+       /* This get set while controlling fb blank state from the driver */
+       bool ignore_fb_events;
+};
+
+struct dcon_platform_data {
+       int (*init)(struct dcon_priv *);
+       void (*bus_stabilize_wiggle)(void);
+       void (*set_dconload)(int);
+       int (*read_status)(u8 *);
+};
+
+#include <linux/interrupt.h>
+
+irqreturn_t dcon_interrupt(int irq, void *id);
+
+#ifdef CONFIG_FB_OLPC_DCON_1
+extern struct dcon_platform_data dcon_pdata_xo_1;
+#endif
+
+#ifdef CONFIG_FB_OLPC_DCON_1_5
+extern struct dcon_platform_data dcon_pdata_xo_1_5;
+#endif
+
+#endif
diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
new file mode 100644 (file)
index 0000000..0c5a10c
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * Mainly by David Woodhouse, somewhat modified by Jordan Crouse
+ *
+ * Copyright © 2006-2007  Red Hat, Inc.
+ * Copyright © 2006-2007  Advanced Micro Devices, Inc.
+ * Copyright © 2009       VIA Technology, Inc.
+ * Copyright (c) 2010  Andres Salomon <dilinger@queued.net>
+ *
+ * This program is free software.  You can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/cs5535.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <asm/olpc.h>
+
+#include "olpc_dcon.h"
+
+static int dcon_init_xo_1(struct dcon_priv *dcon)
+{
+       unsigned char lob;
+
+       if (gpio_request(OLPC_GPIO_DCON_STAT0, "OLPC-DCON")) {
+               pr_err("failed to request STAT0 GPIO\n");
+               return -EIO;
+       }
+       if (gpio_request(OLPC_GPIO_DCON_STAT1, "OLPC-DCON")) {
+               pr_err("failed to request STAT1 GPIO\n");
+               goto err_gp_stat1;
+       }
+       if (gpio_request(OLPC_GPIO_DCON_IRQ, "OLPC-DCON")) {
+               pr_err("failed to request IRQ GPIO\n");
+               goto err_gp_irq;
+       }
+       if (gpio_request(OLPC_GPIO_DCON_LOAD, "OLPC-DCON")) {
+               pr_err("failed to request LOAD GPIO\n");
+               goto err_gp_load;
+       }
+       if (gpio_request(OLPC_GPIO_DCON_BLANK, "OLPC-DCON")) {
+               pr_err("failed to request BLANK GPIO\n");
+               goto err_gp_blank;
+       }
+
+       /* Turn off the event enable for GPIO7 just to be safe */
+       cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_EVENTS_ENABLE);
+
+       /*
+        * Determine the current state by reading the GPIO bit; earlier
+        * stages of the boot process have established the state.
+        *
+        * Note that we read GPIO_OUTPUT_VAL rather than GPIO_READ_BACK here;
+        * this is because OFW will disable input for the pin and set a value..
+        * READ_BACK will only contain a valid value if input is enabled and
+        * then a value is set.  So, future readings of the pin can use
+        * READ_BACK, but the first one cannot.  Awesome, huh?
+        */
+       dcon->curr_src = cs5535_gpio_isset(OLPC_GPIO_DCON_LOAD, GPIO_OUTPUT_VAL)
+               ? DCON_SOURCE_CPU
+               : DCON_SOURCE_DCON;
+       dcon->pending_src = dcon->curr_src;
+
+       /* Set the directions for the GPIO pins */
+       gpio_direction_input(OLPC_GPIO_DCON_STAT0);
+       gpio_direction_input(OLPC_GPIO_DCON_STAT1);
+       gpio_direction_input(OLPC_GPIO_DCON_IRQ);
+       gpio_direction_input(OLPC_GPIO_DCON_BLANK);
+       gpio_direction_output(OLPC_GPIO_DCON_LOAD,
+                       dcon->curr_src == DCON_SOURCE_CPU);
+
+       /* Set up the interrupt mappings */
+
+       /* Set the IRQ to pair 2 */
+       cs5535_gpio_setup_event(OLPC_GPIO_DCON_IRQ, 2, 0);
+
+       /* Enable group 2 to trigger the DCON interrupt */
+       cs5535_gpio_set_irq(2, DCON_IRQ);
+
+       /* Select edge level for interrupt (in PIC) */
+       lob = inb(0x4d0);
+       lob &= ~(1 << DCON_IRQ);
+       outb(lob, 0x4d0);
+
+       /* Register the interrupt handler */
+       if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", dcon)) {
+               pr_err("failed to request DCON's irq\n");
+               goto err_req_irq;
+       }
+
+       /* Clear INV_EN for GPIO7 (DCONIRQ) */
+       cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_INPUT_INVERT);
+
+       /* Enable filter for GPIO12 (DCONBLANK) */
+       cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_INPUT_FILTER);
+
+       /* Disable filter for GPIO7 */
+       cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_INPUT_FILTER);
+
+       /* Disable event counter for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */
+       cs5535_gpio_clear(OLPC_GPIO_DCON_IRQ, GPIO_INPUT_EVENT_COUNT);
+       cs5535_gpio_clear(OLPC_GPIO_DCON_BLANK, GPIO_INPUT_EVENT_COUNT);
+
+       /* Add GPIO12 to the Filter Event Pair #7 */
+       cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_FE7_SEL);
+
+       /* Turn off negative Edge Enable for GPIO12 */
+       cs5535_gpio_clear(OLPC_GPIO_DCON_BLANK, GPIO_NEGATIVE_EDGE_EN);
+
+       /* Enable negative Edge Enable for GPIO7 */
+       cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_EN);
+
+       /* Zero the filter amount for Filter Event Pair #7 */
+       cs5535_gpio_set(0, GPIO_FLTR7_AMOUNT);
+
+       /* Clear the negative edge status for GPIO7 and GPIO12 */
+       cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_STS);
+       cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_NEGATIVE_EDGE_STS);
+
+       /* FIXME:  Clear the positive status as well, just to be sure */
+       cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_POSITIVE_EDGE_STS);
+       cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_POSITIVE_EDGE_STS);
+
+       /* Enable events for GPIO7 (DCONIRQ) and GPIO12 (DCONBLANK) */
+       cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_EVENTS_ENABLE);
+       cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_EVENTS_ENABLE);
+
+       return 0;
+
+err_req_irq:
+       gpio_free(OLPC_GPIO_DCON_BLANK);
+err_gp_blank:
+       gpio_free(OLPC_GPIO_DCON_LOAD);
+err_gp_load:
+       gpio_free(OLPC_GPIO_DCON_IRQ);
+err_gp_irq:
+       gpio_free(OLPC_GPIO_DCON_STAT1);
+err_gp_stat1:
+       gpio_free(OLPC_GPIO_DCON_STAT0);
+       return -EIO;
+}
+
+static void dcon_wiggle_xo_1(void)
+{
+       int x;
+
+       /*
+        * According to HiMax, when powering the DCON up we should hold
+        * SMB_DATA high for 8 SMB_CLK cycles.  This will force the DCON
+        * state machine to reset to a (sane) initial state.  Mitch Bradley
+        * did some testing and discovered that holding for 16 SMB_CLK cycles
+        * worked a lot more reliably, so that's what we do here.
+        *
+        * According to the cs5536 spec, to set GPIO14 to SMB_CLK we must
+        * simultaneously set AUX1 IN/OUT to GPIO14; ditto for SMB_DATA and
+        * GPIO15.
+        */
+       cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL);
+       cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_VAL);
+       cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_ENABLE);
+       cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_ENABLE);
+       cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_AUX1);
+       cs5535_gpio_clear(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX1);
+       cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_AUX2);
+       cs5535_gpio_clear(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX2);
+       cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_INPUT_AUX1);
+       cs5535_gpio_clear(OLPC_GPIO_SMB_DATA, GPIO_INPUT_AUX1);
+
+       for (x = 0; x < 16; x++) {
+               udelay(5);
+               cs5535_gpio_clear(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL);
+               udelay(5);
+               cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL);
+       }
+       udelay(5);
+       cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_AUX1);
+       cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_AUX1);
+       cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_INPUT_AUX1);
+       cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_INPUT_AUX1);
+}
+
+static void dcon_set_dconload_1(int val)
+{
+       gpio_set_value(OLPC_GPIO_DCON_LOAD, val);
+}
+
+static int dcon_read_status_xo_1(u8 *status)
+{
+       *status = gpio_get_value(OLPC_GPIO_DCON_STAT0);
+       *status |= gpio_get_value(OLPC_GPIO_DCON_STAT1) << 1;
+
+       /* Clear the negative edge status for GPIO7 */
+       cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_STS);
+
+       return 0;
+}
+
+struct dcon_platform_data dcon_pdata_xo_1 = {
+       .init = dcon_init_xo_1,
+       .bus_stabilize_wiggle = dcon_wiggle_xo_1,
+       .set_dconload = dcon_set_dconload_1,
+       .read_status = dcon_read_status_xo_1,
+};
diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
new file mode 100644 (file)
index 0000000..6a4d379
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2009,2010       One Laptop per Child
+ *
+ * This program is free software.  You can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <asm/olpc.h>
+
+/* TODO: this eventually belongs in linux/vx855.h */
+#define NR_VX855_GPI    14
+#define NR_VX855_GPO    13
+#define NR_VX855_GPIO   15
+
+#define VX855_GPI(n)    (n)
+#define VX855_GPO(n)    (NR_VX855_GPI + (n))
+#define VX855_GPIO(n)   (NR_VX855_GPI + NR_VX855_GPO + (n))
+
+#include "olpc_dcon.h"
+
+/* Hardware setup on the XO 1.5:
+ *     DCONLOAD connects to VX855_GPIO1 (not SMBCK2)
+ *     DCONBLANK connects to VX855_GPIO8 (not SSPICLK)  unused in driver
+ *     DCONSTAT0 connects to VX855_GPI10 (not SSPISDI)
+ *     DCONSTAT1 connects to VX855_GPI11 (not nSSPISS)
+ *     DCONIRQ connects to VX855_GPIO12
+ *     DCONSMBDATA connects to VX855 graphics CRTSPD
+ *     DCONSMBCLK connects to VX855 graphics CRTSPCLK
+ */
+
+#define VX855_GENL_PURPOSE_OUTPUT 0x44c /* PMIO_Rx4c-4f */
+#define VX855_GPI_STATUS_CHG 0x450  /* PMIO_Rx50 */
+#define VX855_GPI_SCI_SMI 0x452  /* PMIO_Rx52 */
+#define BIT_GPIO12 0x40
+
+#define PREFIX "OLPC DCON:"
+
+static void dcon_clear_irq(void)
+{
+       /* irq status will appear in PMIO_Rx50[6] (RW1C) on gpio12 */
+       outb(BIT_GPIO12, VX855_GPI_STATUS_CHG);
+}
+
+static int dcon_was_irq(void)
+{
+       u_int8_t tmp;
+
+       /* irq status will appear in PMIO_Rx50[6] on gpio12 */
+       tmp = inb(VX855_GPI_STATUS_CHG);
+       return !!(tmp & BIT_GPIO12);
+
+       return 0;
+}
+
+static int dcon_init_xo_1_5(struct dcon_priv *dcon)
+{
+       unsigned int irq;
+
+       dcon_clear_irq();
+
+       /* set   PMIO_Rx52[6] to enable SCI/SMI on gpio12 */
+       outb(inb(VX855_GPI_SCI_SMI)|BIT_GPIO12, VX855_GPI_SCI_SMI);
+
+       /* Determine the current state of DCONLOAD, likely set by firmware */
+       /* GPIO1 */
+       dcon->curr_src = (inl(VX855_GENL_PURPOSE_OUTPUT) & 0x1000) ?
+                       DCON_SOURCE_CPU : DCON_SOURCE_DCON;
+       dcon->pending_src = dcon->curr_src;
+
+       /* we're sharing the IRQ with ACPI */
+       irq = acpi_gbl_FADT.sci_interrupt;
+       if (request_irq(irq, &dcon_interrupt, IRQF_SHARED, "DCON", dcon)) {
+               pr_err("DCON (IRQ%d) allocation failed\n", irq);
+               return 1;
+       }
+
+       return 0;
+}
+
+static void set_i2c_line(int sda, int scl)
+{
+       unsigned char tmp;
+       unsigned int port = 0x26;
+
+       /* FIXME: This directly accesses the CRT GPIO controller !!! */
+       outb(port, 0x3c4);
+       tmp = inb(0x3c5);
+
+       if (scl)
+               tmp |= 0x20;
+       else
+               tmp &= ~0x20;
+
+       if (sda)
+               tmp |= 0x10;
+       else
+               tmp &= ~0x10;
+
+       tmp |= 0x01;
+
+       outb(port, 0x3c4);
+       outb(tmp, 0x3c5);
+}
+
+
+static void dcon_wiggle_xo_1_5(void)
+{
+       int x;
+
+       /*
+        * According to HiMax, when powering the DCON up we should hold
+        * SMB_DATA high for 8 SMB_CLK cycles.  This will force the DCON
+        * state machine to reset to a (sane) initial state.  Mitch Bradley
+        * did some testing and discovered that holding for 16 SMB_CLK cycles
+        * worked a lot more reliably, so that's what we do here.
+        */
+       set_i2c_line(1, 1);
+
+       for (x = 0; x < 16; x++) {
+               udelay(5);
+               set_i2c_line(1, 0);
+               udelay(5);
+               set_i2c_line(1, 1);
+       }
+       udelay(5);
+
+       /* set   PMIO_Rx52[6] to enable SCI/SMI on gpio12 */
+       outb(inb(VX855_GPI_SCI_SMI)|BIT_GPIO12, VX855_GPI_SCI_SMI);
+}
+
+static void dcon_set_dconload_xo_1_5(int val)
+{
+       gpio_set_value(VX855_GPIO(1), val);
+}
+
+static int dcon_read_status_xo_1_5(u8 *status)
+{
+       if (!dcon_was_irq())
+               return -1;
+
+       /* i believe this is the same as "inb(0x44b) & 3" */
+       *status = gpio_get_value(VX855_GPI(10));
+       *status |= gpio_get_value(VX855_GPI(11)) << 1;
+
+       dcon_clear_irq();
+
+       return 0;
+}
+
+struct dcon_platform_data dcon_pdata_xo_1_5 = {
+       .init = dcon_init_xo_1_5,
+       .bus_stabilize_wiggle = dcon_wiggle_xo_1_5,
+       .set_dconload = dcon_set_dconload_xo_1_5,
+       .read_status = dcon_read_status_xo_1_5,
+};
index 3e668d852f03029985b131544d67b2b47fe45376..a925fb0db70603f3ec64b99c92bbdcf365463fc3 100644 (file)
@@ -2,6 +2,7 @@ config INFINIBAND_HFI1
        tristate "Intel OPA Gen1 support"
        depends on X86_64 && INFINIBAND_RDMAVT
        select MMU_NOTIFIER
+       select CRC32
        default m
        ---help---
        This is a low-level driver for Intel OPA Gen1 adapter.
index 8d26ed79bb4c593a1dabbd4ab76b45be2338e8fc..9b04d72e752e5e398aef0122eabf0d9ba2d2e1c1 100644 (file)
@@ -2049,14 +2049,13 @@ static struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode,
        if (tty) {
                mutex_unlock(&tty_mutex);
                retval = tty_lock_interruptible(tty);
+               tty_kref_put(tty);  /* drop kref from tty_driver_lookup_tty() */
                if (retval) {
                        if (retval == -EINTR)
                                retval = -ERESTARTSYS;
                        tty = ERR_PTR(retval);
                        goto out;
                }
-               /* safe to drop the kref from tty_driver_lookup_tty() */
-               tty_kref_put(tty);
                retval = tty_reopen(tty);
                if (retval < 0) {
                        tty_unlock(tty);
@@ -2158,7 +2157,7 @@ retry_open:
        read_lock(&tasklist_lock);
        spin_lock_irq(&current->sighand->siglock);
        noctty = (filp->f_flags & O_NOCTTY) ||
-                       device == MKDEV(TTY_MAJOR, 0) ||
+                       (IS_ENABLED(CONFIG_VT) && device == MKDEV(TTY_MAJOR, 0)) ||
                        device == MKDEV(TTYAUX_MAJOR, 1) ||
                        (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
                         tty->driver->subtype == PTY_TYPE_MASTER);
index 5eb1a87228b47afd397fecfd4180413e7043a304..31ccdccd7a04fda36003cdc3ba58b82e25773fa9 100644 (file)
@@ -75,8 +75,6 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
         * be the first thing immediately following the endpoint descriptor.
         */
        desc = (struct usb_ss_ep_comp_descriptor *) buffer;
-       buffer += desc->bLength;
-       size -= desc->bLength;
 
        if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP ||
                        size < USB_DT_SS_EP_COMP_SIZE) {
@@ -100,7 +98,8 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
                                        ep->desc.wMaxPacketSize;
                return;
        }
-
+       buffer += desc->bLength;
+       size -= desc->bLength;
        memcpy(&ep->ss_ep_comp, desc, USB_DT_SS_EP_COMP_SIZE);
 
        /* Check the various values */
@@ -146,12 +145,6 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
                ep->ss_ep_comp.bmAttributes = 2;
        }
 
-       /* Parse a possible SuperSpeedPlus isoc ep companion descriptor */
-       if (usb_endpoint_xfer_isoc(&ep->desc) &&
-           USB_SS_SSP_ISOC_COMP(desc->bmAttributes))
-               usb_parse_ssp_isoc_endpoint_companion(ddev, cfgno, inum, asnum,
-                                                       ep, buffer, size);
-
        if (usb_endpoint_xfer_isoc(&ep->desc))
                max_tx = (desc->bMaxBurst + 1) *
                        (USB_SS_MULT(desc->bmAttributes)) *
@@ -171,6 +164,11 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
                                max_tx);
                ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);
        }
+       /* Parse a possible SuperSpeedPlus isoc ep companion descriptor */
+       if (usb_endpoint_xfer_isoc(&ep->desc) &&
+           USB_SS_SSP_ISOC_COMP(desc->bmAttributes))
+               usb_parse_ssp_isoc_endpoint_companion(ddev, cfgno, inum, asnum,
+                                                       ep, buffer, size);
 }
 
 static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
index e9940dd004e46c11472f776d79aebddc6497a906..818f158232bb6eb84e13e16a85808a25b7b1f668 100644 (file)
@@ -2254,6 +2254,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 {
        u32 intmsk;
        u32 val;
+       u32 usbcfg;
 
        /* Kill any ep0 requests as controller will be reinitialized */
        kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET);
@@ -2267,10 +2268,16 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
         * set configuration.
         */
 
+       /* keep other bits untouched (so e.g. forced modes are not lost) */
+       usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
+       usbcfg &= ~(GUSBCFG_TOUTCAL_MASK | GUSBCFG_PHYIF16 | GUSBCFG_SRPCAP |
+               GUSBCFG_HNPCAP);
+
        /* set the PLL on, remove the HNP/SRP and set the PHY */
        val = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5;
-       dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) |
-              (val << GUSBCFG_USBTRDTIM_SHIFT), hsotg->regs + GUSBCFG);
+       usbcfg |= hsotg->phyif | GUSBCFG_TOUTCAL(7) |
+               (val << GUSBCFG_USBTRDTIM_SHIFT);
+       dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 
        dwc2_hsotg_init_fifo(hsotg);
 
@@ -3031,6 +3038,7 @@ static struct usb_ep_ops dwc2_hsotg_ep_ops = {
 static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg)
 {
        u32 trdtim;
+       u32 usbcfg;
        /* unmask subset of endpoint interrupts */
 
        dwc2_writel(DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK |
@@ -3054,11 +3062,16 @@ static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg)
 
        dwc2_hsotg_init_fifo(hsotg);
 
+       /* keep other bits untouched (so e.g. forced modes are not lost) */
+       usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
+       usbcfg &= ~(GUSBCFG_TOUTCAL_MASK | GUSBCFG_PHYIF16 | GUSBCFG_SRPCAP |
+               GUSBCFG_HNPCAP);
+
        /* set the PLL on, remove the HNP/SRP and set the PHY */
        trdtim = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5;
-       dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) |
-               (trdtim << GUSBCFG_USBTRDTIM_SHIFT),
-               hsotg->regs + GUSBCFG);
+       usbcfg |= hsotg->phyif | GUSBCFG_TOUTCAL(7) |
+               (trdtim << GUSBCFG_USBTRDTIM_SHIFT);
+       dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 
        if (using_dma(hsotg))
                __orr32(hsotg->regs + GAHBCFG, GAHBCFG_DMA_EN);
index 17fd81447c9f72b452c83f8567e056e28bb1dd67..fa20f5a99d125aad27d28717683b5447a419fedf 100644 (file)
@@ -67,23 +67,9 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
 static int dwc3_core_soft_reset(struct dwc3 *dwc)
 {
        u32             reg;
+       int             retries = 1000;
        int             ret;
 
-       /* Before Resetting PHY, put Core in Reset */
-       reg = dwc3_readl(dwc->regs, DWC3_GCTL);
-       reg |= DWC3_GCTL_CORESOFTRESET;
-       dwc3_writel(dwc->regs, DWC3_GCTL, reg);
-
-       /* Assert USB3 PHY reset */
-       reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
-       reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
-       dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
-
-       /* Assert USB2 PHY reset */
-       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-       reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
-       dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-
        usb_phy_init(dwc->usb2_phy);
        usb_phy_init(dwc->usb3_phy);
        ret = phy_init(dwc->usb2_generic_phy);
@@ -95,26 +81,28 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
                phy_exit(dwc->usb2_generic_phy);
                return ret;
        }
-       mdelay(100);
 
-       /* Clear USB3 PHY reset */
-       reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
-       reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
-       dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
+       /*
+        * We're resetting only the device side because, if we're in host mode,
+        * XHCI driver will reset the host block. If dwc3 was configured for
+        * host-only mode, then we can return early.
+        */
+       if (dwc->dr_mode == USB_DR_MODE_HOST)
+               return 0;
 
-       /* Clear USB2 PHY reset */
-       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-       reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
-       dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+       reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+       reg |= DWC3_DCTL_CSFTRST;
+       dwc3_writel(dwc->regs, DWC3_DCTL, reg);
 
-       mdelay(100);
+       do {
+               reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+               if (!(reg & DWC3_DCTL_CSFTRST))
+                       return 0;
 
-       /* After PHYs are stable we can take Core out of reset state */
-       reg = dwc3_readl(dwc->regs, DWC3_GCTL);
-       reg &= ~DWC3_GCTL_CORESOFTRESET;
-       dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+               udelay(1);
+       } while (--retries);
 
-       return 0;
+       return -ETIMEDOUT;
 }
 
 /**
index 2be268d2423d9339679d38dc0a01982912424b96..72664700b8a25c7d9bcee89c16c68fa6b5792565 100644 (file)
@@ -39,8 +39,6 @@
 #define USBSS_IRQ_COREIRQ_EN   BIT(0)
 #define USBSS_IRQ_COREIRQ_CLR  BIT(0)
 
-static u64 kdwc3_dma_mask;
-
 struct dwc3_keystone {
        struct device                   *dev;
        struct clk                      *clk;
@@ -108,9 +106,6 @@ static int kdwc3_probe(struct platform_device *pdev)
        if (IS_ERR(kdwc->usbss))
                return PTR_ERR(kdwc->usbss);
 
-       kdwc3_dma_mask = dma_get_mask(dev);
-       dev->dma_mask = &kdwc3_dma_mask;
-
        kdwc->clk = devm_clk_get(kdwc->dev, "usb");
 
        error = clk_prepare_enable(kdwc->clk);
index 009d83048c8c9ab51ae01191e3cb2aa30207d928..adc1e8a624cb036d8fdb7ceee8d87d153a472eb4 100644 (file)
@@ -35,6 +35,7 @@
 #define PCI_DEVICE_ID_INTEL_SPTLP              0x9d30
 #define PCI_DEVICE_ID_INTEL_SPTH               0xa130
 #define PCI_DEVICE_ID_INTEL_BXT                        0x0aaa
+#define PCI_DEVICE_ID_INTEL_BXT_M              0x1aaa
 #define PCI_DEVICE_ID_INTEL_APL                        0x5aaa
 
 static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
@@ -213,6 +214,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTLP), },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTH), },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT), },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT_M), },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), },
        {  }    /* Terminating Entry */
index 3ac170f9d94d46156a172231c61be29c8067af09..d54a028cdfebaf69920f964bd7280427088b5b38 100644 (file)
@@ -568,7 +568,7 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
                dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
 
                if (!usb_endpoint_xfer_isoc(desc))
-                       return 0;
+                       goto out;
 
                /* Link TRB for ISOC. The HWO bit is never reset */
                trb_st_hw = &dep->trb_pool[0];
@@ -582,9 +582,10 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
                trb_link->ctrl |= DWC3_TRB_CTRL_HWO;
        }
 
+out:
        switch (usb_endpoint_type(desc)) {
        case USB_ENDPOINT_XFER_CONTROL:
-               strlcat(dep->name, "-control", sizeof(dep->name));
+               /* don't change name */
                break;
        case USB_ENDPOINT_XFER_ISOC:
                strlcat(dep->name, "-isoc", sizeof(dep->name));
@@ -2487,7 +2488,11 @@ static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc)
         * implemented.
         */
 
-       dwc->gadget_driver->resume(&dwc->gadget);
+       if (dwc->gadget_driver && dwc->gadget_driver->resume) {
+               spin_unlock(&dwc->lock);
+               dwc->gadget_driver->resume(&dwc->gadget);
+               spin_lock(&dwc->lock);
+       }
 }
 
 static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
index a5c62093c26c67192dc91ca9920817e88928ae02..de9ffd60fcfa84b59291e755edc4ca0fb9945f2f 100644 (file)
@@ -656,7 +656,8 @@ static int bos_desc(struct usb_composite_dev *cdev)
                ssp_cap->bmAttributes = cpu_to_le32(1);
 
                /* Min RX/TX Lane Count = 1 */
-               ssp_cap->wFunctionalitySupport = (1 << 8) | (1 << 12);
+               ssp_cap->wFunctionalitySupport =
+                       cpu_to_le16((1 << 8) | (1 << 12));
 
                /*
                 * bmSublinkSpeedAttr[0]:
@@ -666,7 +667,7 @@ static int bos_desc(struct usb_composite_dev *cdev)
                 *   LSM = 10 (10 Gbps)
                 */
                ssp_cap->bmSublinkSpeedAttr[0] =
-                       (3 << 4) | (1 << 14) | (0xa << 16);
+                       cpu_to_le32((3 << 4) | (1 << 14) | (0xa << 16));
                /*
                 * bmSublinkSpeedAttr[1] =
                 *   ST  = Symmetric, TX
@@ -675,7 +676,8 @@ static int bos_desc(struct usb_composite_dev *cdev)
                 *   LSM = 10 (10 Gbps)
                 */
                ssp_cap->bmSublinkSpeedAttr[1] =
-                       (3 << 4) | (1 << 14) | (0xa << 16) | (1 << 7);
+                       cpu_to_le32((3 << 4) | (1 << 14) |
+                                   (0xa << 16) | (1 << 7));
        }
 
        return le16_to_cpu(bos->wTotalLength);
index 84c0ee5ebd1ea6e97abbfd22f69cdfaaa2627d70..58fc199a18ecd735021796ed4c352f7f728d0e22 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/kfifo.h>
+#include <linux/spinlock.h>
 
 #include <sound/core.h>
 #include <sound/initval.h>
@@ -89,6 +90,7 @@ struct f_midi {
        unsigned int buflen, qlen;
        /* This fifo is used as a buffer ring for pre-allocated IN usb_requests */
        DECLARE_KFIFO_PTR(in_req_fifo, struct usb_request *);
+       spinlock_t transmit_lock;
        unsigned int in_last_port;
 
        struct gmidi_in_port    in_ports_array[/* in_ports */];
@@ -358,7 +360,9 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
        /* allocate a bunch of read buffers and queue them all at once. */
        for (i = 0; i < midi->qlen && err == 0; i++) {
                struct usb_request *req =
-                       midi_alloc_ep_req(midi->out_ep, midi->buflen);
+                       midi_alloc_ep_req(midi->out_ep,
+                               max_t(unsigned, midi->buflen,
+                                       bulk_out_desc.wMaxPacketSize));
                if (req == NULL)
                        return -ENOMEM;
 
@@ -597,17 +601,24 @@ static void f_midi_transmit(struct f_midi *midi)
 {
        struct usb_ep *ep = midi->in_ep;
        int ret;
+       unsigned long flags;
 
        /* We only care about USB requests if IN endpoint is enabled */
        if (!ep || !ep->enabled)
                goto drop_out;
 
+       spin_lock_irqsave(&midi->transmit_lock, flags);
+
        do {
                ret = f_midi_do_transmit(midi, ep);
-               if (ret < 0)
+               if (ret < 0) {
+                       spin_unlock_irqrestore(&midi->transmit_lock, flags);
                        goto drop_out;
+               }
        } while (ret);
 
+       spin_unlock_irqrestore(&midi->transmit_lock, flags);
+
        return;
 
 drop_out:
@@ -1201,6 +1212,8 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
        if (status)
                goto setup_fail;
 
+       spin_lock_init(&midi->transmit_lock);
+
        ++opts->refcnt;
        mutex_unlock(&opts->lock);
 
index 81d42cce885a4ae3a080c20f08ca20f4db241d16..18569de06b0495762950fcc724f69d05f10047af 100644 (file)
@@ -1045,20 +1045,6 @@ static void reset_all_endpoints(struct usba_udc *udc)
                list_del_init(&req->queue);
                request_complete(ep, req, -ECONNRESET);
        }
-
-       /* NOTE:  normally, the next call to the gadget driver is in
-        * charge of disabling endpoints... usually disconnect().
-        * The exception would be entering a high speed test mode.
-        *
-        * FIXME remove this code ... and retest thoroughly.
-        */
-       list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
-               if (ep->ep.desc) {
-                       spin_unlock(&udc->lock);
-                       usba_ep_disable(&ep->ep);
-                       spin_lock(&udc->lock);
-               }
-       }
 }
 
 static struct usba_ep *get_ep_by_addr(struct usba_udc *udc, u16 wIndex)
index 4151597e9d2881ac107012d3cdc895bbcba7dc4f..e4e70e11d0f6ca2c2cc2b7a423353fb652dabf6a 100644 (file)
@@ -371,12 +371,6 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
        INIT_WORK(&gadget->work, usb_gadget_state_work);
        gadget->dev.parent = parent;
 
-#ifdef CONFIG_HAS_DMA
-       dma_set_coherent_mask(&gadget->dev, parent->coherent_dma_mask);
-       gadget->dev.dma_parms = parent->dma_parms;
-       gadget->dev.dma_mask = parent->dma_mask;
-#endif
-
        if (release)
                gadget->dev.release = release;
        else
index 579587d972177338e97ca7ece02fabbc60fdcf55..3d7af85aecb9564d23946a98e7bb48dea81bf86f 100644 (file)
@@ -65,9 +65,7 @@ struct phy_8x16 {
        void __iomem                    *regs;
        struct clk                      *core_clk;
        struct clk                      *iface_clk;
-       struct regulator                *v3p3;
-       struct regulator                *v1p8;
-       struct regulator                *vdd;
+       struct regulator_bulk_data      regulator[3];
 
        struct reset_control            *phy_reset;
 
@@ -78,51 +76,6 @@ struct phy_8x16 {
        struct notifier_block           reboot_notify;
 };
 
-static int phy_8x16_regulators_enable(struct phy_8x16 *qphy)
-{
-       int ret;
-
-       ret = regulator_set_voltage(qphy->vdd, HSPHY_VDD_MIN, HSPHY_VDD_MAX);
-       if (ret)
-               return ret;
-
-       ret = regulator_enable(qphy->vdd);
-       if (ret)
-               return ret;
-
-       ret = regulator_set_voltage(qphy->v3p3, HSPHY_3P3_MIN, HSPHY_3P3_MAX);
-       if (ret)
-               goto off_vdd;
-
-       ret = regulator_enable(qphy->v3p3);
-       if (ret)
-               goto off_vdd;
-
-       ret = regulator_set_voltage(qphy->v1p8, HSPHY_1P8_MIN, HSPHY_1P8_MAX);
-       if (ret)
-               goto off_3p3;
-
-       ret = regulator_enable(qphy->v1p8);
-       if (ret)
-               goto off_3p3;
-
-       return 0;
-
-off_3p3:
-       regulator_disable(qphy->v3p3);
-off_vdd:
-       regulator_disable(qphy->vdd);
-
-       return ret;
-}
-
-static void phy_8x16_regulators_disable(struct phy_8x16 *qphy)
-{
-       regulator_disable(qphy->v1p8);
-       regulator_disable(qphy->v3p3);
-       regulator_disable(qphy->vdd);
-}
-
 static int phy_8x16_notify_connect(struct usb_phy *phy,
                                   enum usb_device_speed speed)
 {
@@ -261,7 +214,6 @@ static void phy_8x16_shutdown(struct usb_phy *phy)
 
 static int phy_8x16_read_devicetree(struct phy_8x16 *qphy)
 {
-       struct regulator_bulk_data regs[3];
        struct device *dev = qphy->phy.dev;
        int ret;
 
@@ -273,18 +225,15 @@ static int phy_8x16_read_devicetree(struct phy_8x16 *qphy)
        if (IS_ERR(qphy->iface_clk))
                return PTR_ERR(qphy->iface_clk);
 
-       regs[0].supply = "v3p3";
-       regs[1].supply = "v1p8";
-       regs[2].supply = "vddcx";
+       qphy->regulator[0].supply = "v3p3";
+       qphy->regulator[1].supply = "v1p8";
+       qphy->regulator[2].supply = "vddcx";
 
-       ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(regs), regs);
+       ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(qphy->regulator),
+                                     qphy->regulator);
        if (ret)
                return ret;
 
-       qphy->v3p3 = regs[0].consumer;
-       qphy->v1p8 = regs[1].consumer;
-       qphy->vdd  = regs[2].consumer;
-
        qphy->phy_reset = devm_reset_control_get(dev, "phy");
        if (IS_ERR(qphy->phy_reset))
                return PTR_ERR(qphy->phy_reset);
@@ -364,8 +313,9 @@ static int phy_8x16_probe(struct platform_device *pdev)
        if (ret < 0)
                goto off_core;
 
-       ret = phy_8x16_regulators_enable(qphy);
-       if (0 && ret)
+       ret = regulator_bulk_enable(ARRAY_SIZE(qphy->regulator),
+                                   qphy->regulator);
+       if (WARN_ON(ret))
                goto off_clks;
 
        qphy->vbus_notify.notifier_call = phy_8x16_vbus_notify;
@@ -387,7 +337,7 @@ off_extcon:
        extcon_unregister_notifier(qphy->vbus_edev, EXTCON_USB,
                                   &qphy->vbus_notify);
 off_power:
-       phy_8x16_regulators_disable(qphy);
+       regulator_bulk_disable(ARRAY_SIZE(qphy->regulator), qphy->regulator);
 off_clks:
        clk_disable_unprepare(qphy->iface_clk);
 off_core:
@@ -413,7 +363,7 @@ static int phy_8x16_remove(struct platform_device *pdev)
 
        clk_disable_unprepare(qphy->iface_clk);
        clk_disable_unprepare(qphy->core_clk);
-       phy_8x16_regulators_disable(qphy);
+       regulator_bulk_disable(ARRAY_SIZE(qphy->regulator), qphy->regulator);
        return 0;
 }
 
index b4de70ee16d3cfb56f4f3d5eb2047c5feb729a3a..000f9750149f5503b3da33aaf1f36bd9d550ab9d 100644 (file)
@@ -190,7 +190,8 @@ static int usbhsf_pkt_handler(struct usbhs_pipe *pipe, int type)
                goto __usbhs_pkt_handler_end;
        }
 
-       ret = func(pkt, &is_done);
+       if (likely(func))
+               ret = func(pkt, &is_done);
 
        if (is_done)
                __usbhsf_pkt_del(pkt);
@@ -889,6 +890,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done)
 
        pkt->trans = len;
 
+       usbhsf_tx_irq_ctrl(pipe, 0);
        INIT_WORK(&pkt->work, xfer_work);
        schedule_work(&pkt->work);
 
index 664b263e4b204cf6ac426d8a1bf179f3b5d68b8f..53d104b56ef17a9d47d29a9d1bcdfac9f8f4e7de 100644 (file)
@@ -158,10 +158,14 @@ static void usbhsg_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt)
        struct usbhs_pipe *pipe = pkt->pipe;
        struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe);
        struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt);
+       unsigned long flags;
 
        ureq->req.actual = pkt->actual;
 
-       usbhsg_queue_pop(uep, ureq, 0);
+       usbhs_lock(priv, flags);
+       if (uep)
+               __usbhsg_queue_pop(uep, ureq, 0);
+       usbhs_unlock(priv, flags);
 }
 
 static void usbhsg_queue_push(struct usbhsg_uep *uep,
index fbfe761c7fba7de2e8e8f4c850b140475c6378b6..dd47823bb014c4664fed94181b33fbcd5f8d6e85 100644 (file)
@@ -165,6 +165,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
        { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
        { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
+       { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */
        { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
        { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
        { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
index b283eb8b86d68f5b53c336ee70bc8a6cd609adce..bbeeb2bd55a83cebf4cfec9b4b8f2876edde1ca0 100644 (file)
@@ -447,6 +447,11 @@ static int cypress_generic_port_probe(struct usb_serial_port *port)
        struct usb_serial *serial = port->serial;
        struct cypress_private *priv;
 
+       if (!port->interrupt_out_urb || !port->interrupt_in_urb) {
+               dev_err(&port->dev, "required endpoint is missing\n");
+               return -ENODEV;
+       }
+
        priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
@@ -606,12 +611,6 @@ static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port)
                cypress_set_termios(tty, port, &priv->tmp_termios);
 
        /* setup the port and start reading from the device */
-       if (!port->interrupt_in_urb) {
-               dev_err(&port->dev, "%s - interrupt_in_urb is empty!\n",
-                       __func__);
-               return -1;
-       }
-
        usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
                usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
                port->interrupt_in_urb->transfer_buffer,
index 010a42a92688954d7b65a82472d28fad346c80c3..16e8e37b3b36d521749ec48d17b2becfc4ae4f51 100644 (file)
@@ -1251,8 +1251,27 @@ static int digi_port_init(struct usb_serial_port *port, unsigned port_num)
 
 static int digi_startup(struct usb_serial *serial)
 {
+       struct device *dev = &serial->interface->dev;
        struct digi_serial *serial_priv;
        int ret;
+       int i;
+
+       /* check whether the device has the expected number of endpoints */
+       if (serial->num_port_pointers < serial->type->num_ports + 1) {
+               dev_err(dev, "OOB endpoints missing\n");
+               return -ENODEV;
+       }
+
+       for (i = 0; i < serial->type->num_ports + 1 ; i++) {
+               if (!serial->port[i]->read_urb) {
+                       dev_err(dev, "bulk-in endpoint missing\n");
+                       return -ENODEV;
+               }
+               if (!serial->port[i]->write_urb) {
+                       dev_err(dev, "bulk-out endpoint missing\n");
+                       return -ENODEV;
+               }
+       }
 
        serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL);
        if (!serial_priv)
index 427ae43ee898fabcebafdac0d9042cff9fa053d5..3a814e802dee89644195b7e4c985b07ed8d218ad 100644 (file)
@@ -1004,6 +1004,10 @@ static const struct usb_device_id id_table_combined[] = {
        { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_DISPLAY_PID) },
        { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_LITE_PID) },
        { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_ANALOG_PID) },
+       /* ICP DAS I-756xU devices */
+       { USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) },
+       { USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) },
+       { USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) },
        { }                                     /* Terminating entry */
 };
 
index a84df2513994a57377cc41105f3078e36d2351a2..c5d6c1e73e8e0450d46dc7140637146404f262bb 100644 (file)
 #define NOVITUS_VID                    0x1a28
 #define NOVITUS_BONO_E_PID             0x6010
 
+/*
+ * ICPDAS I-756*U devices
+ */
+#define ICPDAS_VID                     0x1b5c
+#define ICPDAS_I7560U_PID              0x0103
+#define ICPDAS_I7561U_PID              0x0104
+#define ICPDAS_I7563U_PID              0x0105
+
 /*
  * RT Systems programming cables for various ham radios
  */
index 4446b8d70ac203cc8b763c38b6b93903cd1a0cb8..885655315de15a4b28db64da22f5d94bea7c8ea9 100644 (file)
@@ -376,14 +376,21 @@ static void mct_u232_msr_to_state(struct usb_serial_port *port,
 
 static int mct_u232_port_probe(struct usb_serial_port *port)
 {
+       struct usb_serial *serial = port->serial;
        struct mct_u232_private *priv;
 
+       /* check first to simplify error handling */
+       if (!serial->port[1] || !serial->port[1]->interrupt_in_urb) {
+               dev_err(&port->dev, "expected endpoint missing\n");
+               return -ENODEV;
+       }
+
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
        /* Use second interrupt-in endpoint for reading. */
-       priv->read_urb = port->serial->port[1]->interrupt_in_urb;
+       priv->read_urb = serial->port[1]->interrupt_in_urb;
        priv->read_urb->context = port;
 
        spin_lock_init(&priv->lock);
index 348e19834b83e12e7aafafa9d46374822fe43f7f..c6f497f1652659dc59e700181f35d75aab6ceae1 100644 (file)
@@ -1818,6 +1818,8 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) },
        { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) },
        { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) },
+       { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff),                     /* D-Link DWM-221 B1 */
+         .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
        { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) },                /* OLICARD300 - MT6225 */
index facaaf003f19931b2f15603568bb565f3de40607..e40da7759a0e6cd3a55bccdf90bb10284376ab11 100644 (file)
@@ -741,6 +741,17 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
        if (!(size > 0))
                return 0;
 
+       if (size > urb->transfer_buffer_length) {
+               /* should not happen, probably malicious packet */
+               if (ud->side == USBIP_STUB) {
+                       usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
+                       return 0;
+               } else {
+                       usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
+                       return -EPIPE;
+               }
+       }
+
        ret = usbip_recv(ud->tcp_socket, urb->transfer_buffer, size);
        if (ret != size) {
                dev_err(&urb->dev->dev, "recv xbuf, %d\n", ret);
index f6f28cc7eb45765af6db2f4fa2a41de6fcbecf05..e76bd91a29da3b4e09ddf35c806159e7a0ab61c0 100644 (file)
@@ -17,6 +17,7 @@
  *
  */
 
+#include <linux/delay.h>
 #define VIRTIO_PCI_NO_LEGACY
 #include "virtio_pci_common.h"
 
@@ -271,9 +272,13 @@ static void vp_reset(struct virtio_device *vdev)
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        /* 0 status means a reset. */
        vp_iowrite8(0, &vp_dev->common->device_status);
-       /* Flush out the status write, and flush in device writes,
-        * including MSI-X interrupts, if any. */
-       vp_ioread8(&vp_dev->common->device_status);
+       /* After writing 0 to device_status, the driver MUST wait for a read of
+        * device_status to return 0 before reinitializing the device.
+        * This will flush out the status write, and flush in device writes,
+        * including MSI-X interrupts, if any.
+        */
+       while (vp_ioread8(&vp_dev->common->device_status))
+               msleep(1);
        /* Flush pending VQ/configuration callbacks. */
        vp_synchronize_vectors(vdev);
 }
index 77592931ab4feba16615997f96d8beb9d385e858..ec7928a27aaad4c2241ef5b9dcd2048401861085 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/rbtree.h>
+#include <linux/vmalloc.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -5361,10 +5362,13 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
                goto out;
        }
 
-       tmp_buf = kmalloc(left_root->nodesize, GFP_KERNEL);
+       tmp_buf = kmalloc(left_root->nodesize, GFP_KERNEL | __GFP_NOWARN);
        if (!tmp_buf) {
-               ret = -ENOMEM;
-               goto out;
+               tmp_buf = vmalloc(left_root->nodesize);
+               if (!tmp_buf) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
        }
 
        left_path->search_commit_root = 1;
@@ -5565,7 +5569,7 @@ int btrfs_compare_trees(struct btrfs_root *left_root,
 out:
        btrfs_free_path(left_path);
        btrfs_free_path(right_path);
-       kfree(tmp_buf);
+       kvfree(tmp_buf);
        return ret;
 }
 
index a1d6652e0c4779ecf7e8c675fddcd06a560cdc32..26bcb487f95885295ad3e24d2a8063cbf6355351 100644 (file)
@@ -394,6 +394,8 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
        dev_replace->cursor_right = 0;
        dev_replace->is_valid = 1;
        dev_replace->item_needs_writeback = 1;
+       atomic64_set(&dev_replace->num_write_errors, 0);
+       atomic64_set(&dev_replace->num_uncorrectable_read_errors, 0);
        args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR;
        btrfs_dev_replace_unlock(dev_replace, 1);
 
index ce114ba9780a3b51ceecaee1fdcdaa4baa769f2c..84e060eb0de8c6aca562bcfb537f5236a71e9e66 100644 (file)
@@ -9386,15 +9386,23 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
        u64 dev_min = 1;
        u64 dev_nr = 0;
        u64 target;
+       int debug;
        int index;
        int full = 0;
        int ret = 0;
 
+       debug = btrfs_test_opt(root, ENOSPC_DEBUG);
+
        block_group = btrfs_lookup_block_group(root->fs_info, bytenr);
 
        /* odd, couldn't find the block group, leave it alone */
-       if (!block_group)
+       if (!block_group) {
+               if (debug)
+                       btrfs_warn(root->fs_info,
+                                  "can't find block group for bytenr %llu",
+                                  bytenr);
                return -1;
+       }
 
        min_free = btrfs_block_group_used(&block_group->item);
 
@@ -9448,8 +9456,13 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
                 * this is just a balance, so if we were marked as full
                 * we know there is no space for a new chunk
                 */
-               if (full)
+               if (full) {
+                       if (debug)
+                               btrfs_warn(root->fs_info,
+                                       "no space to alloc new chunk for block group %llu",
+                                       block_group->key.objectid);
                        goto out;
+               }
 
                index = get_block_group_index(block_group);
        }
@@ -9496,6 +9509,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
                        ret = -1;
                }
        }
+       if (debug && ret == -1)
+               btrfs_warn(root->fs_info,
+                       "no space to allocate a new chunk for block group %llu",
+                       block_group->key.objectid);
        mutex_unlock(&root->fs_info->chunk_mutex);
        btrfs_end_transaction(trans, root);
 out:
index cf31a60c6284812de197ef88553b0fed8b04309e..8d7b5a45c00523f4ca7ee5d58810b9d571ad4148 100644 (file)
@@ -1905,7 +1905,7 @@ static int start_ordered_ops(struct inode *inode, loff_t start, loff_t end)
  */
 int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
 {
-       struct dentry *dentry = file->f_path.dentry;
+       struct dentry *dentry = file_dentry(file);
        struct inode *inode = d_inode(dentry);
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_trans_handle *trans;
@@ -2682,9 +2682,12 @@ static long btrfs_fallocate(struct file *file, int mode,
                return ret;
 
        inode_lock(inode);
-       ret = inode_newsize_ok(inode, alloc_end);
-       if (ret)
-               goto out;
+
+       if (!(mode & FALLOC_FL_KEEP_SIZE) && offset + len > inode->i_size) {
+               ret = inode_newsize_ok(inode, offset + len);
+               if (ret)
+                       goto out;
+       }
 
        /*
         * TODO: Move these two operations after we have checked
index 94a0c8a3e8717b72f50bcf119d3e3b152203c973..5a23806ae418af8e3952b4cbf65df06aae384b57 100644 (file)
@@ -1654,7 +1654,7 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
 
                src_inode = file_inode(src.file);
                if (src_inode->i_sb != file_inode(file)->i_sb) {
-                       btrfs_info(BTRFS_I(src_inode)->root->fs_info,
+                       btrfs_info(BTRFS_I(file_inode(file))->root->fs_info,
                                   "Snapshot src from another FS");
                        ret = -EXDEV;
                } else if (!inode_owner_or_capable(src_inode)) {
index 5279fdae7142fbe3177a556a020ed1af3a7aa8f1..9e119552ed32cb4236eb3933fb9e7e9d104b77af 100644 (file)
@@ -1463,6 +1463,7 @@ struct btrfs_qgroup_extent_record
        u64 bytenr = record->bytenr;
 
        assert_spin_locked(&delayed_refs->lock);
+       trace_btrfs_qgroup_insert_dirty_extent(record);
 
        while (*p) {
                parent_node = *p;
@@ -1594,6 +1595,9 @@ static int qgroup_update_counters(struct btrfs_fs_info *fs_info,
                cur_old_count = btrfs_qgroup_get_old_refcnt(qg, seq);
                cur_new_count = btrfs_qgroup_get_new_refcnt(qg, seq);
 
+               trace_qgroup_update_counters(qg->qgroupid, cur_old_count,
+                                            cur_new_count);
+
                /* Rfer update part */
                if (cur_old_count == 0 && cur_new_count > 0) {
                        qg->rfer += num_bytes;
@@ -1683,6 +1687,9 @@ btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans,
                goto out_free;
        BUG_ON(!fs_info->quota_root);
 
+       trace_btrfs_qgroup_account_extent(bytenr, num_bytes, nr_old_roots,
+                                         nr_new_roots);
+
        qgroups = ulist_alloc(GFP_NOFS);
        if (!qgroups) {
                ret = -ENOMEM;
@@ -1752,6 +1759,8 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans,
                record = rb_entry(node, struct btrfs_qgroup_extent_record,
                                  node);
 
+               trace_btrfs_qgroup_account_extents(record);
+
                if (!ret) {
                        /*
                         * Use (u64)-1 as time_seq to do special search, which
@@ -1842,8 +1851,10 @@ out:
 }
 
 /*
- * copy the acounting information between qgroups. This is necessary when a
- * snapshot or a subvolume is created
+ * Copy the acounting information between qgroups. This is necessary
+ * when a snapshot or a subvolume is created. Throwing an error will
+ * cause a transaction abort so we take extra care here to only error
+ * when a readonly fs is a reasonable outcome.
  */
 int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
                         struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid,
@@ -1873,15 +1884,15 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
                       2 * inherit->num_excl_copies;
                for (i = 0; i < nums; ++i) {
                        srcgroup = find_qgroup_rb(fs_info, *i_qgroups);
-                       if (!srcgroup) {
-                               ret = -EINVAL;
-                               goto out;
-                       }
 
-                       if ((srcgroup->qgroupid >> 48) <= (objectid >> 48)) {
-                               ret = -EINVAL;
-                               goto out;
-                       }
+                       /*
+                        * Zero out invalid groups so we can ignore
+                        * them later.
+                        */
+                       if (!srcgroup ||
+                           ((srcgroup->qgroupid >> 48) <= (objectid >> 48)))
+                               *i_qgroups = 0ULL;
+
                        ++i_qgroups;
                }
        }
@@ -1916,17 +1927,19 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
         */
        if (inherit) {
                i_qgroups = (u64 *)(inherit + 1);
-               for (i = 0; i < inherit->num_qgroups; ++i) {
+               for (i = 0; i < inherit->num_qgroups; ++i, ++i_qgroups) {
+                       if (*i_qgroups == 0)
+                               continue;
                        ret = add_qgroup_relation_item(trans, quota_root,
                                                       objectid, *i_qgroups);
-                       if (ret)
+                       if (ret && ret != -EEXIST)
                                goto out;
                        ret = add_qgroup_relation_item(trans, quota_root,
                                                       *i_qgroups, objectid);
-                       if (ret)
+                       if (ret && ret != -EEXIST)
                                goto out;
-                       ++i_qgroups;
                }
+               ret = 0;
        }
 
 
@@ -1987,17 +2000,22 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
 
        i_qgroups = (u64 *)(inherit + 1);
        for (i = 0; i < inherit->num_qgroups; ++i) {
-               ret = add_relation_rb(quota_root->fs_info, objectid,
-                                     *i_qgroups);
-               if (ret)
-                       goto unlock;
+               if (*i_qgroups) {
+                       ret = add_relation_rb(quota_root->fs_info, objectid,
+                                             *i_qgroups);
+                       if (ret)
+                               goto unlock;
+               }
                ++i_qgroups;
        }
 
-       for (i = 0; i <  inherit->num_ref_copies; ++i) {
+       for (i = 0; i <  inherit->num_ref_copies; ++i, i_qgroups += 2) {
                struct btrfs_qgroup *src;
                struct btrfs_qgroup *dst;
 
+               if (!i_qgroups[0] || !i_qgroups[1])
+                       continue;
+
                src = find_qgroup_rb(fs_info, i_qgroups[0]);
                dst = find_qgroup_rb(fs_info, i_qgroups[1]);
 
@@ -2008,12 +2026,14 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
 
                dst->rfer = src->rfer - level_size;
                dst->rfer_cmpr = src->rfer_cmpr - level_size;
-               i_qgroups += 2;
        }
-       for (i = 0; i <  inherit->num_excl_copies; ++i) {
+       for (i = 0; i <  inherit->num_excl_copies; ++i, i_qgroups += 2) {
                struct btrfs_qgroup *src;
                struct btrfs_qgroup *dst;
 
+               if (!i_qgroups[0] || !i_qgroups[1])
+                       continue;
+
                src = find_qgroup_rb(fs_info, i_qgroups[0]);
                dst = find_qgroup_rb(fs_info, i_qgroups[1]);
 
@@ -2024,7 +2044,6 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
 
                dst->excl = src->excl + level_size;
                dst->excl_cmpr = src->excl_cmpr + level_size;
-               i_qgroups += 2;
        }
 
 unlock:
index 3c93968b539dd16a32e3d3c171c9c8b46d9ab4f7..08ef890deca69fdce7a35d26bcf5ae45d9f67d8b 100644 (file)
@@ -1850,6 +1850,7 @@ again:
                        eb = read_tree_block(dest, old_bytenr, old_ptr_gen);
                        if (IS_ERR(eb)) {
                                ret = PTR_ERR(eb);
+                               break;
                        } else if (!extent_buffer_uptodate(eb)) {
                                ret = -EIO;
                                free_extent_buffer(eb);
index 24d03c751149f56e484e32c3b1120dceb495b299..517d0ccb351e205a4f415c15c4735c3a76647b91 100644 (file)
@@ -4415,6 +4415,127 @@ static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans,
        return ret;
 }
 
+/*
+ * When we are logging a new inode X, check if it doesn't have a reference that
+ * matches the reference from some other inode Y created in a past transaction
+ * and that was renamed in the current transaction. If we don't do this, then at
+ * log replay time we can lose inode Y (and all its files if it's a directory):
+ *
+ * mkdir /mnt/x
+ * echo "hello world" > /mnt/x/foobar
+ * sync
+ * mv /mnt/x /mnt/y
+ * mkdir /mnt/x                 # or touch /mnt/x
+ * xfs_io -c fsync /mnt/x
+ * <power fail>
+ * mount fs, trigger log replay
+ *
+ * After the log replay procedure, we would lose the first directory and all its
+ * files (file foobar).
+ * For the case where inode Y is not a directory we simply end up losing it:
+ *
+ * echo "123" > /mnt/foo
+ * sync
+ * mv /mnt/foo /mnt/bar
+ * echo "abc" > /mnt/foo
+ * xfs_io -c fsync /mnt/foo
+ * <power fail>
+ *
+ * We also need this for cases where a snapshot entry is replaced by some other
+ * entry (file or directory) otherwise we end up with an unreplayable log due to
+ * attempts to delete the snapshot entry (entry of type BTRFS_ROOT_ITEM_KEY) as
+ * if it were a regular entry:
+ *
+ * mkdir /mnt/x
+ * btrfs subvolume snapshot /mnt /mnt/x/snap
+ * btrfs subvolume delete /mnt/x/snap
+ * rmdir /mnt/x
+ * mkdir /mnt/x
+ * fsync /mnt/x or fsync some new file inside it
+ * <power fail>
+ *
+ * The snapshot delete, rmdir of x, mkdir of a new x and the fsync all happen in
+ * the same transaction.
+ */
+static int btrfs_check_ref_name_override(struct extent_buffer *eb,
+                                        const int slot,
+                                        const struct btrfs_key *key,
+                                        struct inode *inode)
+{
+       int ret;
+       struct btrfs_path *search_path;
+       char *name = NULL;
+       u32 name_len = 0;
+       u32 item_size = btrfs_item_size_nr(eb, slot);
+       u32 cur_offset = 0;
+       unsigned long ptr = btrfs_item_ptr_offset(eb, slot);
+
+       search_path = btrfs_alloc_path();
+       if (!search_path)
+               return -ENOMEM;
+       search_path->search_commit_root = 1;
+       search_path->skip_locking = 1;
+
+       while (cur_offset < item_size) {
+               u64 parent;
+               u32 this_name_len;
+               u32 this_len;
+               unsigned long name_ptr;
+               struct btrfs_dir_item *di;
+
+               if (key->type == BTRFS_INODE_REF_KEY) {
+                       struct btrfs_inode_ref *iref;
+
+                       iref = (struct btrfs_inode_ref *)(ptr + cur_offset);
+                       parent = key->offset;
+                       this_name_len = btrfs_inode_ref_name_len(eb, iref);
+                       name_ptr = (unsigned long)(iref + 1);
+                       this_len = sizeof(*iref) + this_name_len;
+               } else {
+                       struct btrfs_inode_extref *extref;
+
+                       extref = (struct btrfs_inode_extref *)(ptr +
+                                                              cur_offset);
+                       parent = btrfs_inode_extref_parent(eb, extref);
+                       this_name_len = btrfs_inode_extref_name_len(eb, extref);
+                       name_ptr = (unsigned long)&extref->name;
+                       this_len = sizeof(*extref) + this_name_len;
+               }
+
+               if (this_name_len > name_len) {
+                       char *new_name;
+
+                       new_name = krealloc(name, this_name_len, GFP_NOFS);
+                       if (!new_name) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       name_len = this_name_len;
+                       name = new_name;
+               }
+
+               read_extent_buffer(eb, name, name_ptr, this_name_len);
+               di = btrfs_lookup_dir_item(NULL, BTRFS_I(inode)->root,
+                                          search_path, parent,
+                                          name, this_name_len, 0);
+               if (di && !IS_ERR(di)) {
+                       ret = 1;
+                       goto out;
+               } else if (IS_ERR(di)) {
+                       ret = PTR_ERR(di);
+                       goto out;
+               }
+               btrfs_release_path(search_path);
+
+               cur_offset += this_len;
+       }
+       ret = 0;
+out:
+       btrfs_free_path(search_path);
+       kfree(name);
+       return ret;
+}
+
 /* log a single inode in the tree log.
  * At least one parent directory for this inode must exist in the tree
  * or be logged already.
@@ -4602,6 +4723,22 @@ again:
                if (min_key.type == BTRFS_INODE_ITEM_KEY)
                        need_log_inode_item = false;
 
+               if ((min_key.type == BTRFS_INODE_REF_KEY ||
+                    min_key.type == BTRFS_INODE_EXTREF_KEY) &&
+                   BTRFS_I(inode)->generation == trans->transid) {
+                       ret = btrfs_check_ref_name_override(path->nodes[0],
+                                                           path->slots[0],
+                                                           &min_key, inode);
+                       if (ret < 0) {
+                               err = ret;
+                               goto out_unlock;
+                       } else if (ret > 0) {
+                               err = 1;
+                               btrfs_set_log_full_commit(root->fs_info, trans);
+                               goto out_unlock;
+                       }
+               }
+
                /* Skip xattrs, we log them later with btrfs_log_all_xattrs() */
                if (min_key.type == BTRFS_XATTR_ITEM_KEY) {
                        if (ins_nr == 0)
index 32ceae3e611297a9e2ff99c6be92c544026c870d..d5ecc6e477daa3ef63d630a42954ea57cb6d1e5b 100644 (file)
@@ -1667,7 +1667,8 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
                                DCACHE_OP_REVALIDATE    |
                                DCACHE_OP_WEAK_REVALIDATE       |
                                DCACHE_OP_DELETE        |
-                               DCACHE_OP_SELECT_INODE));
+                               DCACHE_OP_SELECT_INODE  |
+                               DCACHE_OP_REAL));
        dentry->d_op = op;
        if (!op)
                return;
@@ -1685,6 +1686,8 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
                dentry->d_flags |= DCACHE_OP_PRUNE;
        if (op->d_select_inode)
                dentry->d_flags |= DCACHE_OP_SELECT_INODE;
+       if (op->d_real)
+               dentry->d_flags |= DCACHE_OP_REAL;
 
 }
 EXPORT_SYMBOL(d_set_d_op);
index 2580ef3346caf6c40448271ea4e5313a17f3eed1..db9ae6e18154d851126d9b9ca4785af012893a2d 100644 (file)
@@ -91,7 +91,8 @@ void ext4_release_crypto_ctx(struct ext4_crypto_ctx *ctx)
  * Return: An allocated and initialized encryption context on success; error
  * value or NULL otherwise.
  */
-struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
+struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode,
+                                           gfp_t gfp_flags)
 {
        struct ext4_crypto_ctx *ctx = NULL;
        int res = 0;
@@ -118,7 +119,7 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
                list_del(&ctx->free_list);
        spin_unlock_irqrestore(&ext4_crypto_ctx_lock, flags);
        if (!ctx) {
-               ctx = kmem_cache_zalloc(ext4_crypto_ctx_cachep, GFP_NOFS);
+               ctx = kmem_cache_zalloc(ext4_crypto_ctx_cachep, gfp_flags);
                if (!ctx) {
                        res = -ENOMEM;
                        goto out;
@@ -255,7 +256,8 @@ static int ext4_page_crypto(struct inode *inode,
                            ext4_direction_t rw,
                            pgoff_t index,
                            struct page *src_page,
-                           struct page *dest_page)
+                           struct page *dest_page,
+                           gfp_t gfp_flags)
 
 {
        u8 xts_tweak[EXT4_XTS_TWEAK_SIZE];
@@ -266,7 +268,7 @@ static int ext4_page_crypto(struct inode *inode,
        struct crypto_skcipher *tfm = ci->ci_ctfm;
        int res = 0;
 
-       req = skcipher_request_alloc(tfm, GFP_NOFS);
+       req = skcipher_request_alloc(tfm, gfp_flags);
        if (!req) {
                printk_ratelimited(KERN_ERR
                                   "%s: crypto_request_alloc() failed\n",
@@ -307,9 +309,10 @@ static int ext4_page_crypto(struct inode *inode,
        return 0;
 }
 
-static struct page *alloc_bounce_page(struct ext4_crypto_ctx *ctx)
+static struct page *alloc_bounce_page(struct ext4_crypto_ctx *ctx,
+                                     gfp_t gfp_flags)
 {
-       ctx->w.bounce_page = mempool_alloc(ext4_bounce_page_pool, GFP_NOWAIT);
+       ctx->w.bounce_page = mempool_alloc(ext4_bounce_page_pool, gfp_flags);
        if (ctx->w.bounce_page == NULL)
                return ERR_PTR(-ENOMEM);
        ctx->flags |= EXT4_WRITE_PATH_FL;
@@ -332,7 +335,8 @@ static struct page *alloc_bounce_page(struct ext4_crypto_ctx *ctx)
  * error value or NULL.
  */
 struct page *ext4_encrypt(struct inode *inode,
-                         struct page *plaintext_page)
+                         struct page *plaintext_page,
+                         gfp_t gfp_flags)
 {
        struct ext4_crypto_ctx *ctx;
        struct page *ciphertext_page = NULL;
@@ -340,17 +344,17 @@ struct page *ext4_encrypt(struct inode *inode,
 
        BUG_ON(!PageLocked(plaintext_page));
 
-       ctx = ext4_get_crypto_ctx(inode);
+       ctx = ext4_get_crypto_ctx(inode, gfp_flags);
        if (IS_ERR(ctx))
                return (struct page *) ctx;
 
        /* The encryption operation will require a bounce page. */
-       ciphertext_page = alloc_bounce_page(ctx);
+       ciphertext_page = alloc_bounce_page(ctx, gfp_flags);
        if (IS_ERR(ciphertext_page))
                goto errout;
        ctx->w.control_page = plaintext_page;
        err = ext4_page_crypto(inode, EXT4_ENCRYPT, plaintext_page->index,
-                              plaintext_page, ciphertext_page);
+                              plaintext_page, ciphertext_page, gfp_flags);
        if (err) {
                ciphertext_page = ERR_PTR(err);
        errout:
@@ -378,8 +382,8 @@ int ext4_decrypt(struct page *page)
 {
        BUG_ON(!PageLocked(page));
 
-       return ext4_page_crypto(page->mapping->host,
-                               EXT4_DECRYPT, page->index, page, page);
+       return ext4_page_crypto(page->mapping->host, EXT4_DECRYPT,
+                               page->index, page, page, GFP_NOFS);
 }
 
 int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk,
@@ -398,11 +402,11 @@ int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk,
 
        BUG_ON(inode->i_sb->s_blocksize != PAGE_SIZE);
 
-       ctx = ext4_get_crypto_ctx(inode);
+       ctx = ext4_get_crypto_ctx(inode, GFP_NOFS);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
-       ciphertext_page = alloc_bounce_page(ctx);
+       ciphertext_page = alloc_bounce_page(ctx, GFP_NOWAIT);
        if (IS_ERR(ciphertext_page)) {
                err = PTR_ERR(ciphertext_page);
                goto errout;
@@ -410,11 +414,12 @@ int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk,
 
        while (len--) {
                err = ext4_page_crypto(inode, EXT4_ENCRYPT, lblk,
-                                      ZERO_PAGE(0), ciphertext_page);
+                                      ZERO_PAGE(0), ciphertext_page,
+                                      GFP_NOFS);
                if (err)
                        goto errout;
 
-               bio = bio_alloc(GFP_KERNEL, 1);
+               bio = bio_alloc(GFP_NOWAIT, 1);
                if (!bio) {
                        err = -ENOMEM;
                        goto errout;
@@ -473,13 +478,16 @@ uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size)
  */
 static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags)
 {
-       struct inode *dir = d_inode(dentry->d_parent);
-       struct ext4_crypt_info *ci = EXT4_I(dir)->i_crypt_info;
+       struct dentry *dir;
+       struct ext4_crypt_info *ci;
        int dir_has_key, cached_with_key;
 
-       if (!ext4_encrypted_inode(dir))
+       dir = dget_parent(dentry);
+       if (!ext4_encrypted_inode(d_inode(dir))) {
+               dput(dir);
                return 0;
-
+       }
+       ci = EXT4_I(d_inode(dir))->i_crypt_info;
        if (ci && ci->ci_keyring_key &&
            (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
                                          (1 << KEY_FLAG_REVOKED) |
@@ -489,6 +497,7 @@ static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags)
        /* this should eventually be an flag in d_flags */
        cached_with_key = dentry->d_fsdata != NULL;
        dir_has_key = (ci != NULL);
+       dput(dir);
 
        /*
         * If the dentry was cached without the key, and it is a
index 7ccba1aa142d9fc7cb625b506afc22a9636da1fe..349afebe21ee192a3cd6596438dd7502d7d16c80 100644 (file)
@@ -911,6 +911,29 @@ do {                                                                              \
 
 #include "extents_status.h"
 
+/*
+ * Lock subclasses for i_data_sem in the ext4_inode_info structure.
+ *
+ * These are needed to avoid lockdep false positives when we need to
+ * allocate blocks to the quota inode during ext4_map_blocks(), while
+ * holding i_data_sem for a normal (non-quota) inode.  Since we don't
+ * do quota tracking for the quota inode, this avoids deadlock (as
+ * well as infinite recursion, since it isn't turtles all the way
+ * down...)
+ *
+ *  I_DATA_SEM_NORMAL - Used for most inodes
+ *  I_DATA_SEM_OTHER  - Used by move_inode.c for the second normal inode
+ *                       where the second inode has larger inode number
+ *                       than the first
+ *  I_DATA_SEM_QUOTA  - Used for quota inodes only
+ */
+enum {
+       I_DATA_SEM_NORMAL = 0,
+       I_DATA_SEM_OTHER,
+       I_DATA_SEM_QUOTA,
+};
+
+
 /*
  * fourth extended file system inode data in memory
  */
@@ -2282,11 +2305,13 @@ extern struct kmem_cache *ext4_crypt_info_cachep;
 bool ext4_valid_contents_enc_mode(uint32_t mode);
 uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size);
 extern struct workqueue_struct *ext4_read_workqueue;
-struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode);
+struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode,
+                                           gfp_t gfp_flags);
 void ext4_release_crypto_ctx(struct ext4_crypto_ctx *ctx);
 void ext4_restore_control_page(struct page *data_page);
 struct page *ext4_encrypt(struct inode *inode,
-                         struct page *plaintext_page);
+                         struct page *plaintext_page,
+                         gfp_t gfp_flags);
 int ext4_decrypt(struct page *page);
 int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk,
                           ext4_fsblk_t pblk, ext4_lblk_t len);
index 0caece398eb86371398519a5bcfa332cadfa1baa..fa2208bae2e1211d8d761dd4e90e934a64575306 100644 (file)
@@ -329,7 +329,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
        struct super_block *sb = inode->i_sb;
        struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
        struct vfsmount *mnt = filp->f_path.mnt;
-       struct inode *dir = filp->f_path.dentry->d_parent->d_inode;
+       struct dentry *dir;
        struct path path;
        char buf[64], *cp;
        int ret;
@@ -373,14 +373,18 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
                if (ext4_encryption_info(inode) == NULL)
                        return -ENOKEY;
        }
-       if (ext4_encrypted_inode(dir) &&
-           !ext4_is_child_context_consistent_with_parent(dir, inode)) {
+
+       dir = dget_parent(file_dentry(filp));
+       if (ext4_encrypted_inode(d_inode(dir)) &&
+           !ext4_is_child_context_consistent_with_parent(d_inode(dir), inode)) {
                ext4_warning(inode->i_sb,
                             "Inconsistent encryption contexts: %lu/%lu\n",
-                            (unsigned long) dir->i_ino,
+                            (unsigned long) d_inode(dir)->i_ino,
                             (unsigned long) inode->i_ino);
+               dput(dir);
                return -EPERM;
        }
+       dput(dir);
        /*
         * Set up the jbd2_inode if we are opening the inode for
         * writing and the journal is present
index 4f7043ba44475326c830d04a1764a912b47b5504..981a1fc30eaa2c291c97958ce088e3ce96ab4353 100644 (file)
@@ -763,39 +763,47 @@ int ext4_get_block_unwritten(struct inode *inode, sector_t iblock,
 /* Maximum number of blocks we map for direct IO at once. */
 #define DIO_MAX_BLOCKS 4096
 
-static handle_t *start_dio_trans(struct inode *inode,
-                                struct buffer_head *bh_result)
+/*
+ * Get blocks function for the cases that need to start a transaction -
+ * generally difference cases of direct IO and DAX IO. It also handles retries
+ * in case of ENOSPC.
+ */
+static int ext4_get_block_trans(struct inode *inode, sector_t iblock,
+                               struct buffer_head *bh_result, int flags)
 {
        int dio_credits;
+       handle_t *handle;
+       int retries = 0;
+       int ret;
 
        /* Trim mapping request to maximum we can map at once for DIO */
        if (bh_result->b_size >> inode->i_blkbits > DIO_MAX_BLOCKS)
                bh_result->b_size = DIO_MAX_BLOCKS << inode->i_blkbits;
        dio_credits = ext4_chunk_trans_blocks(inode,
                                      bh_result->b_size >> inode->i_blkbits);
-       return ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS, dio_credits);
+retry:
+       handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS, dio_credits);
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       ret = _ext4_get_block(inode, iblock, bh_result, flags);
+       ext4_journal_stop(handle);
+
+       if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+               goto retry;
+       return ret;
 }
 
 /* Get block function for DIO reads and writes to inodes without extents */
 int ext4_dio_get_block(struct inode *inode, sector_t iblock,
                       struct buffer_head *bh, int create)
 {
-       handle_t *handle;
-       int ret;
-
        /* We don't expect handle for direct IO */
        WARN_ON_ONCE(ext4_journal_current_handle());
 
-       if (create) {
-               handle = start_dio_trans(inode, bh);
-               if (IS_ERR(handle))
-                       return PTR_ERR(handle);
-       }
-       ret = _ext4_get_block(inode, iblock, bh,
-                             create ? EXT4_GET_BLOCKS_CREATE : 0);
-       if (create)
-               ext4_journal_stop(handle);
-       return ret;
+       if (!create)
+               return _ext4_get_block(inode, iblock, bh, 0);
+       return ext4_get_block_trans(inode, iblock, bh, EXT4_GET_BLOCKS_CREATE);
 }
 
 /*
@@ -806,18 +814,13 @@ int ext4_dio_get_block(struct inode *inode, sector_t iblock,
 static int ext4_dio_get_block_unwritten_async(struct inode *inode,
                sector_t iblock, struct buffer_head *bh_result, int create)
 {
-       handle_t *handle;
        int ret;
 
        /* We don't expect handle for direct IO */
        WARN_ON_ONCE(ext4_journal_current_handle());
 
-       handle = start_dio_trans(inode, bh_result);
-       if (IS_ERR(handle))
-               return PTR_ERR(handle);
-       ret = _ext4_get_block(inode, iblock, bh_result,
-                             EXT4_GET_BLOCKS_IO_CREATE_EXT);
-       ext4_journal_stop(handle);
+       ret = ext4_get_block_trans(inode, iblock, bh_result,
+                                  EXT4_GET_BLOCKS_IO_CREATE_EXT);
 
        /*
         * When doing DIO using unwritten extents, we need io_end to convert
@@ -850,18 +853,13 @@ static int ext4_dio_get_block_unwritten_async(struct inode *inode,
 static int ext4_dio_get_block_unwritten_sync(struct inode *inode,
                sector_t iblock, struct buffer_head *bh_result, int create)
 {
-       handle_t *handle;
        int ret;
 
        /* We don't expect handle for direct IO */
        WARN_ON_ONCE(ext4_journal_current_handle());
 
-       handle = start_dio_trans(inode, bh_result);
-       if (IS_ERR(handle))
-               return PTR_ERR(handle);
-       ret = _ext4_get_block(inode, iblock, bh_result,
-                             EXT4_GET_BLOCKS_IO_CREATE_EXT);
-       ext4_journal_stop(handle);
+       ret = ext4_get_block_trans(inode, iblock, bh_result,
+                                  EXT4_GET_BLOCKS_IO_CREATE_EXT);
 
        /*
         * Mark inode as having pending DIO writes to unwritten extents.
index 675b67e5d5c20dfd543341d2b8f11cc14f68b922..325cef48b39a8d23788dc17ef056ccf79a7b58f6 100644 (file)
@@ -60,10 +60,10 @@ ext4_double_down_write_data_sem(struct inode *first, struct inode *second)
 {
        if (first < second) {
                down_write(&EXT4_I(first)->i_data_sem);
-               down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
+               down_write_nested(&EXT4_I(second)->i_data_sem, I_DATA_SEM_OTHER);
        } else {
                down_write(&EXT4_I(second)->i_data_sem);
-               down_write_nested(&EXT4_I(first)->i_data_sem, SINGLE_DEPTH_NESTING);
+               down_write_nested(&EXT4_I(first)->i_data_sem, I_DATA_SEM_OTHER);
 
        }
 }
@@ -484,6 +484,13 @@ mext_check_arguments(struct inode *orig_inode,
                return -EBUSY;
        }
 
+       if (IS_NOQUOTA(orig_inode) || IS_NOQUOTA(donor_inode)) {
+               ext4_debug("ext4 move extent: The argument files should "
+                       "not be quota files [ino:orig %lu, donor %lu]\n",
+                       orig_inode->i_ino, donor_inode->i_ino);
+               return -EBUSY;
+       }
+
        /* Ext4 move extent supports only extent based file */
        if (!(ext4_test_inode_flag(orig_inode, EXT4_INODE_EXTENTS))) {
                ext4_debug("ext4 move extent: orig file is not extents "
index 93ad0acf704c0be7114adf73e775722c9a0f9599..e4fc8ea45d7888fe3677f052e1af8dff39d443ab 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
+#include <linux/backing-dev.h>
 
 #include "ext4_jbd2.h"
 #include "xattr.h"
@@ -470,9 +471,20 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
 
        if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode) &&
            nr_to_submit) {
-               data_page = ext4_encrypt(inode, page);
+               gfp_t gfp_flags = GFP_NOFS;
+
+       retry_encrypt:
+               data_page = ext4_encrypt(inode, page, gfp_flags);
                if (IS_ERR(data_page)) {
                        ret = PTR_ERR(data_page);
+                       if (ret == -ENOMEM && wbc->sync_mode == WB_SYNC_ALL) {
+                               if (io->io_bio) {
+                                       ext4_io_submit(io);
+                                       congestion_wait(BLK_RW_ASYNC, HZ/50);
+                               }
+                               gfp_flags |= __GFP_NOFAIL;
+                               goto retry_encrypt;
+                       }
                        data_page = NULL;
                        goto out;
                }
index f24e7299e1c828834b89581c50fd7423710d2397..dc54a4b60eba0faf0b4f8afb290925b5b57e355a 100644 (file)
@@ -279,7 +279,7 @@ int ext4_mpage_readpages(struct address_space *mapping,
 
                        if (ext4_encrypted_inode(inode) &&
                            S_ISREG(inode->i_mode)) {
-                               ctx = ext4_get_crypto_ctx(inode);
+                               ctx = ext4_get_crypto_ctx(inode, GFP_NOFS);
                                if (IS_ERR(ctx))
                                        goto set_error_page;
                        }
index 0bb74aacb8c075f8b25a4e0323a58a9b11af4acd..304c712dbe12e8ba7d5c5abfaca30f7ef3f5e5a6 100644 (file)
@@ -1113,6 +1113,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
 static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
                             unsigned int flags);
 static int ext4_enable_quotas(struct super_block *sb);
+static int ext4_get_next_id(struct super_block *sb, struct kqid *qid);
 
 static struct dquot **ext4_get_dquots(struct inode *inode)
 {
@@ -1129,7 +1130,7 @@ static const struct dquot_operations ext4_quota_operations = {
        .alloc_dquot    = dquot_alloc,
        .destroy_dquot  = dquot_destroy,
        .get_projid     = ext4_get_projid,
-       .get_next_id    = dquot_get_next_id,
+       .get_next_id    = ext4_get_next_id,
 };
 
 static const struct quotactl_ops ext4_qctl_operations = {
@@ -1323,9 +1324,9 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
                return -1;
        }
        if (ext4_has_feature_quota(sb)) {
-               ext4_msg(sb, KERN_ERR, "Cannot set journaled quota options "
-                        "when QUOTA feature is enabled");
-               return -1;
+               ext4_msg(sb, KERN_INFO, "Journaled quota options "
+                        "ignored when QUOTA feature is enabled");
+               return 1;
        }
        qname = match_strdup(args);
        if (!qname) {
@@ -1688,10 +1689,10 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
                        return -1;
                }
                if (ext4_has_feature_quota(sb)) {
-                       ext4_msg(sb, KERN_ERR,
-                                "Cannot set journaled quota options "
+                       ext4_msg(sb, KERN_INFO,
+                                "Quota format mount options ignored "
                                 "when QUOTA feature is enabled");
-                       return -1;
+                       return 1;
                }
                sbi->s_jquota_fmt = m->mount_opt;
 #endif
@@ -1756,11 +1757,11 @@ static int parse_options(char *options, struct super_block *sb,
 #ifdef CONFIG_QUOTA
        if (ext4_has_feature_quota(sb) &&
            (test_opt(sb, USRQUOTA) || test_opt(sb, GRPQUOTA))) {
-               ext4_msg(sb, KERN_ERR, "Cannot set quota options when QUOTA "
-                        "feature is enabled");
-               return 0;
-       }
-       if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
+               ext4_msg(sb, KERN_INFO, "Quota feature enabled, usrquota and grpquota "
+                        "mount options ignored.");
+               clear_opt(sb, USRQUOTA);
+               clear_opt(sb, GRPQUOTA);
+       } else if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
                if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
                        clear_opt(sb, USRQUOTA);
 
@@ -5028,6 +5029,20 @@ static int ext4_quota_on_mount(struct super_block *sb, int type)
                                        EXT4_SB(sb)->s_jquota_fmt, type);
 }
 
+static void lockdep_set_quota_inode(struct inode *inode, int subclass)
+{
+       struct ext4_inode_info *ei = EXT4_I(inode);
+
+       /* The first argument of lockdep_set_subclass has to be
+        * *exactly* the same as the argument to init_rwsem() --- in
+        * this case, in init_once() --- or lockdep gets unhappy
+        * because the name of the lock is set using the
+        * stringification of the argument to init_rwsem().
+        */
+       (void) ei;      /* shut up clang warning if !CONFIG_LOCKDEP */
+       lockdep_set_subclass(&ei->i_data_sem, subclass);
+}
+
 /*
  * Standard function to be called on quota_on
  */
@@ -5067,8 +5082,12 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
                if (err)
                        return err;
        }
-
-       return dquot_quota_on(sb, type, format_id, path);
+       lockdep_set_quota_inode(path->dentry->d_inode, I_DATA_SEM_QUOTA);
+       err = dquot_quota_on(sb, type, format_id, path);
+       if (err)
+               lockdep_set_quota_inode(path->dentry->d_inode,
+                                            I_DATA_SEM_NORMAL);
+       return err;
 }
 
 static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
@@ -5095,8 +5114,11 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
 
        /* Don't account quota for quota files to avoid recursion */
        qf_inode->i_flags |= S_NOQUOTA;
+       lockdep_set_quota_inode(qf_inode, I_DATA_SEM_QUOTA);
        err = dquot_enable(qf_inode, type, format_id, flags);
        iput(qf_inode);
+       if (err)
+               lockdep_set_quota_inode(qf_inode, I_DATA_SEM_NORMAL);
 
        return err;
 }
@@ -5253,6 +5275,17 @@ out:
        return len;
 }
 
+static int ext4_get_next_id(struct super_block *sb, struct kqid *qid)
+{
+       const struct quota_format_ops   *ops;
+
+       if (!sb_has_quota_loaded(sb, qid->type))
+               return -ESRCH;
+       ops = sb_dqopt(sb)->ops[qid->type];
+       if (!ops || !ops->get_next_id)
+               return -ENOSYS;
+       return dquot_get_next_id(sb, qid);
+}
 #endif
 
 static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
index 0441e055c8e8b734a86a31b2f2afcac1d43a013b..e79bd32b9b798735f312ba87e3658e0796c44a2a 100644 (file)
@@ -230,6 +230,27 @@ ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh)
        return error;
 }
 
+static int
+__xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
+                        void *end, const char *function, unsigned int line)
+{
+       struct ext4_xattr_entry *entry = IFIRST(header);
+       int error = -EFSCORRUPTED;
+
+       if (((void *) header >= end) ||
+           (header->h_magic != le32_to_cpu(EXT4_XATTR_MAGIC)))
+               goto errout;
+       error = ext4_xattr_check_names(entry, end, entry);
+errout:
+       if (error)
+               __ext4_error_inode(inode, function, line, 0,
+                                  "corrupted in-inode xattr");
+       return error;
+}
+
+#define xattr_check_inode(inode, header, end) \
+       __xattr_check_inode((inode), (header), (end), __func__, __LINE__)
+
 static inline int
 ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size)
 {
@@ -341,7 +362,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
        header = IHDR(inode, raw_inode);
        entry = IFIRST(header);
        end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
-       error = ext4_xattr_check_names(entry, end, entry);
+       error = xattr_check_inode(inode, header, end);
        if (error)
                goto cleanup;
        error = ext4_xattr_find_entry(&entry, name_index, name,
@@ -477,7 +498,7 @@ ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size)
        raw_inode = ext4_raw_inode(&iloc);
        header = IHDR(inode, raw_inode);
        end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
-       error = ext4_xattr_check_names(IFIRST(header), end, IFIRST(header));
+       error = xattr_check_inode(inode, header, end);
        if (error)
                goto cleanup;
        error = ext4_xattr_list_entries(dentry, IFIRST(header),
@@ -1040,8 +1061,7 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
        is->s.here = is->s.first;
        is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
        if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) {
-               error = ext4_xattr_check_names(IFIRST(header), is->s.end,
-                                              IFIRST(header));
+               error = xattr_check_inode(inode, header, is->s.end);
                if (error)
                        return error;
                /* Find the named attribute. */
@@ -1356,6 +1376,10 @@ retry:
        last = entry;
        total_ino = sizeof(struct ext4_xattr_ibody_header);
 
+       error = xattr_check_inode(inode, header, end);
+       if (error)
+               goto cleanup;
+
        free = ext4_xattr_free_space(last, &min_offs, base, &total_ino);
        if (free >= new_extra_isize) {
                entry = IFIRST(header);
index adef506c57865b972c1ea69efa2f2e1e6b045fb0..33eb81738d03f1833250f8ad29224b4c14a37d4c 100644 (file)
@@ -377,7 +377,7 @@ int nfs_readdir_xdr_filler(struct page **pages, nfs_readdir_descriptor_t *desc,
  again:
        timestamp = jiffies;
        gencount = nfs_inc_attr_generation_counter();
-       error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, entry->cookie, pages,
+       error = NFS_PROTO(inode)->readdir(file_dentry(file), cred, entry->cookie, pages,
                                          NFS_SERVER(inode)->dtsize, desc->plus);
        if (error < 0) {
                /* We requested READDIRPLUS, but the server doesn't grok it */
@@ -560,7 +560,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
                count++;
 
                if (desc->plus != 0)
-                       nfs_prime_dcache(desc->file->f_path.dentry, entry);
+                       nfs_prime_dcache(file_dentry(desc->file), entry);
 
                status = nfs_readdir_add_to_array(entry, page);
                if (status != 0)
@@ -864,7 +864,7 @@ static bool nfs_dir_mapping_need_revalidate(struct inode *dir)
  */
 static int nfs_readdir(struct file *file, struct dir_context *ctx)
 {
-       struct dentry   *dentry = file->f_path.dentry;
+       struct dentry   *dentry = file_dentry(file);
        struct inode    *inode = d_inode(dentry);
        nfs_readdir_descriptor_t my_desc,
                        *desc = &my_desc;
index 33d18c4119057bb874604398337a990e94b5f9c4..738c84a42eb0217eae22b264eea27930f29f9118 100644 (file)
@@ -940,7 +940,7 @@ int nfs_open(struct inode *inode, struct file *filp)
 {
        struct nfs_open_context *ctx;
 
-       ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode);
+       ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
        nfs_file_set_open_context(filp, ctx);
index 22c35abbee9d6c88244b220054d2256c30d050ec..d0390516467c00f7f7506e3832b561338cd5bb79 100644 (file)
@@ -26,7 +26,7 @@ static int
 nfs4_file_open(struct inode *inode, struct file *filp)
 {
        struct nfs_open_context *ctx;
-       struct dentry *dentry = filp->f_path.dentry;
+       struct dentry *dentry = file_dentry(filp);
        struct dentry *parent = NULL;
        struct inode *dir;
        unsigned openflags = filp->f_flags;
@@ -57,7 +57,7 @@ nfs4_file_open(struct inode *inode, struct file *filp)
        parent = dget_parent(dentry);
        dir = d_inode(parent);
 
-       ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode);
+       ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode);
        err = PTR_ERR(ctx);
        if (IS_ERR(ctx))
                goto out;
index ba7dec40771e6d902e43551efcba9f528034faf1..324f0af40d7bd3c4c014c5e8de7a7b2b56e129b7 100644 (file)
@@ -153,7 +153,6 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx)
        struct dentry *dentry = file->f_path.dentry;
        struct orangefs_kernel_op_s *new_op = NULL;
        struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(dentry->d_inode);
-       int buffer_full = 0;
        struct orangefs_readdir_response_s readdir_response;
        void *dents_buf;
        int i = 0;
@@ -350,8 +349,7 @@ get_new_buffer_index:
        /*
         * Did we hit the end of the directory?
         */
-       if (readdir_response.token == ORANGEFS_READDIR_END &&
-           !buffer_full) {
+       if (readdir_response.token == ORANGEFS_READDIR_END) {
                gossip_debug(GOSSIP_DIR_DEBUG,
                "End of dir detected; setting ctx->pos to ORANGEFS_READDIR_END.\n");
                ctx->pos = ORANGEFS_READDIR_END;
index 0166faabf8f2980f0c4e1cecfbdbd439a5c54c15..85640e955cde93dfe40b70768aa78d6cb660ac41 100644 (file)
@@ -204,22 +204,8 @@ static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr)
        if (ret != 0)
                return ret;
 
-       /*
-        * Only change the c/mtime if we are changing the size or we are
-        * explicitly asked to change it.  This handles the semantic difference
-        * between truncate() and ftruncate() as implemented in the VFS.
-        *
-        * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a
-        * special case where we need to update the times despite not having
-        * these flags set.  For all other operations the VFS set these flags
-        * explicitly if it wants a timestamp update.
-        */
-       if (orig_size != i_size_read(inode) &&
-           !(iattr->ia_valid & (ATTR_CTIME | ATTR_MTIME))) {
-               iattr->ia_ctime = iattr->ia_mtime =
-                       current_fs_time(inode->i_sb);
+       if (orig_size != i_size_read(inode))
                iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME;
-       }
 
        return ret;
 }
index 19670b8b4053b49a6c40da82464ff75000bb84da..1714a737d5563ba3fd6dbbd468837b9e9f66de7e 100644 (file)
@@ -126,8 +126,7 @@ out:
 
 void orangefs_debugfs_cleanup(void)
 {
-       if (debug_dir)
-               debugfs_remove_recursive(debug_dir);
+       debugfs_remove_recursive(debug_dir);
 }
 
 /* open ORANGEFS_KMOD_DEBUG_HELP_FILE */
index 8277aba65e87447086c96b0f4b741752aa8a4875..2d129b5886eeb7a61d067502900dca75cf525d08 100644 (file)
@@ -315,9 +315,13 @@ int orangefs_inode_getattr(struct inode *inode, int new, int size)
                        inode->i_size = (loff_t)strlen(new_op->
                            downcall.resp.getattr.link_target);
                        orangefs_inode->blksize = (1 << inode->i_blkbits);
-                       strlcpy(orangefs_inode->link_target,
+                       ret = strscpy(orangefs_inode->link_target,
                            new_op->downcall.resp.getattr.link_target,
                            ORANGEFS_NAME_MAX);
+                       if (ret == -E2BIG) {
+                               ret = -EIO;
+                               goto out;
+                       }
                        inode->i_link = orangefs_inode->link_target;
                }
                break;
index 50578a28bd9ea64976cfeb59182b0ae21b038384..1efc6f8a5224cb0cd1ebb84b793cb68042e70442 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/spinlock_types.h>
 #include <linux/slab.h>
@@ -74,8 +75,8 @@ static inline void ORANGEFS_khandle_to(const struct orangefs_khandle *kh,
                                   void *p, int size)
 {
 
-       memset(p, 0, size);
        memcpy(p, kh->u, 16);
+       memset(p + 16, 0, size - 16);
 
 }
 
@@ -427,26 +428,28 @@ struct ORANGEFS_dev_map_desc {
 /* gossip.h *****************************************************************/
 
 #ifdef GOSSIP_DISABLE_DEBUG
-#define gossip_debug(mask, format, f...) do {} while (0)
+#define gossip_debug(mask, fmt, ...)                                   \
+do {                                                                   \
+       if (0)                                                          \
+               printk(KERN_DEBUG fmt, ##__VA_ARGS__);                  \
+} while (0)
 #else
 extern __u64 gossip_debug_mask;
 extern struct client_debug_mask client_debug_mask;
 
 /* try to avoid function call overhead by checking masks in macro */
-#define gossip_debug(mask, format, f...)                       \
-do {                                                           \
-       if (gossip_debug_mask & mask)                           \
-               printk(format, ##f);                            \
+#define gossip_debug(mask, fmt, ...)                                   \
+do {                                                                   \
+       if (gossip_debug_mask & (mask))                                 \
+               printk(KERN_DEBUG fmt, ##__VA_ARGS__);                  \
 } while (0)
 #endif /* GOSSIP_DISABLE_DEBUG */
 
 /* do file and line number printouts w/ the GNU preprocessor */
-#define gossip_ldebug(mask, format, f...)                              \
-               gossip_debug(mask, "%s: " format, __func__, ##f)
-
-#define gossip_err printk
-#define gossip_lerr(format, f...)                                      \
-               gossip_err("%s line %d: " format,                       \
-                          __FILE__,                                    \
-                          __LINE__,                                    \
-                          ##f)
+#define gossip_ldebug(mask, fmt, ...)                                  \
+       gossip_debug(mask, "%s: " fmt, __func__, ##__VA_ARGS__)
+
+#define gossip_err pr_err
+#define gossip_lerr(fmt, ...)                                          \
+       gossip_err("%s line %d: " fmt,                                  \
+                  __FILE__, __LINE__, ##__VA_ARGS__)
index ef5da7538cd5177f78c31542121ad36f2d24115e..63a6280d8c3a415df407ce96bd4833a99538fde0 100644 (file)
@@ -73,10 +73,6 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix,
                     "%s: prefix %s name %s, buffer_size %zd\n",
                     __func__, prefix, name, size);
 
-       if (name == NULL || (size > 0 && buffer == NULL)) {
-               gossip_err("orangefs_inode_getxattr: bogus NULL pointers\n");
-               return -EINVAL;
-       }
        if ((strlen(name) + strlen(prefix)) >= ORANGEFS_MAX_XATTR_NAMELEN) {
                gossip_err("Invalid key length (%d)\n",
                           (int)(strlen(name) + strlen(prefix)));
@@ -146,8 +142,8 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix,
                goto out_release_op;
        }
 
-       memset(buffer, 0, size);
        memcpy(buffer, new_op->downcall.resp.getxattr.val, length);
+       memset(buffer + length, 0, size - length);
        gossip_debug(GOSSIP_XATTR_DEBUG,
             "orangefs_inode_getxattr: inode %pU "
             "key %s key_sz %d, val_len %d\n",
@@ -239,8 +235,7 @@ int orangefs_inode_setxattr(struct inode *inode, const char *prefix,
                     "%s: prefix %s, name %s, buffer_size %zd\n",
                     __func__, prefix, name, size);
 
-       if (size < 0 ||
-           size >= ORANGEFS_MAX_XATTR_VALUELEN ||
+       if (size >= ORANGEFS_MAX_XATTR_VALUELEN ||
            flags < 0) {
                gossip_err("orangefs_inode_setxattr: bogus values of size(%d), flags(%d)\n",
                           (int)size,
@@ -248,12 +243,6 @@ int orangefs_inode_setxattr(struct inode *inode, const char *prefix,
                return -EINVAL;
        }
 
-       if (name == NULL ||
-           (size > 0 && value == NULL)) {
-               gossip_err("orangefs_inode_setxattr: bogus NULL pointers!\n");
-               return -EINVAL;
-       }
-
        internal_flag = convert_to_internal_xattr_flags(flags);
 
        if (prefix) {
@@ -353,10 +342,6 @@ ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size)
                gossip_err("%s: bogus NULL pointers\n", __func__);
                return -EINVAL;
        }
-       if (size < 0) {
-               gossip_err("Invalid size (%d)\n", (int)size);
-               return -EINVAL;
-       }
 
        down_read(&orangefs_inode->xattr_sem);
        new_op = op_alloc(ORANGEFS_VFS_OP_LISTXATTR);
index ef64984c9bbcec1f765ed0601dbfb9082bc44f42..5d972e6cd3fe97fcae5c782b59c72c0007668566 100644 (file)
@@ -295,6 +295,37 @@ static void ovl_dentry_release(struct dentry *dentry)
        }
 }
 
+static struct dentry *ovl_d_real(struct dentry *dentry, struct inode *inode)
+{
+       struct dentry *real;
+
+       if (d_is_dir(dentry)) {
+               if (!inode || inode == d_inode(dentry))
+                       return dentry;
+               goto bug;
+       }
+
+       real = ovl_dentry_upper(dentry);
+       if (real && (!inode || inode == d_inode(real)))
+               return real;
+
+       real = ovl_dentry_lower(dentry);
+       if (!real)
+               goto bug;
+
+       if (!inode || inode == d_inode(real))
+               return real;
+
+       /* Handle recursion */
+       if (real->d_flags & DCACHE_OP_REAL)
+               return real->d_op->d_real(real, inode);
+
+bug:
+       WARN(1, "ovl_d_real(%pd4, %s:%lu\n): real dentry not found\n", dentry,
+            inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0);
+       return dentry;
+}
+
 static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags)
 {
        struct ovl_entry *oe = dentry->d_fsdata;
@@ -339,11 +370,13 @@ static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags)
 static const struct dentry_operations ovl_dentry_operations = {
        .d_release = ovl_dentry_release,
        .d_select_inode = ovl_d_select_inode,
+       .d_real = ovl_d_real,
 };
 
 static const struct dentry_operations ovl_reval_dentry_operations = {
        .d_release = ovl_dentry_release,
        .d_select_inode = ovl_d_select_inode,
+       .d_real = ovl_d_real,
        .d_revalidate = ovl_dentry_revalidate,
        .d_weak_revalidate = ovl_dentry_weak_revalidate,
 };
index afae2316bd434e0067f5007f4467c3b0e3f54bb9..055a08ddac02a4a5b1149470f7bd74a03b173096 100644 (file)
@@ -92,7 +92,7 @@ struct ttm_placement {
  */
 struct ttm_bus_placement {
        void            *addr;
-       unsigned long   base;
+       phys_addr_t     base;
        unsigned long   size;
        unsigned long   offset;
        bool            is_iomem;
index 7cb043d8f4e8079cb1156e22b43e3a287a61294f..4bb4de8d95ea5869000db22baa662451c6acd1a0 100644 (file)
@@ -161,6 +161,7 @@ struct dentry_operations {
        struct vfsmount *(*d_automount)(struct path *);
        int (*d_manage)(struct dentry *, bool);
        struct inode *(*d_select_inode)(struct dentry *, unsigned);
+       struct dentry *(*d_real)(struct dentry *, struct inode *);
 } ____cacheline_aligned;
 
 /*
@@ -229,6 +230,7 @@ struct dentry_operations {
 #define DCACHE_OP_SELECT_INODE         0x02000000 /* Unioned entry: dcache op selects inode */
 
 #define DCACHE_ENCRYPTED_WITH_KEY      0x04000000 /* dir is encrypted with a valid key */
+#define DCACHE_OP_REAL                 0x08000000
 
 extern seqlock_t rename_lock;
 
@@ -555,4 +557,12 @@ static inline struct dentry *d_backing_dentry(struct dentry *upper)
        return upper;
 }
 
+static inline struct dentry *d_real(struct dentry *dentry)
+{
+       if (unlikely(dentry->d_flags & DCACHE_OP_REAL))
+               return dentry->d_op->d_real(dentry, NULL);
+       else
+               return dentry;
+}
+
 #endif /* __LINUX_DCACHE_H */
index 304991a80e23099c8f556e80b1ee9f0968fee474..70e61b58baaf662d15f4ca67f355b5dcf8d52438 100644 (file)
@@ -1241,6 +1241,16 @@ static inline struct inode *file_inode(const struct file *f)
        return f->f_inode;
 }
 
+static inline struct dentry *file_dentry(const struct file *file)
+{
+       struct dentry *dentry = file->f_path.dentry;
+
+       if (unlikely(dentry->d_flags & DCACHE_OP_REAL))
+               return dentry->d_op->d_real(dentry, file_inode(file));
+       else
+               return dentry;
+}
+
 static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl)
 {
        return locks_lock_inode_wait(file_inode(filp), fl);
index a5c539fa5d2bc03ba233f4d11de1b64d839990ab..ef7a6ecd85846c04fa5cc1aed2c6aa9373fedd91 100644 (file)
@@ -195,9 +195,7 @@ struct iommu_ops {
        /* Get the number of windows per domain */
        u32 (*domain_get_windows)(struct iommu_domain *domain);
 
-#ifdef CONFIG_OF_IOMMU
        int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
-#endif
 
        unsigned long pgsize_bitmap;
        void *priv;
index cb0d5d09c2e4f86243a7f3ac2acc0d61fe3da1a9..8395308a24456028f22621c5e00f757c4c817576 100644 (file)
@@ -2120,7 +2120,10 @@ struct napi_gro_cb {
        /* Used in foo-over-udp, set in udp[46]_gro_receive */
        u8      is_ipv6:1;
 
-       /* 7 bit hole */
+       /* Used in GRE, set in fou/gue_gro_receive */
+       u8      is_fou:1;
+
+       /* 6 bit hole */
 
        /* used to support CHECKSUM_COMPLETE for tunneling protocols */
        __wsum  csum;
index 2a19fe111c78836629bd914086b17a48f96c472c..03e322b30218244b9bde7fca5438cacc20923307 100644 (file)
@@ -135,6 +135,7 @@ void tcf_hashinfo_destroy(const struct tc_action_ops *ops,
 static inline void tc_action_net_exit(struct tc_action_net *tn)
 {
        tcf_hashinfo_destroy(tn->ops, tn->hinfo);
+       kfree(tn->hinfo);
 }
 
 int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
index 0c09da34b67a7e7ca4ab45fd1da8f132d8bedc63..e385eb3076a1a7241349f3f72d160aa39f2b0df7 100644 (file)
@@ -1001,6 +1001,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
  *     flag indicates that the PN was verified for replay protection.
  *     Note that this flag is also currently only supported when a frame
  *     is also decrypted (ie. @RX_FLAG_DECRYPTED must be set)
+ * @RX_FLAG_DUP_VALIDATED: The driver should set this flag if it did
+ *     de-duplication by itself.
  * @RX_FLAG_FAILED_FCS_CRC: Set this flag if the FCS check failed on
  *     the frame.
  * @RX_FLAG_FAILED_PLCP_CRC: Set this flag if the PCLP check failed on
index 65521cfdcadeee35d61f280165a387cc2164ab6d..03fb33efcae21d54192204629ff4ced2e36e7d4d 100644 (file)
@@ -386,11 +386,9 @@ static inline struct list_head *sctp_list_dequeue(struct list_head *list)
 {
        struct list_head *result = NULL;
 
-       if (list->next != list) {
+       if (!list_empty(list)) {
                result = list->next;
-               list->next = result->next;
-               list->next->prev = list;
-               INIT_LIST_HEAD(result);
+               list_del_init(result);
        }
        return result;
 }
index c067019ed12a7f4acb6c31391ede379527893098..74d79bde70750c717284b34ab77ac5f1dd7774b6 100644 (file)
@@ -516,6 +516,31 @@ static inline int scsi_device_tpgs(struct scsi_device *sdev)
        return sdev->inquiry ? (sdev->inquiry[5] >> 4) & 0x3 : 0;
 }
 
+/**
+ * scsi_device_supports_vpd - test if a device supports VPD pages
+ * @sdev: the &struct scsi_device to test
+ *
+ * If the 'try_vpd_pages' flag is set it takes precedence.
+ * Otherwise we will assume VPD pages are supported if the
+ * SCSI level is at least SPC-3 and 'skip_vpd_pages' is not set.
+ */
+static inline int scsi_device_supports_vpd(struct scsi_device *sdev)
+{
+       /* Attempt VPD inquiry if the device blacklist explicitly calls
+        * for it.
+        */
+       if (sdev->try_vpd_pages)
+               return 1;
+       /*
+        * Although VPD inquiries can go to SCSI-2 type devices,
+        * some USB ones crash on receiving them, and the pages
+        * we currently ask for are for SPC-3 and beyond
+        */
+       if (sdev->scsi_level > SCSI_SPC_2 && !sdev->skip_vpd_pages)
+               return 1;
+       return 0;
+}
+
 #define MODULE_ALIAS_SCSI_DEVICE(type) \
        MODULE_ALIAS("scsi:t-" __stringify(type) "*")
 #define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x"
index 677807f29a1cd18ae142f0f6e95999b0b6e1125e..e90e82ad68754cc8776935961275631507695ac4 100644 (file)
@@ -23,7 +23,7 @@ struct map_lookup;
 struct extent_buffer;
 struct btrfs_work;
 struct __btrfs_workqueue;
-struct btrfs_qgroup_operation;
+struct btrfs_qgroup_extent_record;
 
 #define show_ref_type(type)                                            \
        __print_symbolic(type,                                          \
@@ -1231,6 +1231,93 @@ DEFINE_EVENT(btrfs__qgroup_delayed_ref, btrfs_qgroup_free_delayed_ref,
 
        TP_ARGS(ref_root, reserved)
 );
+
+DECLARE_EVENT_CLASS(btrfs_qgroup_extent,
+       TP_PROTO(struct btrfs_qgroup_extent_record *rec),
+
+       TP_ARGS(rec),
+
+       TP_STRUCT__entry(
+               __field(        u64,  bytenr            )
+               __field(        u64,  num_bytes         )
+       ),
+
+       TP_fast_assign(
+               __entry->bytenr         = rec->bytenr,
+               __entry->num_bytes      = rec->num_bytes;
+       ),
+
+       TP_printk("bytenr = %llu, num_bytes = %llu",
+                 (unsigned long long)__entry->bytenr,
+                 (unsigned long long)__entry->num_bytes)
+);
+
+DEFINE_EVENT(btrfs_qgroup_extent, btrfs_qgroup_account_extents,
+
+       TP_PROTO(struct btrfs_qgroup_extent_record *rec),
+
+       TP_ARGS(rec)
+);
+
+DEFINE_EVENT(btrfs_qgroup_extent, btrfs_qgroup_insert_dirty_extent,
+
+       TP_PROTO(struct btrfs_qgroup_extent_record *rec),
+
+       TP_ARGS(rec)
+);
+
+TRACE_EVENT(btrfs_qgroup_account_extent,
+
+       TP_PROTO(u64 bytenr, u64 num_bytes, u64 nr_old_roots, u64 nr_new_roots),
+
+       TP_ARGS(bytenr, num_bytes, nr_old_roots, nr_new_roots),
+
+       TP_STRUCT__entry(
+               __field(        u64,  bytenr                    )
+               __field(        u64,  num_bytes                 )
+               __field(        u64,  nr_old_roots              )
+               __field(        u64,  nr_new_roots              )
+       ),
+
+       TP_fast_assign(
+               __entry->bytenr         = bytenr;
+               __entry->num_bytes      = num_bytes;
+               __entry->nr_old_roots   = nr_old_roots;
+               __entry->nr_new_roots   = nr_new_roots;
+       ),
+
+       TP_printk("bytenr = %llu, num_bytes = %llu, nr_old_roots = %llu, "
+                 "nr_new_roots = %llu",
+                 __entry->bytenr,
+                 __entry->num_bytes,
+                 __entry->nr_old_roots,
+                 __entry->nr_new_roots)
+);
+
+TRACE_EVENT(qgroup_update_counters,
+
+       TP_PROTO(u64 qgid, u64 cur_old_count, u64 cur_new_count),
+
+       TP_ARGS(qgid, cur_old_count, cur_new_count),
+
+       TP_STRUCT__entry(
+               __field(        u64,  qgid                      )
+               __field(        u64,  cur_old_count             )
+               __field(        u64,  cur_new_count             )
+       ),
+
+       TP_fast_assign(
+               __entry->qgid           = qgid;
+               __entry->cur_old_count  = cur_old_count;
+               __entry->cur_new_count  = cur_new_count;
+       ),
+
+       TP_printk("qgid = %llu, cur_old_count = %llu, cur_new_count = %llu",
+                 __entry->qgid,
+                 __entry->cur_old_count,
+                 __entry->cur_new_count)
+);
+
 #endif /* _TRACE_BTRFS_H */
 
 /* This part must be outside protection */
index 06d6c6228a7a75cfbbd0426d376a441b69597459..d5ce71607972e82f37e7a2aaa83d9fd59c87f919 100644 (file)
@@ -899,7 +899,7 @@ struct usb_ssp_cap_descriptor {
        __le32 bmAttributes;
 #define USB_SSP_SUBLINK_SPEED_ATTRIBS  (0x1f << 0) /* sublink speed entries */
 #define USB_SSP_SUBLINK_SPEED_IDS      (0xf << 5)  /* speed ID entries */
-       __u16  wFunctionalitySupport;
+       __le16  wFunctionalitySupport;
 #define USB_SSP_MIN_SUBLINK_SPEED_ATTRIBUTE_ID (0xf)
 #define USB_SSP_MIN_RX_LANE_COUNT              (0xf << 8)
 #define USB_SSP_MIN_TX_LANE_COUNT              (0xf << 12)
index c18264df9504c17ce11c84ef1a14f12a132cb35e..4cb65bbfa654852ab0d0c2e8b344731a86b2e132 100644 (file)
@@ -40,6 +40,8 @@
 #define VIRTIO_CONFIG_S_DRIVER_OK      4
 /* Driver has finished configuring features */
 #define VIRTIO_CONFIG_S_FEATURES_OK    8
+/* Device entered invalid state, driver must reset it */
+#define VIRTIO_CONFIG_S_NEEDS_RESET    0x40
 /* We've given up on this device. */
 #define VIRTIO_CONFIG_S_FAILED         0x80
 
index eeba75395f7d10b61fabf995d2b0157aec6d9ee5..ad66589f2ae6ec6bd1290fb112b2e8947bef6d24 100644 (file)
@@ -194,8 +194,9 @@ int ipu_cpmem_set_format_rgb(struct ipuv3_channel *ch,
 int ipu_cpmem_set_format_passthrough(struct ipuv3_channel *ch, int width);
 void ipu_cpmem_set_yuv_interleaved(struct ipuv3_channel *ch, u32 pixel_format);
 void ipu_cpmem_set_yuv_planar_full(struct ipuv3_channel *ch,
-                                  u32 pixel_format, int stride,
-                                  int u_offset, int v_offset);
+                                  unsigned int uv_stride,
+                                  unsigned int u_offset,
+                                  unsigned int v_offset);
 void ipu_cpmem_set_yuv_planar(struct ipuv3_channel *ch,
                              u32 pixel_format, int stride, int height);
 int ipu_cpmem_set_fmt(struct ipuv3_channel *ch, u32 drm_fourcc);
@@ -236,7 +237,7 @@ void ipu_dmfc_disable_channel(struct dmfc_channel *dmfc);
 int ipu_dmfc_alloc_bandwidth(struct dmfc_channel *dmfc,
                unsigned long bandwidth_mbs, int burstsize);
 void ipu_dmfc_free_bandwidth(struct dmfc_channel *dmfc);
-int ipu_dmfc_init_channel(struct dmfc_channel *dmfc, int width);
+void ipu_dmfc_config_wait4eot(struct dmfc_channel *dmfc, int width);
 struct dmfc_channel *ipu_dmfc_get(struct ipu_soc *ipu, int ipuv3_channel);
 void ipu_dmfc_put(struct dmfc_channel *dmfc);
 
index 27a7a26b1ece2e145296b144096191ffa6af504e..8f22fbedc3a699d07f05375d0a0832cc9da1d1b0 100644 (file)
@@ -2443,6 +2443,22 @@ static struct bpf_test tests[] = {
                { },
                { { 0, 4294967295U } },
        },
+       {
+               "ALU_ADD_X: 2 + 4294967294 = 0",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R0, 2),
+                       BPF_LD_IMM64(R1, 4294967294U),
+                       BPF_ALU32_REG(BPF_ADD, R0, R1),
+                       BPF_JMP_IMM(BPF_JEQ, R0, 0, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 1 } },
+       },
        {
                "ALU64_ADD_X: 1 + 2 = 3",
                .u.insns_int = {
@@ -2467,6 +2483,23 @@ static struct bpf_test tests[] = {
                { },
                { { 0, 4294967295U } },
        },
+       {
+               "ALU64_ADD_X: 2 + 4294967294 = 4294967296",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R0, 2),
+                       BPF_LD_IMM64(R1, 4294967294U),
+                       BPF_LD_IMM64(R2, 4294967296ULL),
+                       BPF_ALU64_REG(BPF_ADD, R0, R1),
+                       BPF_JMP_REG(BPF_JEQ, R0, R2, 2),
+                       BPF_MOV32_IMM(R0, 0),
+                       BPF_EXIT_INSN(),
+                       BPF_MOV32_IMM(R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 1 } },
+       },
        /* BPF_ALU | BPF_ADD | BPF_K */
        {
                "ALU_ADD_K: 1 + 2 = 3",
@@ -2501,6 +2534,21 @@ static struct bpf_test tests[] = {
                { },
                { { 0, 4294967295U } },
        },
+       {
+               "ALU_ADD_K: 4294967294 + 2 = 0",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R0, 4294967294U),
+                       BPF_ALU32_IMM(BPF_ADD, R0, 2),
+                       BPF_JMP_IMM(BPF_JEQ, R0, 0, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 1 } },
+       },
        {
                "ALU_ADD_K: 0 + (-1) = 0x00000000ffffffff",
                .u.insns_int = {
@@ -2517,6 +2565,70 @@ static struct bpf_test tests[] = {
                { },
                { { 0, 0x1 } },
        },
+       {
+               "ALU_ADD_K: 0 + 0xffff = 0xffff",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R2, 0x0),
+                       BPF_LD_IMM64(R3, 0xffff),
+                       BPF_ALU32_IMM(BPF_ADD, R2, 0xffff),
+                       BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
+                       BPF_MOV32_IMM(R0, 2),
+                       BPF_EXIT_INSN(),
+                       BPF_MOV32_IMM(R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0x1 } },
+       },
+       {
+               "ALU_ADD_K: 0 + 0x7fffffff = 0x7fffffff",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R2, 0x0),
+                       BPF_LD_IMM64(R3, 0x7fffffff),
+                       BPF_ALU32_IMM(BPF_ADD, R2, 0x7fffffff),
+                       BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
+                       BPF_MOV32_IMM(R0, 2),
+                       BPF_EXIT_INSN(),
+                       BPF_MOV32_IMM(R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0x1 } },
+       },
+       {
+               "ALU_ADD_K: 0 + 0x80000000 = 0x80000000",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R2, 0x0),
+                       BPF_LD_IMM64(R3, 0x80000000),
+                       BPF_ALU32_IMM(BPF_ADD, R2, 0x80000000),
+                       BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
+                       BPF_MOV32_IMM(R0, 2),
+                       BPF_EXIT_INSN(),
+                       BPF_MOV32_IMM(R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0x1 } },
+       },
+       {
+               "ALU_ADD_K: 0 + 0x80008000 = 0x80008000",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R2, 0x0),
+                       BPF_LD_IMM64(R3, 0x80008000),
+                       BPF_ALU32_IMM(BPF_ADD, R2, 0x80008000),
+                       BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
+                       BPF_MOV32_IMM(R0, 2),
+                       BPF_EXIT_INSN(),
+                       BPF_MOV32_IMM(R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0x1 } },
+       },
        {
                "ALU64_ADD_K: 1 + 2 = 3",
                .u.insns_int = {
@@ -2550,6 +2662,22 @@ static struct bpf_test tests[] = {
                { },
                { { 0, 2147483647 } },
        },
+       {
+               "ALU64_ADD_K: 4294967294 + 2 = 4294967296",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R0, 4294967294U),
+                       BPF_LD_IMM64(R1, 4294967296ULL),
+                       BPF_ALU64_IMM(BPF_ADD, R0, 2),
+                       BPF_JMP_REG(BPF_JEQ, R0, R1, 2),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_EXIT_INSN(),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 1 } },
+       },
        {
                "ALU64_ADD_K: 2147483646 + -2147483647 = -1",
                .u.insns_int = {
@@ -2593,6 +2721,70 @@ static struct bpf_test tests[] = {
                { },
                { { 0, 0x1 } },
        },
+       {
+               "ALU64_ADD_K: 0 + 0xffff = 0xffff",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R2, 0x0),
+                       BPF_LD_IMM64(R3, 0xffff),
+                       BPF_ALU64_IMM(BPF_ADD, R2, 0xffff),
+                       BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
+                       BPF_MOV32_IMM(R0, 2),
+                       BPF_EXIT_INSN(),
+                       BPF_MOV32_IMM(R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0x1 } },
+       },
+       {
+               "ALU64_ADD_K: 0 + 0x7fffffff = 0x7fffffff",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R2, 0x0),
+                       BPF_LD_IMM64(R3, 0x7fffffff),
+                       BPF_ALU64_IMM(BPF_ADD, R2, 0x7fffffff),
+                       BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
+                       BPF_MOV32_IMM(R0, 2),
+                       BPF_EXIT_INSN(),
+                       BPF_MOV32_IMM(R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0x1 } },
+       },
+       {
+               "ALU64_ADD_K: 0 + 0x80000000 = 0xffffffff80000000",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R2, 0x0),
+                       BPF_LD_IMM64(R3, 0xffffffff80000000LL),
+                       BPF_ALU64_IMM(BPF_ADD, R2, 0x80000000),
+                       BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
+                       BPF_MOV32_IMM(R0, 2),
+                       BPF_EXIT_INSN(),
+                       BPF_MOV32_IMM(R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0x1 } },
+       },
+       {
+               "ALU_ADD_K: 0 + 0x80008000 = 0xffffffff80008000",
+               .u.insns_int = {
+                       BPF_LD_IMM64(R2, 0x0),
+                       BPF_LD_IMM64(R3, 0xffffffff80008000LL),
+                       BPF_ALU64_IMM(BPF_ADD, R2, 0x80008000),
+                       BPF_JMP_REG(BPF_JEQ, R2, R3, 2),
+                       BPF_MOV32_IMM(R0, 2),
+                       BPF_EXIT_INSN(),
+                       BPF_MOV32_IMM(R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 0x1 } },
+       },
        /* BPF_ALU | BPF_SUB | BPF_X */
        {
                "ALU_SUB_X: 3 - 1 = 2",
@@ -4222,6 +4414,20 @@ static struct bpf_test tests[] = {
                { },
                { { 0, 1 } },
        },
+       {
+               "JMP_JGT_K: Unsigned jump: if (-1 > 1) return 1",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_LD_IMM64(R1, -1),
+                       BPF_JMP_IMM(BPF_JGT, R1, 1, 1),
+                       BPF_EXIT_INSN(),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 1 } },
+       },
        /* BPF_JMP | BPF_JGE | BPF_K */
        {
                "JMP_JGE_K: if (3 >= 2) return 1",
@@ -4303,7 +4509,7 @@ static struct bpf_test tests[] = {
                .u.insns_int = {
                        BPF_ALU32_IMM(BPF_MOV, R0, 0),
                        BPF_LD_IMM64(R1, 3),
-                       BPF_JMP_IMM(BPF_JNE, R1, 2, 1),
+                       BPF_JMP_IMM(BPF_JSET, R1, 2, 1),
                        BPF_EXIT_INSN(),
                        BPF_ALU32_IMM(BPF_MOV, R0, 1),
                        BPF_EXIT_INSN(),
@@ -4317,7 +4523,7 @@ static struct bpf_test tests[] = {
                .u.insns_int = {
                        BPF_ALU32_IMM(BPF_MOV, R0, 0),
                        BPF_LD_IMM64(R1, 3),
-                       BPF_JMP_IMM(BPF_JNE, R1, 0xffffffff, 1),
+                       BPF_JMP_IMM(BPF_JSET, R1, 0xffffffff, 1),
                        BPF_EXIT_INSN(),
                        BPF_ALU32_IMM(BPF_MOV, R0, 1),
                        BPF_EXIT_INSN(),
@@ -4404,6 +4610,21 @@ static struct bpf_test tests[] = {
                { },
                { { 0, 1 } },
        },
+       {
+               "JMP_JGT_X: Unsigned jump: if (-1 > 1) return 1",
+               .u.insns_int = {
+                       BPF_ALU32_IMM(BPF_MOV, R0, 0),
+                       BPF_LD_IMM64(R1, -1),
+                       BPF_LD_IMM64(R2, 1),
+                       BPF_JMP_REG(BPF_JGT, R1, R2, 1),
+                       BPF_EXIT_INSN(),
+                       BPF_ALU32_IMM(BPF_MOV, R0, 1),
+                       BPF_EXIT_INSN(),
+               },
+               INTERNAL,
+               { },
+               { { 0, 1 } },
+       },
        /* BPF_JMP | BPF_JGE | BPF_X */
        {
                "JMP_JGE_X: if (3 >= 2) return 1",
@@ -4474,7 +4695,7 @@ static struct bpf_test tests[] = {
                        BPF_ALU32_IMM(BPF_MOV, R0, 0),
                        BPF_LD_IMM64(R1, 3),
                        BPF_LD_IMM64(R2, 2),
-                       BPF_JMP_REG(BPF_JNE, R1, R2, 1),
+                       BPF_JMP_REG(BPF_JSET, R1, R2, 1),
                        BPF_EXIT_INSN(),
                        BPF_ALU32_IMM(BPF_MOV, R0, 1),
                        BPF_EXIT_INSN(),
@@ -4489,7 +4710,7 @@ static struct bpf_test tests[] = {
                        BPF_ALU32_IMM(BPF_MOV, R0, 0),
                        BPF_LD_IMM64(R1, 3),
                        BPF_LD_IMM64(R2, 0xffffffff),
-                       BPF_JMP_REG(BPF_JNE, R1, R2, 1),
+                       BPF_JMP_REG(BPF_JSET, R1, R2, 1),
                        BPF_EXIT_INSN(),
                        BPF_ALU32_IMM(BPF_MOV, R0, 1),
                        BPF_EXIT_INSN(),
index b9bcbe77d913b15dcbe7cdc9ee6cb7f74ee55aee..77a71cd68535fc02ae939168934fa4fb4f419644 100644 (file)
@@ -4439,6 +4439,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
                NAPI_GRO_CB(skb)->flush = 0;
                NAPI_GRO_CB(skb)->free = 0;
                NAPI_GRO_CB(skb)->encap_mark = 0;
+               NAPI_GRO_CB(skb)->is_fou = 0;
                NAPI_GRO_CB(skb)->gro_remcsum_start = 0;
 
                /* Setup for GRO checksum validation */
index a57bd17805b494be077f1c9d0d358ae7373ee18f..94acfc89ad976da245bed577511bd7a1c079f6f5 100644 (file)
@@ -603,6 +603,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
        const struct net_device_ops *ops;
        int err;
 
+       np->dev = ndev;
        strlcpy(np->dev_name, ndev->name, IFNAMSIZ);
        INIT_WORK(&np->cleanup_work, netpoll_async_cleanup);
 
@@ -669,7 +670,6 @@ int netpoll_setup(struct netpoll *np)
                goto unlock;
        }
        dev_hold(ndev);
-       np->dev = ndev;
 
        if (netdev_master_upper_dev_get(ndev)) {
                np_err(np, "%s is a slave device, aborting\n", np->dev_name);
@@ -770,7 +770,6 @@ int netpoll_setup(struct netpoll *np)
        return 0;
 
 put:
-       np->dev = NULL;
        dev_put(ndev);
 unlock:
        rtnl_unlock();
index b67b9aedb230f9480d7ae91d8a8a79f5693187a5..7e73c26b6bb468c071339ba60127ce20d59073ee 100644 (file)
@@ -221,7 +221,8 @@ static const char *const af_family_key_strings[AF_MAX+1] = {
   "sk_lock-AF_TIPC"  , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV"        ,
   "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN"     , "sk_lock-AF_PHONET"   ,
   "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG"      ,
-  "sk_lock-AF_NFC"   , "sk_lock-AF_VSOCK"    , "sk_lock-AF_MAX"
+  "sk_lock-AF_NFC"   , "sk_lock-AF_VSOCK"    , "sk_lock-AF_KCM"      ,
+  "sk_lock-AF_MAX"
 };
 static const char *const af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_UNSPEC", "slock-AF_UNIX"     , "slock-AF_INET"     ,
@@ -237,7 +238,8 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_TIPC"  , "slock-AF_BLUETOOTH", "slock-AF_IUCV"     ,
   "slock-AF_RXRPC" , "slock-AF_ISDN"     , "slock-AF_PHONET"   ,
   "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG"      ,
-  "slock-AF_NFC"   , "slock-AF_VSOCK"    ,"slock-AF_MAX"
+  "slock-AF_NFC"   , "slock-AF_VSOCK"    ,"slock-AF_KCM"       ,
+  "slock-AF_MAX"
 };
 static const char *const af_family_clock_key_strings[AF_MAX+1] = {
   "clock-AF_UNSPEC", "clock-AF_UNIX"     , "clock-AF_INET"     ,
@@ -253,7 +255,8 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = {
   "clock-AF_TIPC"  , "clock-AF_BLUETOOTH", "clock-AF_IUCV"     ,
   "clock-AF_RXRPC" , "clock-AF_ISDN"     , "clock-AF_PHONET"   ,
   "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG"      ,
-  "clock-AF_NFC"   , "clock-AF_VSOCK"    , "clock-AF_MAX"
+  "clock-AF_NFC"   , "clock-AF_VSOCK"    , "clock-AF_KCM"      ,
+  "clock-AF_MAX"
 };
 
 /*
index 5a94aea280d35cebd94d35f4be756a3cea2163a4..a39068b4a4d99383096c3c970c4c15f1ee464617 100644 (file)
@@ -203,6 +203,9 @@ static struct sk_buff **fou_gro_receive(struct sk_buff **head,
         */
        NAPI_GRO_CB(skb)->encap_mark = 0;
 
+       /* Flag this frame as already having an outer encap header */
+       NAPI_GRO_CB(skb)->is_fou = 1;
+
        rcu_read_lock();
        offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
        ops = rcu_dereference(offloads[proto]);
@@ -368,6 +371,9 @@ static struct sk_buff **gue_gro_receive(struct sk_buff **head,
         */
        NAPI_GRO_CB(skb)->encap_mark = 0;
 
+       /* Flag this frame as already having an outer encap header */
+       NAPI_GRO_CB(skb)->is_fou = 1;
+
        rcu_read_lock();
        offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
        ops = rcu_dereference(offloads[guehdr->proto_ctype]);
index c47539d04b88a78457e1f6badc5770cc931b469c..6a5bd43178666eed954c4ee6f22837059fad470d 100644 (file)
@@ -150,6 +150,14 @@ static struct sk_buff **gre_gro_receive(struct sk_buff **head,
        if ((greh->flags & ~(GRE_KEY|GRE_CSUM)) != 0)
                goto out;
 
+       /* We can only support GRE_CSUM if we can track the location of
+        * the GRE header.  In the case of FOU/GUE we cannot because the
+        * outer UDP header displaces the GRE header leaving us in a state
+        * of limbo.
+        */
+       if ((greh->flags & GRE_CSUM) && NAPI_GRO_CB(skb)->is_fou)
+               goto out;
+
        type = greh->protocol;
 
        rcu_read_lock();
index 31936d387cfd58b75218d340f683880e486c7351..af5d1f38217f4e4dcb977b6410d0d9a6a6c1e87c 100644 (file)
@@ -862,9 +862,16 @@ static void __gre_tunnel_init(struct net_device *dev)
        dev->hw_features        |= GRE_FEATURES;
 
        if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
-               /* TCP offload with GRE SEQ is not supported. */
-               dev->features    |= NETIF_F_GSO_SOFTWARE;
-               dev->hw_features |= NETIF_F_GSO_SOFTWARE;
+               /* TCP offload with GRE SEQ is not supported, nor
+                * can we support 2 levels of outer headers requiring
+                * an update.
+                */
+               if (!(tunnel->parms.o_flags & TUNNEL_CSUM) ||
+                   (tunnel->encap.type == TUNNEL_ENCAP_NONE)) {
+                       dev->features    |= NETIF_F_GSO_SOFTWARE;
+                       dev->hw_features |= NETIF_F_GSO_SOFTWARE;
+               }
+
                /* Can use a lockless transmit, unless we generate
                 * output sequences
                 */
index 9428345d3a078786f6662e9384e75c97b9c3e245..bc972e7152c738d72ac04e3733608a1a4b5ace5f 100644 (file)
@@ -1090,8 +1090,8 @@ static inline int ip6_ufo_append_data(struct sock *sk,
                        int getfrag(void *from, char *to, int offset, int len,
                        int odd, struct sk_buff *skb),
                        void *from, int length, int hh_len, int fragheaderlen,
-                       int transhdrlen, int mtu, unsigned int flags,
-                       const struct flowi6 *fl6)
+                       int exthdrlen, int transhdrlen, int mtu,
+                       unsigned int flags, const struct flowi6 *fl6)
 
 {
        struct sk_buff *skb;
@@ -1116,7 +1116,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
                skb_put(skb, fragheaderlen + transhdrlen);
 
                /* initialize network header pointer */
-               skb_reset_network_header(skb);
+               skb_set_network_header(skb, exthdrlen);
 
                /* initialize protocol header pointer */
                skb->transport_header = skb->network_header + fragheaderlen;
@@ -1358,7 +1358,7 @@ emsgsize:
            (rt->dst.dev->features & NETIF_F_UFO) &&
            (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) {
                err = ip6_ufo_append_data(sk, queue, getfrag, from, length,
-                                         hh_len, fragheaderlen,
+                                         hh_len, fragheaderlen, exthdrlen,
                                          transhdrlen, mtu, flags, fl6);
                if (err)
                        goto error;
index eb2ac4bb09ce0fb0f9afb3fcc142aad80270a6cb..1f20345cbc970e88dd3b1ace2cc111cb56e5f73b 100644 (file)
@@ -252,12 +252,12 @@ static int ip6_tnl_create2(struct net_device *dev)
 
        t = netdev_priv(dev);
 
+       dev->rtnl_link_ops = &ip6_link_ops;
        err = register_netdevice(dev);
        if (err < 0)
                goto out;
 
        strcpy(t->parms.name, dev->name);
-       dev->rtnl_link_ops = &ip6_link_ops;
 
        dev_hold(dev);
        ip6_tnl_link(ip6n, t);
index ec22078b0914ff7ce65c3b11801504e252102dc2..42de4ccd159f6f6853930afd44cea239e2011a54 100644 (file)
@@ -123,12 +123,11 @@ static int l2tp_ip_recv(struct sk_buff *skb)
        struct l2tp_tunnel *tunnel = NULL;
        int length;
 
-       /* Point to L2TP header */
-       optr = ptr = skb->data;
-
        if (!pskb_may_pull(skb, 4))
                goto discard;
 
+       /* Point to L2TP header */
+       optr = ptr = skb->data;
        session_id = ntohl(*((__be32 *) ptr));
        ptr += 4;
 
@@ -156,6 +155,9 @@ static int l2tp_ip_recv(struct sk_buff *skb)
                if (!pskb_may_pull(skb, length))
                        goto discard;
 
+               /* Point to L2TP header */
+               optr = ptr = skb->data;
+               ptr += 4;
                pr_debug("%s: ip recv\n", tunnel->name);
                print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
        }
index 6b54ff3ff4cb8e7af49e7ee315cc78cfca148007..cd479903d943a93abfb196782b0336bb6ff006cb 100644 (file)
@@ -136,12 +136,11 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
        struct l2tp_tunnel *tunnel = NULL;
        int length;
 
-       /* Point to L2TP header */
-       optr = ptr = skb->data;
-
        if (!pskb_may_pull(skb, 4))
                goto discard;
 
+       /* Point to L2TP header */
+       optr = ptr = skb->data;
        session_id = ntohl(*((__be32 *) ptr));
        ptr += 4;
 
@@ -169,6 +168,9 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
                if (!pskb_may_pull(skb, length))
                        goto discard;
 
+               /* Point to L2TP header */
+               optr = ptr = skb->data;
+               ptr += 4;
                pr_debug("%s: ip recv\n", tunnel->name);
                print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
        }
index 283981108ca80cb5bb7182b28e626a1a14c09fb1..74142d07ad31072f8308681a3ff3cfd55da74738 100644 (file)
@@ -343,8 +343,10 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
                                     struct ieee80211_chanctx *ctx,
                                     const struct cfg80211_chan_def *chandef)
 {
-       if (cfg80211_chandef_identical(&ctx->conf.def, chandef))
+       if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) {
+               ieee80211_recalc_chanctx_min_def(local, ctx);
                return;
+       }
 
        WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
 
index 804575ff7af506e73ef50d6ebc32326219b99082..422003540169acb168d8d7a97d3cd62c1337c124 100644 (file)
@@ -1719,6 +1719,10 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
 enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta);
 enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta);
 void ieee80211_sta_set_rx_nss(struct sta_info *sta);
+enum ieee80211_sta_rx_bandwidth
+ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width);
+enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta);
+void ieee80211_sta_set_rx_nss(struct sta_info *sta);
 void ieee80211_process_mu_groups(struct ieee80211_sub_if_data *sdata,
                                 struct ieee80211_mgmt *mgmt);
 u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
index 5b6aec1a06302c7b5efac015a5e50d5239242406..002244bca948520f9e3d722dc908c62aa3eb4fb1 100644 (file)
@@ -530,7 +530,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
        const u8 *target_addr, *orig_addr;
        const u8 *da;
        u8 target_flags, ttl, flags;
-       u32 orig_sn, target_sn, lifetime, target_metric;
+       u32 orig_sn, target_sn, lifetime, target_metric = 0;
        bool reply = false;
        bool forward = true;
        bool root_is_gate;
index d20bab5c146c9d435ee67d6a11eec746db1b1bfa..861b93ffbe92dda5dd234b6aa27a99795f6381ae 100644 (file)
@@ -67,6 +67,7 @@
 
 static const struct rhashtable_params sta_rht_params = {
        .nelem_hint = 3, /* start small */
+       .insecure_elasticity = true, /* Disable chain-length checks. */
        .automatic_shrinking = true,
        .head_offset = offsetof(struct sta_info, hash_node),
        .key_offset = offsetof(struct sta_info, addr),
@@ -258,11 +259,11 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
 }
 
 /* Caller must hold local->sta_mtx */
-static void sta_info_hash_add(struct ieee80211_local *local,
-                             struct sta_info *sta)
+static int sta_info_hash_add(struct ieee80211_local *local,
+                            struct sta_info *sta)
 {
-       rhashtable_insert_fast(&local->sta_hash, &sta->hash_node,
-                              sta_rht_params);
+       return rhashtable_insert_fast(&local->sta_hash, &sta->hash_node,
+                                     sta_rht_params);
 }
 
 static void sta_deliver_ps_frames(struct work_struct *wk)
@@ -524,7 +525,9 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
        set_sta_flag(sta, WLAN_STA_BLOCK_BA);
 
        /* make the station visible */
-       sta_info_hash_add(local, sta);
+       err = sta_info_hash_add(local, sta);
+       if (err)
+               goto out_drop_sta;
 
        list_add_tail_rcu(&sta->list, &local->sta_list);
 
@@ -557,6 +560,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
  out_remove:
        sta_info_hash_del(local, sta);
        list_del_rcu(&sta->list);
+ out_drop_sta:
        local->num_sta--;
        synchronize_net();
        __cleanup_single_sta(sta);
index 053f5c4fa495ba02cd99c5ddb201ce0ad0f7aeff..62193f4bc37bbffa1102a7d52ae896bc1f63ca10 100644 (file)
@@ -377,7 +377,6 @@ DECLARE_EWMA(signal, 1024, 8)
  * @uploaded: set to true when sta is uploaded to the driver
  * @sta: station information we share with the driver
  * @sta_state: duplicates information about station state (for debug)
- * @beacon_loss_count: number of times beacon loss has triggered
  * @rcu_head: RCU head used for freeing this station struct
  * @cur_max_bandwidth: maximum bandwidth to use for TX to the station,
  *     taken from HT/VHT capabilities or VHT operating mode notification
index c9eeb3f1280852b6ec1c44eb82755390cf959629..a29ea813b7d52433174fd72310e77788530b9fa9 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2014, Intel Corporation
  * Copyright 2014  Intel Mobile Communications GmbH
- * Copyright 2015  Intel Deutschland GmbH
+ * Copyright 2015 - 2016 Intel Deutschland GmbH
  *
  * This file is GPLv2 as found in COPYING.
  */
@@ -15,6 +15,7 @@
 #include <linux/rtnetlink.h>
 #include "ieee80211_i.h"
 #include "driver-ops.h"
+#include "rate.h"
 
 /* give usermode some time for retries in setting up the TDLS session */
 #define TDLS_PEER_SETUP_TIMEOUT        (15 * HZ)
@@ -302,7 +303,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata,
        /* IEEE802.11ac-2013 Table E-4 */
        u16 centers_80mhz[] = { 5210, 5290, 5530, 5610, 5690, 5775 };
        struct cfg80211_chan_def uc = sta->tdls_chandef;
-       enum nl80211_chan_width max_width = ieee80211_get_sta_bw(&sta->sta);
+       enum nl80211_chan_width max_width = ieee80211_sta_cap_chan_bw(sta);
        int i;
 
        /* only support upgrading non-narrow channels up to 80Mhz */
@@ -313,7 +314,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata,
        if (max_width > NL80211_CHAN_WIDTH_80)
                max_width = NL80211_CHAN_WIDTH_80;
 
-       if (uc.width == max_width)
+       if (uc.width >= max_width)
                return;
        /*
         * Channel usage constrains in the IEEE802.11ac-2013 specification only
@@ -324,6 +325,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata,
        for (i = 0; i < ARRAY_SIZE(centers_80mhz); i++)
                if (abs(uc.chan->center_freq - centers_80mhz[i]) <= 30) {
                        uc.center_freq1 = centers_80mhz[i];
+                       uc.center_freq2 = 0;
                        uc.width = NL80211_CHAN_WIDTH_80;
                        break;
                }
@@ -332,7 +334,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata,
                return;
 
        /* proceed to downgrade the chandef until usable or the same */
-       while (uc.width > max_width &&
+       while (uc.width > max_width ||
               !cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc,
                                              sdata->wdev.iftype))
                ieee80211_chandef_downgrade(&uc);
@@ -1242,18 +1244,44 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
        return ret;
 }
 
-static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata)
+static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata,
+                                        struct sta_info *sta)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_chanctx_conf *conf;
        struct ieee80211_chanctx *ctx;
+       enum nl80211_chan_width width;
+       struct ieee80211_supported_band *sband;
 
        mutex_lock(&local->chanctx_mtx);
        conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
                                         lockdep_is_held(&local->chanctx_mtx));
        if (conf) {
+               width = conf->def.width;
+               sband = local->hw.wiphy->bands[conf->def.chan->band];
                ctx = container_of(conf, struct ieee80211_chanctx, conf);
                ieee80211_recalc_chanctx_chantype(local, ctx);
+
+               /* if width changed and a peer is given, update its BW */
+               if (width != conf->def.width && sta &&
+                   test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW)) {
+                       enum ieee80211_sta_rx_bandwidth bw;
+
+                       bw = ieee80211_chan_width_to_rx_bw(conf->def.width);
+                       bw = min(bw, ieee80211_sta_cap_rx_bw(sta));
+                       if (bw != sta->sta.bandwidth) {
+                               sta->sta.bandwidth = bw;
+                               rate_control_rate_update(local, sband, sta,
+                                                        IEEE80211_RC_BW_CHANGED);
+                               /*
+                                * if a TDLS peer BW was updated, we need to
+                                * recalc the chandef width again, to get the
+                                * correct chanctx min_def
+                                */
+                               ieee80211_recalc_chanctx_chantype(local, ctx);
+                       }
+               }
+
        }
        mutex_unlock(&local->chanctx_mtx);
 }
@@ -1350,8 +1378,6 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
                        break;
                }
 
-               iee80211_tdls_recalc_chanctx(sdata);
-
                mutex_lock(&local->sta_mtx);
                sta = sta_info_get(sdata, peer);
                if (!sta) {
@@ -1360,6 +1386,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
                        break;
                }
 
+               iee80211_tdls_recalc_chanctx(sdata, sta);
                iee80211_tdls_recalc_ht_protection(sdata, sta);
 
                set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
@@ -1390,7 +1417,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
                iee80211_tdls_recalc_ht_protection(sdata, NULL);
                mutex_unlock(&local->sta_mtx);
 
-               iee80211_tdls_recalc_chanctx(sdata);
+               iee80211_tdls_recalc_chanctx(sdata, NULL);
                break;
        default:
                ret = -ENOTSUPP;
index 62ad5321257d0679918c0f1e21ed716b221a3bf4..21f6602395f769680e3311a0158fe0781073ccc0 100644 (file)
@@ -1116,11 +1116,15 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
                        reset_agg_timer = true;
                } else {
                        queued = true;
+                       if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) {
+                               clear_sta_flag(tx->sta, WLAN_STA_SP);
+                               ps_dbg(tx->sta->sdata,
+                                      "STA %pM aid %d: SP frame queued, close the SP w/o telling the peer\n",
+                                      tx->sta->sta.addr, tx->sta->sta.aid);
+                       }
                        info->control.vif = &tx->sdata->vif;
                        info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
-                       info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS |
-                                       IEEE80211_TX_CTL_NO_PS_BUFFER |
-                                       IEEE80211_TX_STATUS_EOSP;
+                       info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
                        __skb_queue_tail(&tid_tx->pending, skb);
                        if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER)
                                purge_skb = __skb_dequeue(&tid_tx->pending);
@@ -1247,7 +1251,8 @@ static void ieee80211_drv_tx(struct ieee80211_local *local,
        struct txq_info *txqi;
        u8 ac;
 
-       if (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)
+       if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) ||
+           (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE))
                goto tx_normal;
 
        if (!ieee80211_is_data(hdr->frame_control))
index 89e04d55aa1832e522f8e8f9619bfabc8c81ee93..e590e2ef9eaf70fad500b4bf89616efc0d121b62 100644 (file)
@@ -319,7 +319,30 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta)
        return IEEE80211_STA_RX_BW_80;
 }
 
-static enum ieee80211_sta_rx_bandwidth
+enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta)
+{
+       struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap;
+       u32 cap_width;
+
+       if (!vht_cap->vht_supported) {
+               if (!sta->sta.ht_cap.ht_supported)
+                       return NL80211_CHAN_WIDTH_20_NOHT;
+
+               return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
+                               NL80211_CHAN_WIDTH_40 : NL80211_CHAN_WIDTH_20;
+       }
+
+       cap_width = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
+
+       if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)
+               return NL80211_CHAN_WIDTH_160;
+       else if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
+               return NL80211_CHAN_WIDTH_80P80;
+
+       return NL80211_CHAN_WIDTH_80;
+}
+
+enum ieee80211_sta_rx_bandwidth
 ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width)
 {
        switch (width) {
@@ -347,10 +370,7 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta)
 
        bw = ieee80211_sta_cap_rx_bw(sta);
        bw = min(bw, sta->cur_max_bandwidth);
-
-       /* do not cap the BW of TDLS WIDER_BW peers by the bss */
-       if (!test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW))
-               bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width));
+       bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width));
 
        return bw;
 }
index b18c5ed42d956bd7d9261caa7dd05278f72e2785..0b80a7140cc494d8c39bd3efba2423272d1b8844 100644 (file)
@@ -543,6 +543,9 @@ static struct net_device *find_outdev(struct net *net,
        if (!dev)
                return ERR_PTR(-ENODEV);
 
+       if (IS_ERR(dev))
+               return dev;
+
        /* The caller is holding rtnl anyways, so release the dev reference */
        dev_put(dev);
 
index 1ecfa710ca9803e6cbb49e3d419633085f3544dd..f12c17f355d932d9b6a396654a66fceb5aaf0c73 100644 (file)
@@ -4151,7 +4151,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
 
        /* Opening a Tx-ring is NOT supported in TPACKET_V3 */
        if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
-               WARN(1, "Tx-ring is not supported.\n");
+               net_warn_ratelimited("Tx-ring is not supported.\n");
                goto out;
        }
 
index 977fb86065b75dbef916bd0acb9b94876c0f5c04..abc8cc805e8d063813d496d984e95a0c078ca0d3 100644 (file)
@@ -796,7 +796,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn,
 
                addr = kmap_atomic(sg_page(&frag->f_sg));
 
-               src = addr + frag_off;
+               src = addr + frag->f_sg.offset + frag_off;
                dst = (void *)map->m_page_addrs[map_page] + map_off;
                for (k = 0; k < to_copy; k += 8) {
                        /* Record ports that became uncongested, ie
index 616f21f4e7d7c9f9987c1a0206bab68e589040d7..e2b5a5832d3d52888f11e8730a27d937510e151d 100644 (file)
@@ -135,8 +135,8 @@ int rds_page_remainder_alloc(struct scatterlist *scat, unsigned long bytes,
                        if (rem->r_offset != 0)
                                rds_stats_inc(s_page_remainder_hit);
 
-                       rem->r_offset += bytes;
-                       if (rem->r_offset == PAGE_SIZE) {
+                       rem->r_offset += ALIGN(bytes, 8);
+                       if (rem->r_offset >= PAGE_SIZE) {
                                __free_page(rem->r_page);
                                rem->r_page = NULL;
                        }
index 97745351d58c2fb32b9f9b57d61831d7724d83b2..9844fe573029b9e262743440980f15277ddaf5a1 100644 (file)
@@ -705,7 +705,8 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
        /* Check whether this chunk and all the rest of pending data will fit
         * or delay in hopes of bundling a full sized packet.
         */
-       if (chunk->skb->len + q->out_qlen >= transport->pathmtu - packet->overhead)
+       if (chunk->skb->len + q->out_qlen >
+               transport->pathmtu - packet->overhead - sizeof(sctp_data_chunk_t) - 4)
                /* Enough data queued to fill a packet */
                return SCTP_XMIT_OK;
 
index 0a369bb440e77e03262ae48a7e3519db35c87835..662bdd20a7489198fdbbcb00826f8a2782a62a50 100644 (file)
@@ -842,7 +842,7 @@ static void vmci_transport_peer_detach_cb(u32 sub_id,
         * qp_handle.
         */
        if (vmci_handle_is_invalid(e_payload->handle) ||
-           vmci_handle_is_equal(trans->qp_handle, e_payload->handle))
+           !vmci_handle_is_equal(trans->qp_handle, e_payload->handle))
                return;
 
        /* We don't ask for delayed CBs when we subscribe to this event (we
@@ -2154,7 +2154,7 @@ module_exit(vmci_transport_exit);
 
 MODULE_AUTHOR("VMware, Inc.");
 MODULE_DESCRIPTION("VMCI transport for Virtual Sockets");
-MODULE_VERSION("1.0.2.0-k");
+MODULE_VERSION("1.0.3.0-k");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("vmware_vsock");
 MODULE_ALIAS_NETPROTO(PF_VSOCK);
index 502c9fc8db85d013e9e39ff7008765a0ba79ccfd..b820cc96a3bc9d11dfceb0254cf2fdae32ada196 100644 (file)
@@ -76,16 +76,10 @@ HOSTLOADLIBES_offwaketime += -lelf
 HOSTLOADLIBES_spintest += -lelf
 HOSTLOADLIBES_map_perf_test += -lelf -lrt
 
-# point this to your LLVM backend with bpf support
-LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc
-
-# asm/sysreg.h inline assmbly used by it is incompatible with llvm.
-# But, ehere is not easy way to fix it, so just exclude it since it is
+# asm/sysreg.h - inline assembly used by it is incompatible with llvm.
+# But, there is no easy way to fix it, so just exclude it since it is
 # useless for BPF samples.
 $(obj)/%.o: $(src)/%.c
        clang $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) \
                -D__KERNEL__ -D__ASM_SYSREG_H -Wno-unused-value -Wno-pointer-sign \
-               -O2 -emit-llvm -c $< -o -| $(LLC) -march=bpf -filetype=obj -o $@
-       clang $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) \
-               -D__KERNEL__ -D__ASM_SYSREG_H -Wno-unused-value -Wno-pointer-sign \
-               -O2 -emit-llvm -c $< -o -| $(LLC) -march=bpf -filetype=asm -o $@.s
+               -O2 -emit-llvm -c $< -o -| llc -march=bpf -filetype=obj -o $@
index 9363500131a777f98cd7016a35b9cf9858dbf9a6..7904a2a493de43f69c0cf868d78c38d8509790af 100644 (file)
@@ -82,6 +82,7 @@ static int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flag
 #define PT_REGS_FP(x) ((x)->bp)
 #define PT_REGS_RC(x) ((x)->ax)
 #define PT_REGS_SP(x) ((x)->sp)
+#define PT_REGS_IP(x) ((x)->ip)
 
 #elif defined(__s390x__)
 
@@ -94,6 +95,7 @@ static int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flag
 #define PT_REGS_FP(x) ((x)->gprs[11]) /* Works only with CONFIG_FRAME_POINTER */
 #define PT_REGS_RC(x) ((x)->gprs[2])
 #define PT_REGS_SP(x) ((x)->gprs[15])
+#define PT_REGS_IP(x) ((x)->ip)
 
 #elif defined(__aarch64__)
 
@@ -106,6 +108,30 @@ static int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flag
 #define PT_REGS_FP(x) ((x)->regs[29]) /* Works only with CONFIG_FRAME_POINTER */
 #define PT_REGS_RC(x) ((x)->regs[0])
 #define PT_REGS_SP(x) ((x)->sp)
+#define PT_REGS_IP(x) ((x)->pc)
+
+#elif defined(__powerpc__)
+
+#define PT_REGS_PARM1(x) ((x)->gpr[3])
+#define PT_REGS_PARM2(x) ((x)->gpr[4])
+#define PT_REGS_PARM3(x) ((x)->gpr[5])
+#define PT_REGS_PARM4(x) ((x)->gpr[6])
+#define PT_REGS_PARM5(x) ((x)->gpr[7])
+#define PT_REGS_RC(x) ((x)->gpr[3])
+#define PT_REGS_SP(x) ((x)->sp)
+#define PT_REGS_IP(x) ((x)->nip)
 
 #endif
+
+#ifdef __powerpc__
+#define BPF_KPROBE_READ_RET_IP(ip, ctx)                ({ (ip) = (ctx)->link; })
+#define BPF_KRETPROBE_READ_RET_IP              BPF_KPROBE_READ_RET_IP
+#else
+#define BPF_KPROBE_READ_RET_IP(ip, ctx)                ({                              \
+               bpf_probe_read(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); })
+#define BPF_KRETPROBE_READ_RET_IP(ip, ctx)     ({                              \
+               bpf_probe_read(&(ip), sizeof(ip),                               \
+                               (void *)(PT_REGS_FP(ctx) + sizeof(ip))); })
+#endif
+
 #endif
index 95af56ec573989b9ce06783942fc1c21ebc5f5ed..3147377e8fd3c98fe455c6d96f5c774cb5392f11 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/bpf.h>
 #include <string.h>
 #include <time.h>
+#include <sys/resource.h>
 #include "libbpf.h"
 #include "bpf_load.h"
 
index 4b27619d91a46c680a01b91bf05ac6fd6b5ce1d7..ce0167d09cdc6f1432e687933bf38ebef59bad21 100644 (file)
@@ -34,7 +34,7 @@ struct bpf_map_def SEC("maps") stackmap = {
 #define PROG(foo) \
 int foo(struct pt_regs *ctx) \
 { \
-       long v = ctx->ip, *val; \
+       long v = PT_REGS_IP(ctx), *val; \
 \
        val = bpf_map_lookup_elem(&my_map, &v); \
        bpf_map_update_elem(&my_map, &v, &v, BPF_ANY); \
index 09c1adc27d426ed4adec7408a6fbae9193c39bb0..6d6eefd0d4655ed3bdcebe6bf1956a7f43a70d27 100644 (file)
@@ -27,10 +27,10 @@ int bpf_prog2(struct pt_regs *ctx)
        long init_val = 1;
        long *value;
 
-       /* x64/s390x specific: read ip of kfree_skb caller.
+       /* read ip of kfree_skb caller.
         * non-portable version of __builtin_return_address(0)
         */
-       bpf_probe_read(&loc, sizeof(loc), (void *)PT_REGS_RET(ctx));
+       BPF_KPROBE_READ_RET_IP(loc, ctx);
 
        value = bpf_map_lookup_elem(&my_map, &loc);
        if (value)
index ac4671420cf15949c4087b8c2847c69978646650..6dd8e384de961b66269f5da840b5d4b22d057ea8 100644 (file)
@@ -40,7 +40,7 @@ int bpf_prog2(struct pt_regs *ctx)
        long ip = 0;
 
        /* get ip address of kmem_cache_alloc_node() caller */
-       bpf_probe_read(&ip, sizeof(ip), (void *)(PT_REGS_FP(ctx) + sizeof(ip)));
+       BPF_KRETPROBE_READ_RET_IP(ip, ctx);
 
        struct pair v = {
                .val = bpf_ktime_get_ns(),
index 20a257a12ea5000707edd0ba34a4368df79e35e2..acbf7ff2ee6eed9b1ea38548d3ac5f96c50b65be 100644 (file)
@@ -66,6 +66,8 @@ unsigned int do_slm_cstates;
 unsigned int use_c1_residency_msr;
 unsigned int has_aperf;
 unsigned int has_epb;
+unsigned int do_irtl_snb;
+unsigned int do_irtl_hsw;
 unsigned int units = 1000000;  /* MHz etc */
 unsigned int genuine_intel;
 unsigned int has_invariant_tsc;
@@ -187,7 +189,7 @@ struct pkg_data {
        unsigned long long pkg_any_core_c0;
        unsigned long long pkg_any_gfxe_c0;
        unsigned long long pkg_both_core_gfxe_c0;
-       unsigned long long gfx_rc6_ms;
+       long long gfx_rc6_ms;
        unsigned int gfx_mhz;
        unsigned int package_id;
        unsigned int energy_pkg;        /* MSR_PKG_ENERGY_STATUS */
@@ -621,8 +623,14 @@ int format_counters(struct thread_data *t, struct core_data *c,
                outp += sprintf(outp, "%8d", p->pkg_temp_c);
 
        /* GFXrc6 */
-       if (do_gfx_rc6_ms)
-               outp += sprintf(outp, "%8.2f", 100.0 * p->gfx_rc6_ms / 1000.0 / interval_float);
+       if (do_gfx_rc6_ms) {
+               if (p->gfx_rc6_ms == -1) {      /* detect counter reset */
+                       outp += sprintf(outp, "  ***.**");
+               } else {
+                       outp += sprintf(outp, "%8.2f",
+                               p->gfx_rc6_ms / 10.0 / interval_float);
+               }
+       }
 
        /* GFXMHz */
        if (do_gfx_mhz)
@@ -766,7 +774,12 @@ delta_package(struct pkg_data *new, struct pkg_data *old)
        old->pc10 = new->pc10 - old->pc10;
        old->pkg_temp_c = new->pkg_temp_c;
 
-       old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
+       /* flag an error when rc6 counter resets/wraps */
+       if (old->gfx_rc6_ms >  new->gfx_rc6_ms)
+               old->gfx_rc6_ms = -1;
+       else
+               old->gfx_rc6_ms = new->gfx_rc6_ms - old->gfx_rc6_ms;
+
        old->gfx_mhz = new->gfx_mhz;
 
        DELTA_WRAP32(new->energy_pkg, old->energy_pkg);
@@ -1296,6 +1309,7 @@ int hsw_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S,
 int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
 int amt_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
 int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
+int bxt_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
 
 
 static void
@@ -1579,6 +1593,47 @@ dump_config_tdp(void)
        fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1);
        fprintf(outf, ")\n");
 }
+
+unsigned int irtl_time_units[] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0 };
+
+void print_irtl(void)
+{
+       unsigned long long msr;
+
+       get_msr(base_cpu, MSR_PKGC3_IRTL, &msr);
+       fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr);
+       fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
+               (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
+
+       get_msr(base_cpu, MSR_PKGC6_IRTL, &msr);
+       fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr);
+       fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
+               (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
+
+       get_msr(base_cpu, MSR_PKGC7_IRTL, &msr);
+       fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr);
+       fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
+               (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
+
+       if (!do_irtl_hsw)
+               return;
+
+       get_msr(base_cpu, MSR_PKGC8_IRTL, &msr);
+       fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr);
+       fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
+               (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
+
+       get_msr(base_cpu, MSR_PKGC9_IRTL, &msr);
+       fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr);
+       fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
+               (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
+
+       get_msr(base_cpu, MSR_PKGC10_IRTL, &msr);
+       fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr);
+       fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT",
+               (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]);
+
+}
 void free_fd_percpu(void)
 {
        int i;
@@ -2144,6 +2199,9 @@ int probe_nhm_msrs(unsigned int family, unsigned int model)
        case 0x56:      /* BDX-DE */
        case 0x4E:      /* SKL */
        case 0x5E:      /* SKL */
+       case 0x8E:      /* KBL */
+       case 0x9E:      /* KBL */
+       case 0x55:      /* SKX */
                pkg_cstate_limits = hsw_pkg_cstate_limits;
                break;
        case 0x37:      /* BYT */
@@ -2156,6 +2214,9 @@ int probe_nhm_msrs(unsigned int family, unsigned int model)
        case 0x57:      /* PHI */
                pkg_cstate_limits = phi_pkg_cstate_limits;
                break;
+       case 0x5C:      /* BXT */
+               pkg_cstate_limits = bxt_pkg_cstate_limits;
+               break;
        default:
                return 0;
        }
@@ -2248,6 +2309,9 @@ int has_config_tdp(unsigned int family, unsigned int model)
        case 0x56:      /* BDX-DE */
        case 0x4E:      /* SKL */
        case 0x5E:      /* SKL */
+       case 0x8E:      /* KBL */
+       case 0x9E:      /* KBL */
+       case 0x55:      /* SKX */
 
        case 0x57:      /* Knights Landing */
                return 1;
@@ -2585,13 +2649,19 @@ void rapl_probe(unsigned int family, unsigned int model)
        case 0x47:      /* BDW */
                do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
                break;
+       case 0x5C:      /* BXT */
+               do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO;
+               break;
        case 0x4E:      /* SKL */
        case 0x5E:      /* SKL */
+       case 0x8E:      /* KBL */
+       case 0x9E:      /* KBL */
                do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
                break;
        case 0x3F:      /* HSX */
        case 0x4F:      /* BDX */
        case 0x56:      /* BDX-DE */
+       case 0x55:      /* SKX */
        case 0x57:      /* KNL */
                do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
                break;
@@ -2871,6 +2941,10 @@ int has_snb_msrs(unsigned int family, unsigned int model)
        case 0x56:      /* BDX-DE */
        case 0x4E:      /* SKL */
        case 0x5E:      /* SKL */
+       case 0x8E:      /* KBL */
+       case 0x9E:      /* KBL */
+       case 0x55:      /* SKX */
+       case 0x5C:      /* BXT */
                return 1;
        }
        return 0;
@@ -2879,9 +2953,14 @@ int has_snb_msrs(unsigned int family, unsigned int model)
 /*
  * HSW adds support for additional MSRs:
  *
- * MSR_PKG_C8_RESIDENCY            0x00000630
- * MSR_PKG_C9_RESIDENCY            0x00000631
- * MSR_PKG_C10_RESIDENCY           0x00000632
+ * MSR_PKG_C8_RESIDENCY                0x00000630
+ * MSR_PKG_C9_RESIDENCY                0x00000631
+ * MSR_PKG_C10_RESIDENCY       0x00000632
+ *
+ * MSR_PKGC8_IRTL              0x00000633
+ * MSR_PKGC9_IRTL              0x00000634
+ * MSR_PKGC10_IRTL             0x00000635
+ *
  */
 int has_hsw_msrs(unsigned int family, unsigned int model)
 {
@@ -2893,6 +2972,9 @@ int has_hsw_msrs(unsigned int family, unsigned int model)
        case 0x3D:      /* BDW */
        case 0x4E:      /* SKL */
        case 0x5E:      /* SKL */
+       case 0x8E:      /* KBL */
+       case 0x9E:      /* KBL */
+       case 0x5C:      /* BXT */
                return 1;
        }
        return 0;
@@ -2914,6 +2996,8 @@ int has_skl_msrs(unsigned int family, unsigned int model)
        switch (model) {
        case 0x4E:      /* SKL */
        case 0x5E:      /* SKL */
+       case 0x8E:      /* KBL */
+       case 0x9E:      /* KBL */
                return 1;
        }
        return 0;
@@ -3187,7 +3271,7 @@ void process_cpuid()
        if (debug)
                decode_misc_enable_msr();
 
-       if (max_level >= 0x7) {
+       if (max_level >= 0x7 && debug) {
                int has_sgx;
 
                ecx = 0;
@@ -3221,7 +3305,15 @@ void process_cpuid()
                                switch(model) {
                                case 0x4E:      /* SKL */
                                case 0x5E:      /* SKL */
-                                       crystal_hz = 24000000;  /* 24 MHz */
+                               case 0x8E:      /* KBL */
+                               case 0x9E:      /* KBL */
+                                       crystal_hz = 24000000;  /* 24.0 MHz */
+                                       break;
+                               case 0x55:      /* SKX */
+                                       crystal_hz = 25000000;  /* 25.0 MHz */
+                                       break;
+                               case 0x5C:      /* BXT */
+                                       crystal_hz = 19200000;  /* 19.2 MHz */
                                        break;
                                default:
                                        crystal_hz = 0;
@@ -3254,11 +3346,13 @@ void process_cpuid()
 
        do_nhm_platform_info = do_nhm_cstates = do_smi = probe_nhm_msrs(family, model);
        do_snb_cstates = has_snb_msrs(family, model);
+       do_irtl_snb = has_snb_msrs(family, model);
        do_pc2 = do_snb_cstates && (pkg_cstate_limit >= PCL__2);
        do_pc3 = (pkg_cstate_limit >= PCL__3);
        do_pc6 = (pkg_cstate_limit >= PCL__6);
        do_pc7 = do_snb_cstates && (pkg_cstate_limit >= PCL__7);
        do_c8_c9_c10 = has_hsw_msrs(family, model);
+       do_irtl_hsw = has_hsw_msrs(family, model);
        do_skl_residency = has_skl_msrs(family, model);
        do_slm_cstates = is_slm(family, model);
        do_knl_cstates  = is_knl(family, model);
@@ -3564,6 +3658,9 @@ void turbostat_init()
 
        if (debug)
                for_all_cpus(print_thermal, ODD_COUNTERS);
+
+       if (debug && do_irtl_snb)
+               print_irtl();
 }
 
 int fork_it(char **argv)
@@ -3629,7 +3726,7 @@ int get_and_dump_counters(void)
 }
 
 void print_version() {
-       fprintf(outf, "turbostat version 4.11 27 Feb 2016"
+       fprintf(outf, "turbostat version 4.12 5 Apr 2016"
                " - Len Brown <lenb@kernel.org>\n");
 }
 
This page took 0.219897 seconds and 5 git commands to generate.