]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorDavid S. Miller <davem@davemloft.net>
Sat, 22 Nov 2014 03:28:24 +0000 (22:28 -0500)
committerDavid S. Miller <davem@davemloft.net>
Sat, 22 Nov 2014 03:28:24 +0000 (22:28 -0500)
Conflicts:
drivers/net/ieee802154/fakehard.c

A bug fix went into 'net' for ieee802154/fakehard.c, which is removed
in 'net-next'.

Add build fix into the merge from Stephen Rothwell in openvswitch, the
logging macros take a new initial 'log' argument, a new call was added
in 'net' so when we merge that in here we have to explicitly add the
new 'log' arg to it else the build fails.

Signed-off-by: David S. Miller <davem@davemloft.net>
239 files changed:
Documentation/devicetree/bindings/ata/sata_rcar.txt
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
Documentation/devicetree/bindings/pci/pci.txt
Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt
Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt
Documentation/devicetree/bindings/pinctrl/nvidia,tegra20-pinmux.txt
Documentation/devicetree/bindings/pinctrl/pinctrl-sirf.txt
Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt
Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/qcom,apq8084-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/qcom,msm8960-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/input/elantech.txt
MAINTAINERS
Makefile
arch/arm/boot/compressed/head.S
arch/arm/boot/dts/am335x-evm.dts
arch/arm/boot/dts/am437x-gp-evm.dts
arch/arm/boot/dts/am437x-sk-evm.dts
arch/arm/boot/dts/am43x-epos-evm.dts
arch/arm/boot/dts/sama5d31.dtsi
arch/arm/boot/dts/sama5d33.dtsi
arch/arm/boot/dts/sama5d34.dtsi
arch/arm/boot/dts/sama5d35.dtsi
arch/arm/boot/dts/sama5d36.dtsi
arch/arm/boot/dts/sama5d3xcm.dtsi
arch/arm/mach-mvebu/board-v7.c
arch/arm/mm/Kconfig
arch/arm/plat-orion/gpio.c
arch/arm64/include/asm/memory.h
arch/arm64/kernel/efi-entry.S
arch/arm64/kernel/insn.c
arch/arm64/lib/clear_user.S
arch/arm64/mm/mmu.c
arch/mips/include/asm/jump_label.h
arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
arch/mips/include/asm/uaccess.h
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/jump_label.c
arch/mips/lib/memcpy.S
arch/mips/loongson/loongson-3/numa.c
arch/mips/mm/tlb-r4k.c
arch/mips/oprofile/backtrace.c
arch/mips/sgi-ip27/ip27-memory.c
arch/parisc/include/asm/uaccess.h
arch/parisc/include/uapi/asm/bitsperlong.h
arch/parisc/include/uapi/asm/msgbuf.h
arch/parisc/include/uapi/asm/sembuf.h
arch/parisc/include/uapi/asm/shmbuf.h
arch/parisc/include/uapi/asm/signal.h
arch/parisc/include/uapi/asm/unistd.h
arch/parisc/kernel/syscall_table.S
arch/powerpc/sysdev/fsl_msi.c
arch/sparc/include/asm/atomic_32.h
arch/sparc/include/asm/cmpxchg_32.h
arch/sparc/include/uapi/asm/swab.h
arch/sparc/kernel/pci_schizo.c
arch/sparc/kernel/smp_64.c
arch/sparc/lib/atomic32.c
arch/x86/Kconfig
arch/x86/boot/compressed/Makefile
arch/x86/boot/compressed/head_32.S
arch/x86/boot/compressed/head_64.S
arch/x86/boot/compressed/misc.c
arch/x86/boot/compressed/mkpiggy.c
arch/x86/include/asm/smp.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/microcode/amd_early.c
arch/x86/kernel/cpu/microcode/core.c
arch/x86/kernel/cpu/microcode/core_early.c
arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c
arch/x86/kernel/ptrace.c
arch/x86/kernel/smpboot.c
arch/x86/lib/csum-wrappers_64.c
arch/x86/mm/init_64.c
arch/x86/tools/calc_run_size.pl [new file with mode: 0644]
arch/x86/xen/smp.c
block/blk-merge.c
block/blk-mq.c
block/ioprio.c
block/scsi_ioctl.c
drivers/acpi/blacklist.c
drivers/acpi/device_pm.c
drivers/ata/ahci.c
drivers/ata/libahci.c
drivers/ata/sata_rcar.c
drivers/base/power/domain.c
drivers/cpufreq/cpufreq-dt.c
drivers/cpufreq/cpufreq.c
drivers/dma/pl330.c
drivers/dma/sun6i-dma.c
drivers/firewire/core-cdev.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/exynos/exynos_drm_g2d.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_gem_tiling.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/atom.h
drivers/gpu/drm/radeon/atombios_dp.c
drivers/gpu/drm/radeon/atombios_i2c.c
drivers/gpu/drm/radeon/r600_dpm.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/tegra/dc.c
drivers/infiniband/ulp/isert/ib_isert.c
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/input/misc/twl4030-pwrbutton.c
drivers/input/mouse/alps.c
drivers/input/mouse/elantech.c
drivers/input/mouse/synaptics.c
drivers/md/md.c
drivers/net/bonding/bond_main.c
drivers/net/can/dev.c
drivers/net/can/m_can/Kconfig
drivers/net/can/m_can/m_can.c
drivers/net/can/rcar_can.c
drivers/net/can/sja1000/kvaser_pci.c
drivers/net/can/usb/ems_usb.c
drivers/net/can/usb/esd_usb2.c
drivers/net/can/usb/gs_usb.c
drivers/net/can/xilinx_can.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/ppp/pptp.c
drivers/net/usb/qmi_wwan.c
drivers/net/virtio_net.c
drivers/net/vxlan.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/brcm80211/brcmfmac/of.c
drivers/net/wireless/brcm80211/brcmfmac/pcie.c
drivers/net/wireless/brcm80211/brcmfmac/usb.c
drivers/of/address.c
drivers/of/dynamic.c
drivers/of/fdt.c
drivers/of/selftest.c
drivers/pci/access.c
drivers/pci/host/pci-xgene.c
drivers/pci/pci.h
drivers/pci/probe.c
drivers/platform/x86/Kconfig
drivers/platform/x86/hp_accel.c
drivers/power/ab8500_fg.c
drivers/power/bq2415x_charger.c
drivers/power/charger-manager.c
drivers/power/power_supply_core.c
drivers/scsi/bnx2fc/bnx2fc_els.c
drivers/scsi/bnx2fc/bnx2fc_io.c
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
drivers/scsi/cxgbi/libcxgbi.c
drivers/scsi/device_handler/scsi_dh_alua.c
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/scsi_error.c
drivers/target/iscsi/iscsi_target.c
drivers/target/target_core_pr.c
drivers/target/target_core_transport.c
drivers/vhost/scsi.c
fs/nfs/blocklayout/blocklayout.c
fs/nfs/blocklayout/rpc_pipefs.c
fs/nfs/delegation.c
fs/nfs/delegation.h
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/filelayout/filelayout.c
fs/nfs/inode.c
fs/nfs/netns.h
fs/nfs/nfs4proc.c
fs/nfs/write.c
include/dt-bindings/pinctrl/dra.h
include/linux/bitops.h
include/linux/can/dev.h
include/linux/inetdevice.h
include/linux/kernel_stat.h
include/linux/nfs_xdr.h
include/linux/pm_domain.h
include/linux/power/charger-manager.h
include/linux/power_supply.h
include/net/netfilter/nf_tables.h
include/net/vxlan.h
include/sound/soc-dpcm.h
kernel/events/core.c
kernel/power/suspend.c
kernel/sched/core.c
kernel/sched/deadline.c
kernel/sched/fair.c
kernel/sched/rt.c
kernel/sched/sched.h
kernel/time/posix-cpu-timers.c
lib/Makefile
mm/iov_iter.c
net/bridge/br_multicast.c
net/core/skbuff.c
net/dcb/dcbnl.c
net/ipv4/fib_rules.c
net/ipv4/netfilter/nft_masq_ipv4.c
net/ipv4/tcp_input.c
net/ipv6/ip6mr.c
net/ipv6/netfilter/nft_masq_ipv6.c
net/ipx/af_ipx.c
net/mac80211/rc80211_minstrel_ht.c
net/netfilter/ipset/ip_set_core.c
net/netfilter/ipvs/ip_vs_xmit.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_tables_api.c
net/netfilter/nfnetlink.c
net/netfilter/nft_compat.c
net/openvswitch/actions.c
net/openvswitch/datapath.c
net/openvswitch/flow_netlink.c
net/sunrpc/auth_gss/auth_gss.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/cs42l51-i2c.c
sound/soc/codecs/cs42l51.c
sound/soc/codecs/cs42l51.h
sound/soc/codecs/es8328-i2c.c
sound/soc/codecs/max98090.c
sound/soc/codecs/rt5645.c
sound/soc/codecs/rt5670.c
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/sgtl5000.h
sound/soc/codecs/wm_adsp.c
sound/soc/fsl/fsl_asrc.c
sound/soc/rockchip/rockchip_i2s.c
sound/soc/samsung/snow.c
sound/soc/sh/fsi.c
sound/soc/sh/rcar/core.c
sound/soc/soc-core.c
sound/soc/soc-pcm.c
sound/usb/mixer.c
sound/usb/quirks.c

index 1e6111333fa88f86a2008325637195f51d50648d..80ae87a0784bdba8f2014d51ec6b083512c1dc4f 100644 (file)
@@ -3,8 +3,10 @@
 Required properties:
 - compatible           : should contain one of the following:
                          - "renesas,sata-r8a7779" for R-Car H1
-                         - "renesas,sata-r8a7790" for R-Car H2
-                         - "renesas,sata-r8a7791" for R-Car M2
+                         - "renesas,sata-r8a7790-es1" for R-Car H2 ES1
+                         - "renesas,sata-r8a7790" for R-Car H2 other than ES1
+                         - "renesas,sata-r8a7791" for R-Car M2-W
+                         - "renesas,sata-r8a7793" for R-Car M2-N
 - reg                  : address and length of the SATA registers;
 - interrupts           : must consist of one interrupt specifier.
 
index ce6a1a0720285bd9be4549d478ea49b4b985ee31..8a3c4082989906248fd4f07ee7a1493b20580794 100644 (file)
@@ -30,10 +30,6 @@ should only be used when a device has multiple interrupt parents.
   Example:
        interrupts-extended = <&intc1 5 1>, <&intc2 1 0>;
 
-A device node may contain either "interrupts" or "interrupts-extended", but not
-both. If both properties are present, then the operating system should log an
-error and use only the data in "interrupts".
-
 2) Interrupt controller nodes
 -----------------------------
 
index 41aeed38926d19e84b67f3194994ded9c584106c..f8fbe9af7b2f276350426b299c6030adb9464640 100644 (file)
@@ -7,3 +7,14 @@ And for the interrupt mapping part:
 
 Open Firmware Recommended Practice: Interrupt Mapping
 http://www.openfirmware.org/1275/practice/imap/imap0_9d.pdf
+
+Additionally to the properties specified in the above standards a host bridge
+driver implementation may support the following properties:
+
+- linux,pci-domain:
+   If present this property assigns a fixed PCI domain number to a host bridge,
+   otherwise an unstable (across boots) unique number will be assigned.
+   It is required to either not set this property at all or set it for all
+   host bridges in the system, otherwise potentially conflicting domain numbers
+   may be assigned to root buses behind different host bridges.  The domain
+   number for each host bridge in the system must be unique.
index a186181c402ba693b43c71e5f129e6cb05cfcde7..51b943cc9770e1b096e3def62c3e902c4ce02772 100644 (file)
@@ -9,7 +9,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the
 common pinctrl bindings used by client devices, including the meaning of the
 phrase "pin configuration node".
 
-TZ1090-PDC's pin configuration nodes act as a container for an abitrary number
+TZ1090-PDC's pin configuration nodes act as a container for an arbitrary number
 of subnodes. Each of these subnodes represents some desired configuration for a
 pin, a group, or a list of pins or groups. This configuration can include the
 mux function to select on those pin(s)/group(s), and various pin configuration
index 4b27c99f7f9d496028ae215b7c79d3cc4b1e995b..49d0e6050940256edde1dd8a2dcc2a84c6b5f910 100644 (file)
@@ -9,7 +9,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the
 common pinctrl bindings used by client devices, including the meaning of the
 phrase "pin configuration node".
 
-TZ1090's pin configuration nodes act as a container for an abitrary number of
+TZ1090's pin configuration nodes act as a container for an arbitrary number of
 subnodes. Each of these subnodes represents some desired configuration for a
 pin, a group, or a list of pins or groups. This configuration can include the
 mux function to select on those pin(s)/group(s), and various pin configuration
index daa7689560695d1769bdf7d2064ff1f0181873d6..ac4da9fe07bd1fe28d2ceabacbca5453ff41e7a5 100644 (file)
@@ -9,7 +9,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the
 common pinctrl bindings used by client devices, including the meaning of the
 phrase "pin configuration node".
 
-Lantiq's pin configuration nodes act as a container for an abitrary number of
+Lantiq's pin configuration nodes act as a container for an arbitrary number of
 subnodes. Each of these subnodes represents some desired configuration for a
 pin, a group, or a list of pins or groups. This configuration can include the
 mux function to select on those group(s), and two pin configuration parameters:
index b5469db1d7adc2d4f2ff36adf6ed75e2802fe116..e89b4677567d0fcd9a4550905ea806d905d951c0 100644 (file)
@@ -9,7 +9,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the
 common pinctrl bindings used by client devices, including the meaning of the
 phrase "pin configuration node".
 
-Lantiq's pin configuration nodes act as a container for an abitrary number of
+Lantiq's pin configuration nodes act as a container for an arbitrary number of
 subnodes. Each of these subnodes represents some desired configuration for a
 pin, a group, or a list of pins or groups. This configuration can include the
 mux function to select on those group(s), and two pin configuration parameters:
index 61e73cde9ae9437303b7b095dc2d14c1d4966f62..3c8ce28baad63b164513875221a298dca5bb2066 100644 (file)
@@ -9,7 +9,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the
 common pinctrl bindings used by client devices, including the meaning of the
 phrase "pin configuration node".
 
-Tegra's pin configuration nodes act as a container for an abitrary number of
+Tegra's pin configuration nodes act as a container for an arbitrary number of
 subnodes. Each of these subnodes represents some desired configuration for a
 pin, a group, or a list of pins or groups. This configuration can include the
 mux function to select on those pin(s)/group(s), and various pin configuration
index c596a6ad3285acdd52d357a6e4a56cee98a7eb56..5f55be59d914a33aa71f4f432237782fd45f46ad 100644 (file)
@@ -13,7 +13,7 @@ Optional properties:
 Please refer to pinctrl-bindings.txt in this directory for details of the common
 pinctrl bindings used by client devices.
 
-SiRFprimaII's pinmux nodes act as a container for an abitrary number of subnodes.
+SiRFprimaII's pinmux nodes act as a container for an arbitrary number of subnodes.
 Each of these subnodes represents some desired configuration for a group of pins.
 
 Required subnode-properties:
index b4480d5c3aca93a99721829c604c5a823c28bc82..458615596946f6d29ccd60401f87a419fbe0e84a 100644 (file)
@@ -32,7 +32,7 @@ Required properties:
 Please refer to pinctrl-bindings.txt in this directory for details of the common
 pinctrl bindings used by client devices.
 
-SPEAr's pinmux nodes act as a container for an abitrary number of subnodes. Each
+SPEAr's pinmux nodes act as a container for an arbitrary number of subnodes. Each
 of these subnodes represents muxing for a pin, a group, or a list of pins or
 groups.
 
index 2fb90b37aa09080fec5dc37caaafd72d73548607..a7bde64798c7e33a7a84e73bb92f82d5d7fd53eb 100644 (file)
@@ -18,7 +18,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the
 common pinctrl bindings used by client devices, including the meaning of the
 phrase "pin configuration node".
 
-Qualcomm's pin configuration nodes act as a container for an abitrary number of
+Qualcomm's pin configuration nodes act as a container for an arbitrary number of
 subnodes. Each of these subnodes represents some desired configuration for a
 pin, a group, or a list of pins or groups. This configuration can include the
 mux function to select on those pin(s)/group(s), and various pin configuration
index ffafa1990a3048baaf36efce244e4c9ea4e7887f..c4ea61ac56f2fdbdd535a6123ba29c3a05acfb01 100644 (file)
@@ -47,7 +47,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the
 common pinctrl bindings used by client devices, including the meaning of the
 phrase "pin configuration node".
 
-The pin configuration nodes act as a container for an abitrary number of
+The pin configuration nodes act as a container for an arbitrary number of
 subnodes. Each of these subnodes represents some desired configuration for a
 pin, a group, or a list of pins or groups. This configuration can include the
 mux function to select on those pin(s)/group(s), and various pin configuration
index e33e4dcdce79bdfb51e17b4ab1bbb5602db569b0..6e88e91feb1130796dacf610ceb0a6969c5b0b95 100644 (file)
@@ -18,7 +18,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the
 common pinctrl bindings used by client devices, including the meaning of the
 phrase "pin configuration node".
 
-Qualcomm's pin configuration nodes act as a container for an abitrary number of
+Qualcomm's pin configuration nodes act as a container for an arbitrary number of
 subnodes. Each of these subnodes represents some desired configuration for a
 pin, a group, or a list of pins or groups. This configuration can include the
 mux function to select on those pin(s)/group(s), and various pin configuration
index 93b7de91b9f6f62d824436c003ee332705a1efdb..eb8d8aa41f2051a8be7c87e4d10c12b68f6a76d8 100644 (file)
@@ -47,7 +47,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the
 common pinctrl bindings used by client devices, including the meaning of the
 phrase "pin configuration node".
 
-The pin configuration nodes act as a container for an abitrary number of
+The pin configuration nodes act as a container for an arbitrary number of
 subnodes. Each of these subnodes represents some desired configuration for a
 pin, a group, or a list of pins or groups. This configuration can include the
 mux function to select on those pin(s)/group(s), and various pin configuration
index d2ea80dc43ebca126558ed3f97d8a395f1b63c7c..e4d6a9d20f7d0d82c684356f03397f95872ffe26 100644 (file)
@@ -18,7 +18,7 @@ Please refer to pinctrl-bindings.txt in this directory for details of the
 common pinctrl bindings used by client devices, including the meaning of the
 phrase "pin configuration node".
 
-Qualcomm's pin configuration nodes act as a container for an abitrary number of
+Qualcomm's pin configuration nodes act as a container for an arbitrary number of
 subnodes. Each of these subnodes represents some desired configuration for a
 pin, a group, or a list of pins or groups. This configuration can include the
 mux function to select on those pin(s)/group(s), and various pin configuration
index 723999d737445274728bedde163d3534ca62339c..a344ec2713a54a06b833d23c59ba55e01419f8fd 100644 (file)
@@ -34,6 +34,7 @@ chipidea      Chipidea, Inc
 chrp   Common Hardware Reference Platform
 chunghwa       Chunghwa Picture Tubes Ltd.
 cirrus Cirrus Logic, Inc.
+cnm    Chips&Media, Inc.
 cortina        Cortina Systems, Inc.
 crystalfontz   Crystalfontz America, Inc.
 dallas Maxim Integrated Products (formerly Dallas Semiconductor)
@@ -92,6 +93,7 @@ maxim Maxim Integrated Products
 mediatek       MediaTek Inc.
 micrel Micrel Inc.
 microchip      Microchip Technology Inc.
+micron Micron Technology Inc.
 mitsubishi     Mitsubishi Electric Corporation
 mosaixtech     Mosaix Technologies, Inc.
 moxa   Moxa
@@ -127,6 +129,7 @@ renesas     Renesas Electronics Corporation
 ricoh  Ricoh Co. Ltd.
 rockchip       Fuzhou Rockchip Electronics Co., Ltd
 samsung        Samsung Semiconductor
+sandisk        Sandisk Corporation
 sbs    Smart Battery System
 schindler      Schindler
 seagate        Seagate Technology PLC
@@ -138,7 +141,7 @@ silergy     Silergy Corp.
 sirf   SiRF Technology, Inc.
 sitronix       Sitronix Technology Corporation
 smsc   Standard Microsystems Corporation
-snps   Synopsys, Inc.
+snps   Synopsys, Inc.
 solidrun       SolidRun
 sony   Sony Corporation
 spansion       Spansion Inc.
index e1ae127ed099d4934e1d7fb95f1a8ba819c1da9b..1ec0db7879d310dd3525eee439bc291a3e595c02 100644 (file)
@@ -38,22 +38,38 @@ Contents
         7.2.1 Status packet
         7.2.2 Head packet
         7.2.3 Motion packet
+ 8. Trackpoint (for Hardware version 3 and 4)
+    8.1 Registers
+    8.2 Native relative mode 6 byte packet format
+        8.2.1 Status Packet
 
 
 
 1. Introduction
    ~~~~~~~~~~~~
 
-Currently the Linux Elantech touchpad driver is aware of two different
-hardware versions unimaginatively called version 1 and version 2. Version 1
-is found in "older" laptops and uses 4 bytes per packet. Version 2 seems to
-be introduced with the EeePC and uses 6 bytes per packet, and provides
-additional features such as position of two fingers, and width of the touch.
+Currently the Linux Elantech touchpad driver is aware of four different
+hardware versions unimaginatively called version 1,version 2, version 3
+and version 4. Version 1 is found in "older" laptops and uses 4 bytes per
+packet. Version 2 seems to be introduced with the EeePC and uses 6 bytes
+per packet, and provides additional features such as position of two fingers,
+and width of the touch.  Hardware version 3 uses 6 bytes per packet (and
+for 2 fingers the concatenation of two 6 bytes packets) and allows tracking
+of up to 3 fingers. Hardware version 4 uses 6 bytes per packet, and can
+combine a status packet with multiple head or motion packets. Hardware version
+4 allows tracking up to 5 fingers.
+
+Some Hardware version 3 and version 4 also have a trackpoint which uses a
+separate packet format. It is also 6 bytes per packet.
 
 The driver tries to support both hardware versions and should be compatible
 with the Xorg Synaptics touchpad driver and its graphical configuration
 utilities.
 
+Note that a mouse button is also associated with either the touchpad or the
+trackpoint when a trackpoint is available.  Disabling the Touchpad in xorg
+(TouchPadOff=0) will also disable the buttons associated with the touchpad.
+
 Additionally the operation of the touchpad can be altered by adjusting the
 contents of some of its internal registers. These registers are represented
 by the driver as sysfs entries under /sys/bus/serio/drivers/psmouse/serio?
@@ -78,7 +94,7 @@ completeness sake.
 2. Extra knobs
    ~~~~~~~~~~~
 
-Currently the Linux Elantech touchpad driver provides two extra knobs under
+Currently the Linux Elantech touchpad driver provides three extra knobs under
 /sys/bus/serio/drivers/psmouse/serio? for the user.
 
 * debug
@@ -112,6 +128,20 @@ Currently the Linux Elantech touchpad driver provides two extra knobs under
    data consistency checking can be done. For now checking is disabled by
    default. Currently even turning it on will do nothing.
 
+* crc_enabled
+
+   Sets crc_enabled to 0/1. The name "crc_enabled" is the official name of
+   this integrity check, even though it is not an actual cyclic redundancy
+   check.
+
+   Depending on the state of crc_enabled, certain basic data integrity
+   verification is done by the driver on hardware version 3 and 4. The
+   driver will reject any packet that appears corrupted. Using this knob,
+   The state of crc_enabled can be altered with this knob.
+
+   Reading the crc_enabled value will show the active value. Echoing
+   "0" or "1" to this file will set the state to "0" or "1".
+
 /////////////////////////////////////////////////////////////////////////////
 
 3. Differentiating hardware versions
@@ -746,3 +776,42 @@ byte 5:
 
         byte 0 ~ 2 for one finger
         byte 3 ~ 5 for another
+
+
+8. Trackpoint (for Hardware version 3 and 4)
+   =========================================
+8.1 Registers
+    ~~~~~~~~~
+No special registers have been identified.
+
+8.2 Native relative mode 6 byte packet format
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+8.2.1 Status Packet
+      ~~~~~~~~~~~~~
+
+byte 0:
+   bit   7   6   5   4   3   2   1   0
+         0   0  sx  sy   0   M   R   L
+byte 1:
+   bit   7   6   5   4   3   2   1   0
+       ~sx   0   0   0   0   0   0   0
+byte 2:
+   bit   7   6   5   4   3   2   1   0
+       ~sy   0   0   0   0   0   0   0
+byte 3:
+   bit   7   6   5   4   3   2   1   0
+         0   0 ~sy ~sx   0   1   1   0
+byte 4:
+   bit   7   6   5   4   3   2   1   0
+        x7  x6  x5  x4  x3  x2  x1  x0
+byte 5:
+   bit   7   6   5   4   3   2   1   0
+        y7  y6  y5  y4  y3  y2  y1  y0
+
+
+         x and y are written in two's complement spread
+             over 9 bits with sx/sy the relative top bit and
+             x7..x0 and y7..y0 the lower bits.
+        ~sx is the inverse of sx, ~sy is the inverse of sy.
+         The sign of y is opposite to what the input driver
+             expects for a relative movement
index 064d24191506da232324e045bcb280ffa5e00347..a545d68af54cad334ebcd16527aaedeafdafc74e 100644 (file)
@@ -2752,6 +2752,13 @@ W:       http://www.chelsio.com
 S:     Supported
 F:     drivers/net/ethernet/chelsio/cxgb3/
 
+CXGB3 ISCSI DRIVER (CXGB3I)
+M:      Karen Xie <kxie@chelsio.com>
+L:      linux-scsi@vger.kernel.org
+W:      http://www.chelsio.com
+S:      Supported
+F:      drivers/scsi/cxgbi/cxgb3i
+
 CXGB3 IWARP RNIC DRIVER (IW_CXGB3)
 M:     Steve Wise <swise@chelsio.com>
 L:     linux-rdma@vger.kernel.org
@@ -2766,6 +2773,13 @@ W:       http://www.chelsio.com
 S:     Supported
 F:     drivers/net/ethernet/chelsio/cxgb4/
 
+CXGB4 ISCSI DRIVER (CXGB4I)
+M:      Karen Xie <kxie@chelsio.com>
+L:      linux-scsi@vger.kernel.org
+W:      http://www.chelsio.com
+S:      Supported
+F:      drivers/scsi/cxgbi/cxgb4i
+
 CXGB4 IWARP RNIC DRIVER (IW_CXGB4)
 M:     Steve Wise <swise@chelsio.com>
 L:     linux-rdma@vger.kernel.org
@@ -6617,6 +6631,23 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git
 S:     Maintained
 F:     arch/arm/*omap*/
 F:     drivers/i2c/busses/i2c-omap.c
+F:     drivers/irqchip/irq-omap-intc.c
+F:     drivers/mfd/*omap*.c
+F:     drivers/mfd/menelaus.c
+F:     drivers/mfd/palmas.c
+F:     drivers/mfd/tps65217.c
+F:     drivers/mfd/tps65218.c
+F:     drivers/mfd/tps65910.c
+F:     drivers/mfd/twl-core.[ch]
+F:     drivers/mfd/twl4030*.c
+F:     drivers/mfd/twl6030*.c
+F:     drivers/mfd/twl6040*.c
+F:     drivers/regulator/palmas-regulator*.c
+F:     drivers/regulator/pbias-regulator.c
+F:     drivers/regulator/tps65217-regulator.c
+F:     drivers/regulator/tps65218-regulator.c
+F:     drivers/regulator/tps65910-regulator.c
+F:     drivers/regulator/twl-regulator.c
 F:     include/linux/i2c-omap.h
 
 OMAP DEVICE TREE SUPPORT
@@ -6627,6 +6658,9 @@ L:        devicetree@vger.kernel.org
 S:     Maintained
 F:     arch/arm/boot/dts/*omap*
 F:     arch/arm/boot/dts/*am3*
+F:     arch/arm/boot/dts/*am4*
+F:     arch/arm/boot/dts/*am5*
+F:     arch/arm/boot/dts/*dra7*
 
 OMAP CLOCK FRAMEWORK SUPPORT
 M:     Paul Walmsley <paul@pwsan.com>
index bc7eb6ada9667966110849dc0cdeb3ca631caa7c..00d618bbe8e7588a8c36ed0ba0371b219e8d8543 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 18
 SUBLEVEL = 0
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc5
 NAME = Diseased Newt
 
 # *DOCUMENTATION*
@@ -297,7 +297,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
 
 HOSTCC       = gcc
 HOSTCXX      = g++
-HOSTCFLAGS   = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer
+HOSTCFLAGS   = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu89
 HOSTCXXFLAGS = -O2
 
 ifeq ($(shell $(HOSTCC) -v 2>&1 | grep -c "clang version"), 1)
@@ -401,7 +401,8 @@ KBUILD_CPPFLAGS := -D__KERNEL__
 KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
                   -fno-strict-aliasing -fno-common \
                   -Werror-implicit-function-declaration \
-                  -Wno-format-security
+                  -Wno-format-security \
+                  -std=gnu89
 
 KBUILD_AFLAGS_KERNEL :=
 KBUILD_CFLAGS_KERNEL :=
index 413fd94b53012dacc6596d2e9b225c04a7dab97a..68be9017593df10f235ca228a6837aaa11f5c818 100644 (file)
@@ -397,8 +397,7 @@ dtb_check_done:
                add     sp, sp, r6
 #endif
 
-               tst     r4, #1
-               bleq    cache_clean_flush
+               bl      cache_clean_flush
 
                adr     r0, BSYM(restart)
                add     r0, r0, r6
@@ -1047,6 +1046,8 @@ cache_clean_flush:
                b       call_cache_fn
 
 __armv4_mpu_cache_flush:
+               tst     r4, #1
+               movne   pc, lr
                mov     r2, #1
                mov     r3, #0
                mcr     p15, 0, ip, c7, c6, 0   @ invalidate D cache
@@ -1064,6 +1065,8 @@ __armv4_mpu_cache_flush:
                mov     pc, lr
                
 __fa526_cache_flush:
+               tst     r4, #1
+               movne   pc, lr
                mov     r1, #0
                mcr     p15, 0, r1, c7, c14, 0  @ clean and invalidate D cache
                mcr     p15, 0, r1, c7, c5, 0   @ flush I cache
@@ -1072,13 +1075,16 @@ __fa526_cache_flush:
 
 __armv6_mmu_cache_flush:
                mov     r1, #0
-               mcr     p15, 0, r1, c7, c14, 0  @ clean+invalidate D
+               tst     r4, #1
+               mcreq   p15, 0, r1, c7, c14, 0  @ clean+invalidate D
                mcr     p15, 0, r1, c7, c5, 0   @ invalidate I+BTB
-               mcr     p15, 0, r1, c7, c15, 0  @ clean+invalidate unified
+               mcreq   p15, 0, r1, c7, c15, 0  @ clean+invalidate unified
                mcr     p15, 0, r1, c7, c10, 4  @ drain WB
                mov     pc, lr
 
 __armv7_mmu_cache_flush:
+               tst     r4, #1
+               bne     iflush
                mrc     p15, 0, r10, c0, c1, 5  @ read ID_MMFR1
                tst     r10, #0xf << 16         @ hierarchical cache (ARMv7)
                mov     r10, #0
@@ -1139,6 +1145,8 @@ iflush:
                mov     pc, lr
 
 __armv5tej_mmu_cache_flush:
+               tst     r4, #1
+               movne   pc, lr
 1:             mrc     p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache
                bne     1b
                mcr     p15, 0, r0, c7, c5, 0   @ flush I cache
@@ -1146,6 +1154,8 @@ __armv5tej_mmu_cache_flush:
                mov     pc, lr
 
 __armv4_mmu_cache_flush:
+               tst     r4, #1
+               movne   pc, lr
                mov     r2, #64*1024            @ default: 32K dcache size (*2)
                mov     r11, #32                @ default: 32 byte line size
                mrc     p15, 0, r3, c0, c0, 1   @ read cache type
@@ -1179,6 +1189,8 @@ no_cache_id:
 
 __armv3_mmu_cache_flush:
 __armv3_mpu_cache_flush:
+               tst     r4, #1
+               movne   pc, lr
                mov     r1, #0
                mcr     p15, 0, r1, c7, c0, 0   @ invalidate whole cache v3
                mov     pc, lr
index e2156a583de76a2cd67dcbc06593fb192caaf7e4..c4b968f0feb53434b247c66e37ceac51a7f7b4aa 100644 (file)
                        reg = <0x00060000 0x00020000>;
                };
                partition@4 {
-                       label = "NAND.u-boot-spl";
+                       label = "NAND.u-boot-spl-os";
                        reg = <0x00080000 0x00040000>;
                };
                partition@5 {
index e7ac47fa6615e33ee52e3ef58025721f49c7eb08..a521ac0a7d5a2f53db4caaeea32b0a6432f4a5ad 100644 (file)
                dcdc3: regulator-dcdc3 {
                        compatible = "ti,tps65218-dcdc3";
                        regulator-name = "vdcdc3";
-                       regulator-min-microvolt = <1350000>;
-                       regulator-max-microvolt = <1350000>;
+                       regulator-min-microvolt = <1500000>;
+                       regulator-max-microvolt = <1500000>;
                        regulator-boot-on;
                        regulator-always-on;
                };
index 859ff3d620ee6734bcd0e802cf53fd8b94069547..87aa4f3b8b3d516807cb9446313283df2c0860b0 100644 (file)
                dcdc3: regulator-dcdc3 {
                        compatible = "ti,tps65218-dcdc3";
                        regulator-name = "vdds_ddr";
-                       regulator-min-microvolt = <1350000>;
-                       regulator-max-microvolt = <1350000>;
+                       regulator-min-microvolt = <1500000>;
+                       regulator-max-microvolt = <1500000>;
                        regulator-boot-on;
                        regulator-always-on;
                };
index ac3e4859935f1ad31da67107eda970eec6f526ba..f7e9bba10bd6db397342d2f1561da69bc8bc7808 100644 (file)
                dcdc3: regulator-dcdc3 {
                        compatible = "ti,tps65218-dcdc3";
                        regulator-name = "vdcdc3";
-                       regulator-min-microvolt = <1350000>;
-                       regulator-max-microvolt = <1350000>;
+                       regulator-min-microvolt = <1500000>;
+                       regulator-max-microvolt = <1500000>;
                        regulator-boot-on;
                        regulator-always-on;
                };
index 7997dc9863ed2cb7dd1cfc49c6f5bfcc70304d45..883878b32971a915d6d841ecc404cba1d9dd6056 100644 (file)
@@ -12,5 +12,5 @@
 #include "sama5d3_uart.dtsi"
 
 / {
-       compatible = "atmel,samad31", "atmel,sama5d3", "atmel,sama5";
+       compatible = "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
 };
index 39f832253cafb7613ed46bed3d2cb3d19f0a1b1f..4b4434aca351208553a857d0b9a662c4a977b2e3 100644 (file)
@@ -10,5 +10,5 @@
 #include "sama5d3_gmac.dtsi"
 
 / {
-       compatible = "atmel,samad33", "atmel,sama5d3", "atmel,sama5";
+       compatible = "atmel,sama5d33", "atmel,sama5d3", "atmel,sama5";
 };
index 89cda2c0da39268f548533538fb76a9d08652a6e..aa01573fdee9366dbb23086092e8dde3d7970d45 100644 (file)
@@ -12,5 +12,5 @@
 #include "sama5d3_mci2.dtsi"
 
 / {
-       compatible = "atmel,samad34", "atmel,sama5d3", "atmel,sama5";
+       compatible = "atmel,sama5d34", "atmel,sama5d3", "atmel,sama5";
 };
index d20cd71b5f0e7f142c9b83ce81b5f9d5a7e73e6a..16c39f4c96a40841d07bac8ffce1d768d1c69cc4 100644 (file)
@@ -14,5 +14,5 @@
 #include "sama5d3_tcb1.dtsi"
 
 / {
-       compatible = "atmel,samad35", "atmel,sama5d3", "atmel,sama5";
+       compatible = "atmel,sama5d35", "atmel,sama5d3", "atmel,sama5";
 };
index db58cad6acd32633b88bf88a0589885bfa58ed9b..e85139ef40aff61a1da90f76d963ed015e9d3fc9 100644 (file)
@@ -16,5 +16,5 @@
 #include "sama5d3_uart.dtsi"
 
 / {
-       compatible = "atmel,samad36", "atmel,sama5d3", "atmel,sama5";
+       compatible = "atmel,sama5d36", "atmel,sama5d3", "atmel,sama5";
 };
index 962dc28dc37b9bbc4a3427c4e127d26fc689bf63..cfcd200b0c177967f91d9c26e4372d4f1f514b27 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 / {
-       compatible = "atmel,samad3xcm", "atmel,sama5d3", "atmel,sama5";
+       compatible = "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5";
 
        chosen {
                bootargs = "console=ttyS0,115200 rootfstype=ubifs ubi.mtd=5 root=ubi0:rootfs";
index 6478626e3ff64c035e11ac69a290099c44d972a8..d0d39f150fabf845d33a5ecff9c1d2687d387bb3 100644 (file)
@@ -188,7 +188,7 @@ static void __init thermal_quirk(void)
 
 static void __init mvebu_dt_init(void)
 {
-       if (of_machine_is_compatible("plathome,openblocks-ax3-4"))
+       if (of_machine_is_compatible("marvell,armadaxp"))
                i2c_quirk();
        if (of_machine_is_compatible("marvell,a375-db")) {
                external_abort_quirk();
index ae69809a9e479bef7617e41627b082452c93d09e..7eb94e6fc37672f82c115c16926832a2089329c4 100644 (file)
@@ -798,6 +798,7 @@ config NEED_KUSER_HELPERS
 
 config KUSER_HELPERS
        bool "Enable kuser helpers in vector page" if !NEED_KUSER_HELPERS
+       depends on MMU
        default y
        help
          Warning: disabling this option may break user programs.
index b61a3bcc2fa83bb028933edc80d934e5d1222386..e048f6198d68d69449c642c71e45db6022b4e4e9 100644 (file)
@@ -497,6 +497,34 @@ static void orion_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 #define orion_gpio_dbg_show NULL
 #endif
 
+static void orion_gpio_unmask_irq(struct irq_data *d)
+{
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct irq_chip_type *ct = irq_data_get_chip_type(d);
+       u32 reg_val;
+       u32 mask = d->mask;
+
+       irq_gc_lock(gc);
+       reg_val = irq_reg_readl(gc->reg_base + ct->regs.mask);
+       reg_val |= mask;
+       irq_reg_writel(reg_val, gc->reg_base + ct->regs.mask);
+       irq_gc_unlock(gc);
+}
+
+static void orion_gpio_mask_irq(struct irq_data *d)
+{
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct irq_chip_type *ct = irq_data_get_chip_type(d);
+       u32 mask = d->mask;
+       u32 reg_val;
+
+       irq_gc_lock(gc);
+       reg_val = irq_reg_readl(gc->reg_base + ct->regs.mask);
+       reg_val &= ~mask;
+       irq_reg_writel(reg_val, gc->reg_base + ct->regs.mask);
+       irq_gc_unlock(gc);
+}
+
 void __init orion_gpio_init(struct device_node *np,
                            int gpio_base, int ngpio,
                            void __iomem *base, int mask_offset,
@@ -565,8 +593,8 @@ void __init orion_gpio_init(struct device_node *np,
        ct = gc->chip_types;
        ct->regs.mask = ochip->mask_offset + GPIO_LEVEL_MASK_OFF;
        ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW;
-       ct->chip.irq_mask = irq_gc_mask_clr_bit;
-       ct->chip.irq_unmask = irq_gc_mask_set_bit;
+       ct->chip.irq_mask = orion_gpio_mask_irq;
+       ct->chip.irq_unmask = orion_gpio_unmask_irq;
        ct->chip.irq_set_type = gpio_irq_set_type;
        ct->chip.name = ochip->chip.label;
 
@@ -575,8 +603,8 @@ void __init orion_gpio_init(struct device_node *np,
        ct->regs.ack = GPIO_EDGE_CAUSE_OFF;
        ct->type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
        ct->chip.irq_ack = irq_gc_ack_clr_bit;
-       ct->chip.irq_mask = irq_gc_mask_clr_bit;
-       ct->chip.irq_unmask = irq_gc_mask_set_bit;
+       ct->chip.irq_mask = orion_gpio_mask_irq;
+       ct->chip.irq_unmask = orion_gpio_unmask_irq;
        ct->chip.irq_set_type = gpio_irq_set_type;
        ct->handler = handle_edge_irq;
        ct->chip.name = ochip->chip.label;
index ccc7087d3c4ea7451ac3734a395b6d6607bbdd2b..a62cd077457b933641d4f016c255e297b332c3bc 100644 (file)
@@ -142,7 +142,7 @@ static inline void *phys_to_virt(phys_addr_t x)
  *  virt_to_page(k)    convert a _valid_ virtual address to struct page *
  *  virt_addr_valid(k) indicates whether a virtual address is valid
  */
-#define ARCH_PFN_OFFSET                PHYS_PFN_OFFSET
+#define ARCH_PFN_OFFSET                ((unsigned long)PHYS_PFN_OFFSET)
 
 #define virt_to_page(kaddr)    pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 #define        virt_addr_valid(kaddr)  pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
index 619b1dd7bcdea70e184daacbfb5dd7797c8460c0..d18a449409683cb8f87e7998259ea4141d3d0eca 100644 (file)
@@ -54,18 +54,17 @@ ENTRY(efi_stub_entry)
        b.eq    efi_load_fail
 
        /*
-        * efi_entry() will have relocated the kernel image if necessary
-        * and we return here with device tree address in x0 and the kernel
-        * entry point stored at *image_addr. Save those values in registers
-        * which are callee preserved.
+        * efi_entry() will have copied the kernel image if necessary and we
+        * return here with device tree address in x0 and the kernel entry
+        * point stored at *image_addr. Save those values in registers which
+        * are callee preserved.
         */
        mov     x20, x0         // DTB address
        ldr     x0, [sp, #16]   // relocated _text address
        mov     x21, x0
 
        /*
-        * Flush dcache covering current runtime addresses
-        * of kernel text/data. Then flush all of icache.
+        * Calculate size of the kernel Image (same for original and copy).
         */
        adrp    x1, _text
        add     x1, x1, #:lo12:_text
@@ -73,9 +72,24 @@ ENTRY(efi_stub_entry)
        add     x2, x2, #:lo12:_edata
        sub     x1, x2, x1
 
+       /*
+        * Flush the copied Image to the PoC, and ensure it is not shadowed by
+        * stale icache entries from before relocation.
+        */
        bl      __flush_dcache_area
        ic      ialluis
 
+       /*
+        * Ensure that the rest of this function (in the original Image) is
+        * visible when the caches are disabled. The I-cache can't have stale
+        * entries for the VA range of the current image, so no maintenance is
+        * necessary.
+        */
+       adr     x0, efi_stub_entry
+       adr     x1, efi_stub_entry_end
+       sub     x1, x1, x0
+       bl      __flush_dcache_area
+
        /* Turn off Dcache and MMU */
        mrs     x0, CurrentEL
        cmp     x0, #CurrentEL_EL2
@@ -105,4 +119,5 @@ efi_load_fail:
        ldp     x29, x30, [sp], #32
        ret
 
+efi_stub_entry_end:
 ENDPROC(efi_stub_entry)
index e007714ded04e6a0854657b0cc39f244e06de18c..8cd27fedc8b6a14caa41fac458549695d4ecb7f9 100644 (file)
@@ -163,9 +163,10 @@ static int __kprobes aarch64_insn_patch_text_cb(void *arg)
                 * which ends with "dsb; isb" pair guaranteeing global
                 * visibility.
                 */
-               atomic_set(&pp->cpu_count, -1);
+               /* Notify other processors with an additional increment. */
+               atomic_inc(&pp->cpu_count);
        } else {
-               while (atomic_read(&pp->cpu_count) != -1)
+               while (atomic_read(&pp->cpu_count) <= num_online_cpus())
                        cpu_relax();
                isb();
        }
index 6e0ed93d51fe1850ee27176fc9222dac5416b74d..c17967fdf5f6007330ba65beb7a05bd347600764 100644 (file)
@@ -46,7 +46,7 @@ USER(9f, strh wzr, [x0], #2   )
        sub     x1, x1, #2
 4:     adds    x1, x1, #1
        b.mi    5f
-       strb    wzr, [x0]
+USER(9f, strb  wzr, [x0]       )
 5:     mov     x0, #0
        ret
 ENDPROC(__clear_user)
index 0bf90d26e7455daf38bc5710a1d01222543cda7f..f4f8b500f74c634ce62d36f25259e26c7826d2b7 100644 (file)
@@ -202,7 +202,7 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
 }
 
 static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
-                                 unsigned long end, unsigned long phys,
+                                 unsigned long end, phys_addr_t phys,
                                  int map_io)
 {
        pud_t *pud;
index e194f957ca8c42a0af82f0621c425308a25e4d53..fdbff44e5482cd20acc5efc798091894a3292c4f 100644 (file)
 #define WORD_INSN ".word"
 #endif
 
+#ifdef CONFIG_CPU_MICROMIPS
+#define NOP_INSN "nop32"
+#else
+#define NOP_INSN "nop"
+#endif
+
 static __always_inline bool arch_static_branch(struct static_key *key)
 {
-       asm_volatile_goto("1:\tnop\n\t"
+       asm_volatile_goto("1:\t" NOP_INSN "\n\t"
                "nop\n\t"
                ".pushsection __jump_table,  \"aw\"\n\t"
                WORD_INSN " 1b, %l[l_yes], %0\n\t"
index 7d28f95b0512ea27e1aeb7fac6f22ecc561a45fd..6d69332f21ecd53e09eebfba0de74f1c9fc1daa6 100644 (file)
 #define cpu_has_mcheck         0
 #define cpu_has_mdmx           0
 #define cpu_has_mips16         0
-#define cpu_has_mips32r1       0
 #define cpu_has_mips32r2       0
 #define cpu_has_mips3d         0
-#define cpu_has_mips64r1       0
 #define cpu_has_mips64r2       0
 #define cpu_has_mipsmt         0
 #define cpu_has_prefetch       0
index a10951090234073cae8aa6ea9d8b5542faef6a22..133678ab4eb88cbf213d6516c21be76d06e23a22 100644 (file)
@@ -301,7 +301,8 @@ do {                                                                        \
                        __get_kernel_common((x), size, __gu_ptr);       \
                else                                                    \
                        __get_user_common((x), size, __gu_ptr);         \
-       }                                                               \
+       } else                                                          \
+               (x) = 0;                                                \
                                                                        \
        __gu_err;                                                       \
 })
@@ -316,6 +317,7 @@ do {                                                                        \
        "       .insn                                           \n"     \
        "       .section .fixup,\"ax\"                          \n"     \
        "3:     li      %0, %4                                  \n"     \
+       "       move    %1, $0                                  \n"     \
        "       j       2b                                      \n"     \
        "       .previous                                       \n"     \
        "       .section __ex_table,\"a\"                       \n"     \
@@ -630,6 +632,7 @@ do {                                                                        \
        "       .insn                                           \n"     \
        "       .section .fixup,\"ax\"                          \n"     \
        "3:     li      %0, %4                                  \n"     \
+       "       move    %1, $0                                  \n"     \
        "       j       2b                                      \n"     \
        "       .previous                                       \n"     \
        "       .section __ex_table,\"a\"                       \n"     \
@@ -773,10 +776,11 @@ extern void __put_user_unaligned_unknown(void);
        "jal\t" #destination "\n\t"
 #endif
 
-#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
-#define DADDI_SCRATCH "$0"
-#else
+#if defined(CONFIG_CPU_DADDI_WORKAROUNDS) || (defined(CONFIG_EVA) &&   \
+                                             defined(CONFIG_CPU_HAS_PREFETCH))
 #define DADDI_SCRATCH "$3"
+#else
+#define DADDI_SCRATCH "$0"
 #endif
 
 extern size_t __copy_user(void *__to, const void *__from, size_t __n);
index 94c4a0c0a577909849326dd38999d30ef017ab99..d5a4f380b019bb8c8a4f5ca1ce0229c45689cf4f 100644 (file)
@@ -757,31 +757,34 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                        c->cputype = CPU_LOONGSON2;
                        __cpu_name[cpu] = "ICT Loongson-2";
                        set_elf_platform(cpu, "loongson2e");
+                       set_isa(c, MIPS_CPU_ISA_III);
                        break;
                case PRID_REV_LOONGSON2F:
                        c->cputype = CPU_LOONGSON2;
                        __cpu_name[cpu] = "ICT Loongson-2";
                        set_elf_platform(cpu, "loongson2f");
+                       set_isa(c, MIPS_CPU_ISA_III);
                        break;
                case PRID_REV_LOONGSON3A:
                        c->cputype = CPU_LOONGSON3;
-                       c->writecombine = _CACHE_UNCACHED_ACCELERATED;
                        __cpu_name[cpu] = "ICT Loongson-3";
                        set_elf_platform(cpu, "loongson3a");
+                       set_isa(c, MIPS_CPU_ISA_M64R1);
                        break;
                case PRID_REV_LOONGSON3B_R1:
                case PRID_REV_LOONGSON3B_R2:
                        c->cputype = CPU_LOONGSON3;
                        __cpu_name[cpu] = "ICT Loongson-3";
                        set_elf_platform(cpu, "loongson3b");
+                       set_isa(c, MIPS_CPU_ISA_M64R1);
                        break;
                }
 
-               set_isa(c, MIPS_CPU_ISA_III);
                c->options = R4K_OPTS |
                             MIPS_CPU_FPU | MIPS_CPU_LLSC |
                             MIPS_CPU_32FPR;
                c->tlbsize = 64;
+               c->writecombine = _CACHE_UNCACHED_ACCELERATED;
                break;
        case PRID_IMP_LOONGSON_32:  /* Loongson-1 */
                decode_configs(c);
index 6001610cfe55f846a403633a13cfa8973a23e07a..dda800e9e73167d3637f972516743b12e25a9ddc 100644 (file)
 
 #ifdef HAVE_JUMP_LABEL
 
-#define J_RANGE_MASK ((1ul << 28) - 1)
+/*
+ * Define parameters for the standard MIPS and the microMIPS jump
+ * instruction encoding respectively:
+ *
+ * - the ISA bit of the target, either 0 or 1 respectively,
+ *
+ * - the amount the jump target address is shifted right to fit in the
+ *   immediate field of the machine instruction, either 2 or 1,
+ *
+ * - the mask determining the size of the jump region relative to the
+ *   delay-slot instruction, either 256MB or 128MB,
+ *
+ * - the jump target alignment, either 4 or 2 bytes.
+ */
+#define J_ISA_BIT      IS_ENABLED(CONFIG_CPU_MICROMIPS)
+#define J_RANGE_SHIFT  (2 - J_ISA_BIT)
+#define J_RANGE_MASK   ((1ul << (26 + J_RANGE_SHIFT)) - 1)
+#define J_ALIGN_MASK   ((1ul << J_RANGE_SHIFT) - 1)
 
 void arch_jump_label_transform(struct jump_entry *e,
                               enum jump_label_type type)
 {
+       union mips_instruction *insn_p;
        union mips_instruction insn;
-       union mips_instruction *insn_p =
-               (union mips_instruction *)(unsigned long)e->code;
 
-       /* Jump only works within a 256MB aligned region. */
-       BUG_ON((e->target & ~J_RANGE_MASK) != (e->code & ~J_RANGE_MASK));
+       insn_p = (union mips_instruction *)msk_isa16_mode(e->code);
+
+       /* Jump only works within an aligned region its delay slot is in. */
+       BUG_ON((e->target & ~J_RANGE_MASK) != ((e->code + 4) & ~J_RANGE_MASK));
 
-       /* Target must have 4 byte alignment. */
-       BUG_ON((e->target & 3) != 0);
+       /* Target must have the right alignment and ISA must be preserved. */
+       BUG_ON((e->target & J_ALIGN_MASK) != J_ISA_BIT);
 
        if (type == JUMP_LABEL_ENABLE) {
-               insn.j_format.opcode = j_op;
-               insn.j_format.target = (e->target & J_RANGE_MASK) >> 2;
+               insn.j_format.opcode = J_ISA_BIT ? mm_j32_op : j_op;
+               insn.j_format.target = e->target >> J_RANGE_SHIFT;
        } else {
                insn.word = 0; /* nop */
        }
 
        get_online_cpus();
        mutex_lock(&text_mutex);
-       *insn_p = insn;
+       if (IS_ENABLED(CONFIG_CPU_MICROMIPS)) {
+               insn_p->halfword[0] = insn.word >> 16;
+               insn_p->halfword[1] = insn.word;
+       } else
+               *insn_p = insn;
 
        flush_icache_range((unsigned long)insn_p,
                           (unsigned long)insn_p + sizeof(*insn_p));
index c17ef80cf65ab0f67946b515c24dab351f684acc..5d3238af9b5cc551ecb0ca9670b242b62f181a73 100644 (file)
        STOREB(t0, NBYTES-2(dst), .Ls_exc_p1\@)
 .Ldone\@:
        jr      ra
+        nop
        .if __memcpy == 1
        END(memcpy)
        .set __memcpy, 0
index 37ed184398c6bbf8d017f130c73317ed2e548518..42323bcc5d28baf7279aacc50d15a4107c2c71b7 100644 (file)
@@ -33,6 +33,7 @@
 
 static struct node_data prealloc__node_data[MAX_NUMNODES];
 unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES];
+EXPORT_SYMBOL(__node_distances);
 struct node_data *__node_data[MAX_NUMNODES];
 EXPORT_SYMBOL(__node_data);
 
index fa6ebd4bc9e9ae9b28a058650d0f9f87011e4c2e..c3917e251f59393a5138b3d4c557886e4fa45286 100644 (file)
@@ -299,6 +299,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
 
        local_irq_save(flags);
 
+       htw_stop();
        pid = read_c0_entryhi() & ASID_MASK;
        address &= (PAGE_MASK << 1);
        write_c0_entryhi(address | pid);
@@ -346,6 +347,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
                        tlb_write_indexed();
        }
        tlbw_use_hazard();
+       htw_start();
        flush_itlb_vm(vma);
        local_irq_restore(flags);
 }
@@ -422,6 +424,7 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
 
        local_irq_save(flags);
        /* Save old context and create impossible VPN2 value */
+       htw_stop();
        old_ctx = read_c0_entryhi();
        old_pagemask = read_c0_pagemask();
        wired = read_c0_wired();
@@ -443,6 +446,7 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
 
        write_c0_entryhi(old_ctx);
        write_c0_pagemask(old_pagemask);
+       htw_start();
 out:
        local_irq_restore(flags);
        return ret;
index 6854ed5097d2e61bb3f7f3e2937612a5d1058b07..83a1dfd8f0e3c34d02cbe24448f5c5407852f942 100644 (file)
@@ -92,7 +92,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame,
                                /* This marks the end of the previous function,
                                   which means we overran. */
                                break;
-                       stack_size = (unsigned) stack_adjustment;
+                       stack_size = (unsigned long) stack_adjustment;
                } else if (is_ra_save_ins(&ip)) {
                        int ra_slot = ip.i_format.simmediate;
                        if (ra_slot < 0)
index a95c00f5fb9697ed90fa79d44ec887b498f680fc..a304bcc37e4fba137a5a1ee8bc792a50d7258e01 100644 (file)
@@ -107,6 +107,7 @@ static void router_recurse(klrou_t *router_a, klrou_t *router_b, int depth)
 }
 
 unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
+EXPORT_SYMBOL(__node_distances);
 
 static int __init compute_node_distance(nasid_t nasid_a, nasid_t nasid_b)
 {
index 4006964d8e12646761d954b9f73ff0b503e736b6..a5cb070b54bf4ade7cce44e50f763a5223991e83 100644 (file)
@@ -9,6 +9,8 @@
 #include <asm/errno.h>
 #include <asm-generic/uaccess-unaligned.h>
 
+#include <linux/bug.h>
+
 #define VERIFY_READ 0
 #define VERIFY_WRITE 1
 
  * that put_user is the same as __put_user, etc.
  */
 
-extern int __get_kernel_bad(void);
-extern int __get_user_bad(void);
-extern int __put_kernel_bad(void);
-extern int __put_user_bad(void);
-
 static inline long access_ok(int type, const void __user * addr,
                unsigned long size)
 {
@@ -43,8 +40,8 @@ static inline long access_ok(int type, const void __user * addr,
 #define get_user __get_user
 
 #if !defined(CONFIG_64BIT)
-#define LDD_KERNEL(ptr)                __get_kernel_bad();
-#define LDD_USER(ptr)          __get_user_bad();
+#define LDD_KERNEL(ptr)                BUILD_BUG()
+#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"
@@ -94,7 +91,7 @@ struct exception_data {
            case 2: __get_kernel_asm("ldh",ptr); break; \
            case 4: __get_kernel_asm("ldw",ptr); break; \
            case 8: LDD_KERNEL(ptr); break;             \
-           default: __get_kernel_bad(); break;         \
+           default: BUILD_BUG(); break;                \
            }                                           \
        }                                               \
        else {                                          \
@@ -103,7 +100,7 @@ struct exception_data {
            case 2: __get_user_asm("ldh",ptr); break;   \
            case 4: __get_user_asm("ldw",ptr); break;   \
            case 8: LDD_USER(ptr);  break;              \
-           default: __get_user_bad(); break;           \
+           default: BUILD_BUG(); break;                \
            }                                           \
        }                                               \
                                                        \
@@ -136,7 +133,7 @@ struct exception_data {
            case 2: __put_kernel_asm("sth",__x,ptr); break;     \
            case 4: __put_kernel_asm("stw",__x,ptr); break;     \
            case 8: STD_KERNEL(__x,ptr); break;                 \
-           default: __put_kernel_bad(); break;                 \
+           default: BUILD_BUG(); break;                        \
            }                                                   \
        }                                                       \
        else {                                                  \
@@ -145,7 +142,7 @@ struct exception_data {
            case 2: __put_user_asm("sth",__x,ptr); break;       \
            case 4: __put_user_asm("stw",__x,ptr); break;       \
            case 8: STD_USER(__x,ptr); break;                   \
-           default: __put_user_bad(); break;                   \
+           default: BUILD_BUG(); break;                        \
            }                                                   \
        }                                                       \
                                                                \
index 75196b415d3f8f313ec94025847427bf15a28bd6..e0a23c7bdd432adc59f4f4ebefcc4d51f91b05f1 100644 (file)
@@ -1,13 +1,7 @@
 #ifndef __ASM_PARISC_BITSPERLONG_H
 #define __ASM_PARISC_BITSPERLONG_H
 
-/*
- * using CONFIG_* outside of __KERNEL__ is wrong,
- * __LP64__ was also removed from headers, so what
- * is the right approach on parisc?
- *     -arnd
- */
-#if (defined(__KERNEL__) && defined(CONFIG_64BIT)) || defined (__LP64__)
+#if defined(__LP64__)
 #define __BITS_PER_LONG 64
 #define SHIFT_PER_LONG 6
 #else
index fe88f2649418e63c77022ed74ff43b12c1bccda2..342138983914ce8e0f5641622fb4a46bf9034155 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _PARISC_MSGBUF_H
 #define _PARISC_MSGBUF_H
 
+#include <asm/bitsperlong.h>
+
 /* 
  * The msqid64_ds structure for parisc architecture, copied from sparc.
  * Note extra padding because this structure is passed back and forth
 
 struct msqid64_ds {
        struct ipc64_perm msg_perm;
-#ifndef CONFIG_64BIT
+#if __BITS_PER_LONG != 64
        unsigned int   __pad1;
 #endif
        __kernel_time_t msg_stime;      /* last msgsnd time */
-#ifndef CONFIG_64BIT
+#if __BITS_PER_LONG != 64
        unsigned int   __pad2;
 #endif
        __kernel_time_t msg_rtime;      /* last msgrcv time */
-#ifndef CONFIG_64BIT
+#if __BITS_PER_LONG != 64
        unsigned int   __pad3;
 #endif
        __kernel_time_t msg_ctime;      /* last change time */
index 1e59ffd3bd1ee6663acc20e663e4dafe282f4b2b..f01d89e30d735098d682b4cca2a71e79e689d4e8 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _PARISC_SEMBUF_H
 #define _PARISC_SEMBUF_H
 
+#include <asm/bitsperlong.h>
+
 /* 
  * The semid64_ds structure for parisc architecture.
  * Note extra padding because this structure is passed back and forth
 
 struct semid64_ds {
        struct ipc64_perm sem_perm;             /* permissions .. see ipc.h */
-#ifndef CONFIG_64BIT
+#if __BITS_PER_LONG != 64
        unsigned int    __pad1;
 #endif
        __kernel_time_t sem_otime;              /* last semop time */
-#ifndef CONFIG_64BIT
+#if __BITS_PER_LONG != 64
        unsigned int    __pad2;
 #endif
        __kernel_time_t sem_ctime;              /* last change time */
index 0a3eada1863b71e1e859e5bf1536da089a65ffd1..8496c38560c6bd63c1a780acef9f7bcd1d00b475 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _PARISC_SHMBUF_H
 #define _PARISC_SHMBUF_H
 
+#include <asm/bitsperlong.h>
+
 /* 
  * The shmid64_ds structure for parisc architecture.
  * Note extra padding because this structure is passed back and forth
 
 struct shmid64_ds {
        struct ipc64_perm       shm_perm;       /* operation perms */
-#ifndef CONFIG_64BIT
+#if __BITS_PER_LONG != 64
        unsigned int            __pad1;
 #endif
        __kernel_time_t         shm_atime;      /* last attach time */
-#ifndef CONFIG_64BIT
+#if __BITS_PER_LONG != 64
        unsigned int            __pad2;
 #endif
        __kernel_time_t         shm_dtime;      /* last detach time */
-#ifndef CONFIG_64BIT
+#if __BITS_PER_LONG != 64
        unsigned int            __pad3;
 #endif
        __kernel_time_t         shm_ctime;      /* last change time */
-#ifndef CONFIG_64BIT
+#if __BITS_PER_LONG != 64
        unsigned int            __pad4;
 #endif
        size_t                  shm_segsz;      /* size of segment (bytes) */
@@ -36,23 +38,16 @@ struct shmid64_ds {
        unsigned int            __unused2;
 };
 
-#ifdef CONFIG_64BIT
-/* The 'unsigned int' (formerly 'unsigned long') data types below will
- * ensure that a 32-bit app calling shmctl(*,IPC_INFO,*) will work on
- * a wide kernel, but if some of these values are meant to contain pointers
- * they may need to be 'long long' instead. -PB XXX FIXME
- */
-#endif
 struct shminfo64 {
-       unsigned int    shmmax;
-       unsigned int    shmmin;
-       unsigned int    shmmni;
-       unsigned int    shmseg;
-       unsigned int    shmall;
-       unsigned int    __unused1;
-       unsigned int    __unused2;
-       unsigned int    __unused3;
-       unsigned int    __unused4;
+       unsigned long   shmmax;
+       unsigned long   shmmin;
+       unsigned long   shmmni;
+       unsigned long   shmseg;
+       unsigned long   shmall;
+       unsigned long   __unused1;
+       unsigned long   __unused2;
+       unsigned long   __unused3;
+       unsigned long   __unused4;
 };
 
 #endif /* _PARISC_SHMBUF_H */
index 10df7079f4cdf08dec0e26d871e4270d157a50ed..e26043b73f5d8e32280b4bd1cfe087f4c93aa3b9 100644 (file)
@@ -85,7 +85,7 @@
 struct siginfo;
 
 /* Type of a signal handler.  */
-#ifdef CONFIG_64BIT
+#if defined(__LP64__)
 /* function pointers on 64-bit parisc are pointers to little structs and the
  * compiler doesn't support code which changes or tests the address of
  * the function in the little struct.  This is really ugly -PB
index 8667f18be2385d7423da2efac3803671b500740e..5f5c0373de63cb6dc898e9b3a273427a96fbe607 100644 (file)
 #define __NR_seccomp           (__NR_Linux + 338)
 #define __NR_getrandom         (__NR_Linux + 339)
 #define __NR_memfd_create      (__NR_Linux + 340)
+#define __NR_bpf               (__NR_Linux + 341)
 
-#define __NR_Linux_syscalls    (__NR_memfd_create + 1)
+#define __NR_Linux_syscalls    (__NR_bpf + 1)
 
 
 #define __IGNORE_select                /* newselect */
index b563d9c8268b153429a06cfc85924c236d00c688..fe4f0b89bf8fa0ed21d3f5a568dd946a0dd81be0 100644 (file)
        ENTRY_COMP(msgsnd)
        ENTRY_COMP(msgrcv)
        ENTRY_SAME(msgget)              /* 190 */
-       ENTRY_SAME(msgctl)
-       ENTRY_SAME(shmat)
+       ENTRY_COMP(msgctl)
+       ENTRY_COMP(shmat)
        ENTRY_SAME(shmdt)
        ENTRY_SAME(shmget)
-       ENTRY_SAME(shmctl)              /* 195 */
+       ENTRY_COMP(shmctl)              /* 195 */
        ENTRY_SAME(ni_syscall)          /* streams1 */
        ENTRY_SAME(ni_syscall)          /* streams2 */
        ENTRY_SAME(lstat64)
        ENTRY_SAME(epoll_ctl)           /* 225 */
        ENTRY_SAME(epoll_wait)
        ENTRY_SAME(remap_file_pages)
-       ENTRY_SAME(semtimedop)
+       ENTRY_COMP(semtimedop)
        ENTRY_COMP(mq_open)
        ENTRY_SAME(mq_unlink)           /* 230 */
        ENTRY_COMP(mq_timedsend)
        ENTRY_SAME(seccomp)
        ENTRY_SAME(getrandom)
        ENTRY_SAME(memfd_create)        /* 340 */
+       ENTRY_SAME(bpf)
 
        /* Nothing yet */
 
index de40b48b460e83a8aaec5168c8a4a1f025d8dd38..da08ed08815751cec116164e8f6d3e828bda9fd4 100644 (file)
@@ -361,7 +361,7 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev,
        cascade_data->virq = virt_msir;
        msi->cascade_array[irq_index] = cascade_data;
 
-       ret = request_irq(virt_msir, fsl_msi_cascade, 0,
+       ret = request_irq(virt_msir, fsl_msi_cascade, IRQF_NO_THREAD,
                          "fsl-msi-cascade", cascade_data);
        if (ret) {
                dev_err(&dev->dev, "failed to request_irq(%d), ret = %d\n",
index 765c1776ec9fd6e900e8c23f39e55af0bf2b316b..0e69b7e7a439ce90e2f831c173fd67d55af53be0 100644 (file)
@@ -22,7 +22,7 @@
 
 int atomic_add_return(int, atomic_t *);
 int atomic_cmpxchg(atomic_t *, int, int);
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+int atomic_xchg(atomic_t *, int);
 int __atomic_add_unless(atomic_t *, int, int);
 void atomic_set(atomic_t *, int);
 
index 32c29a133f9d4b199f1a6a4476f274fd4c0b9890..d38b52dca216273a147328cc2d0288c20c2eeba6 100644 (file)
 #ifndef __ARCH_SPARC_CMPXCHG__
 #define __ARCH_SPARC_CMPXCHG__
 
-static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)
-{
-       __asm__ __volatile__("swap [%2], %0"
-                            : "=&r" (val)
-                            : "0" (val), "r" (m)
-                            : "memory");
-       return val;
-}
-
+unsigned long __xchg_u32(volatile u32 *m, u32 new);
 void __xchg_called_with_bad_pointer(void);
 
 static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
 {
        switch (size) {
        case 4:
-               return xchg_u32(ptr, x);
+               return __xchg_u32(ptr, x);
        }
        __xchg_called_with_bad_pointer();
        return x;
index a34ad079487e85ea8e3dbc5b314f1235ccf7cc4d..4c7c12d69bea6b78f51efcec0a0b8c0b19372a4d 100644 (file)
@@ -9,9 +9,9 @@ static inline __u16 __arch_swab16p(const __u16 *addr)
 {
        __u16 ret;
 
-       __asm__ __volatile__ ("lduha [%1] %2, %0"
+       __asm__ __volatile__ ("lduha [%2] %3, %0"
                              : "=r" (ret)
-                             : "r" (addr), "i" (ASI_PL));
+                             : "m" (*addr), "r" (addr), "i" (ASI_PL));
        return ret;
 }
 #define __arch_swab16p __arch_swab16p
@@ -20,9 +20,9 @@ static inline __u32 __arch_swab32p(const __u32 *addr)
 {
        __u32 ret;
 
-       __asm__ __volatile__ ("lduwa [%1] %2, %0"
+       __asm__ __volatile__ ("lduwa [%2] %3, %0"
                              : "=r" (ret)
-                             : "r" (addr), "i" (ASI_PL));
+                             : "m" (*addr), "r" (addr), "i" (ASI_PL));
        return ret;
 }
 #define __arch_swab32p __arch_swab32p
@@ -31,9 +31,9 @@ static inline __u64 __arch_swab64p(const __u64 *addr)
 {
        __u64 ret;
 
-       __asm__ __volatile__ ("ldxa [%1] %2, %0"
+       __asm__ __volatile__ ("ldxa [%2] %3, %0"
                              : "=r" (ret)
-                             : "r" (addr), "i" (ASI_PL));
+                             : "m" (*addr), "r" (addr), "i" (ASI_PL));
        return ret;
 }
 #define __arch_swab64p __arch_swab64p
index 8f76f23dac38ec66b0afea55a5311e612f2459f0..f9c6813c132d606c2a2d138342d4ed9941165f47 100644 (file)
@@ -581,7 +581,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
 {
        unsigned long csr_reg, csr, csr_error_bits;
        irqreturn_t ret = IRQ_NONE;
-       u16 stat;
+       u32 stat;
 
        csr_reg = pbm->pbm_regs + SCHIZO_PCI_CTRL;
        csr = upa_readq(csr_reg);
@@ -617,7 +617,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
                               pbm->name);
                ret = IRQ_HANDLED;
        }
-       pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat);
+       pbm->pci_ops->read(pbm->pci_bus, 0, PCI_STATUS, 2, &stat);
        if (stat & (PCI_STATUS_PARITY |
                    PCI_STATUS_SIG_TARGET_ABORT |
                    PCI_STATUS_REC_TARGET_ABORT |
@@ -625,7 +625,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
                    PCI_STATUS_SIG_SYSTEM_ERROR)) {
                printk("%s: PCI bus error, PCI_STATUS[%04x]\n",
                       pbm->name, stat);
-               pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff);
+               pbm->pci_ops->write(pbm->pci_bus, 0, PCI_STATUS, 2, 0xffff);
                ret = IRQ_HANDLED;
        }
        return ret;
index 302c476413d5c5eaeb29fd5cedd529f86de2d30f..da6f1a7fc4db4713425d1927af185cb797b4c1fc 100644 (file)
@@ -816,13 +816,17 @@ void arch_send_call_function_single_ipi(int cpu)
 void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
+       irq_enter();
        generic_smp_call_function_interrupt();
+       irq_exit();
 }
 
 void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
+       irq_enter();
        generic_smp_call_function_single_interrupt();
+       irq_exit();
 }
 
 static void tsb_sync(void *info)
index a7c418ac26afbb46500ff812d939a8aefff27945..71cd65ab200c8739634447a995fb5e069cac3717 100644 (file)
@@ -45,6 +45,19 @@ ATOMIC_OP(add, +=)
 
 #undef ATOMIC_OP
 
+int atomic_xchg(atomic_t *v, int new)
+{
+       int ret;
+       unsigned long flags;
+
+       spin_lock_irqsave(ATOMIC_HASH(v), flags);
+       ret = v->counter;
+       v->counter = new;
+       spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
+       return ret;
+}
+EXPORT_SYMBOL(atomic_xchg);
+
 int atomic_cmpxchg(atomic_t *v, int old, int new)
 {
        int ret;
@@ -137,3 +150,17 @@ unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new)
        return (unsigned long)prev;
 }
 EXPORT_SYMBOL(__cmpxchg_u32);
+
+unsigned long __xchg_u32(volatile u32 *ptr, u32 new)
+{
+       unsigned long flags;
+       u32 prev;
+
+       spin_lock_irqsave(ATOMIC_HASH(ptr), flags);
+       prev = *ptr;
+       *ptr = new;
+       spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);
+
+       return (unsigned long)prev;
+}
+EXPORT_SYMBOL(__xchg_u32);
index ded8a6774ac99a6b9fd6708e440f66bc2f6e7433..41a503c158626a870906de36516765869c40ae1d 100644 (file)
@@ -144,7 +144,7 @@ config INSTRUCTION_DECODER
 
 config PERF_EVENTS_INTEL_UNCORE
        def_bool y
-       depends on PERF_EVENTS && SUP_SUP_INTEL && PCI
+       depends on PERF_EVENTS && CPU_SUP_INTEL && PCI
 
 config OUTPUT_FORMAT
        string
index 704f58aa79cd4853f91663512232a59b3441b4c8..be1e07d4b596e4bc5a4e17e819f92ae9bebcb57a 100644 (file)
@@ -76,8 +76,10 @@ suffix-$(CONFIG_KERNEL_XZ)   := xz
 suffix-$(CONFIG_KERNEL_LZO)    := lzo
 suffix-$(CONFIG_KERNEL_LZ4)    := lz4
 
+RUN_SIZE = $(shell objdump -h vmlinux | \
+            perl $(srctree)/arch/x86/tools/calc_run_size.pl)
 quiet_cmd_mkpiggy = MKPIGGY $@
-      cmd_mkpiggy = $(obj)/mkpiggy $< > $@ || ( rm -f $@ ; false )
+      cmd_mkpiggy = $(obj)/mkpiggy $< $(RUN_SIZE) > $@ || ( rm -f $@ ; false )
 
 targets += piggy.S
 $(obj)/piggy.S: $(obj)/vmlinux.bin.$(suffix-y) $(obj)/mkpiggy FORCE
index cbed1407a5cdb7ead8fa0cae90d2e7902133aaa7..1d7fbbcc196d6f8b661545130972453f109e27d7 100644 (file)
@@ -207,7 +207,8 @@ relocated:
  * Do the decompression, and jump to the new kernel..
  */
                                /* push arguments for decompress_kernel: */
-       pushl   $z_output_len   /* decompressed length */
+       pushl   $z_run_size     /* size of kernel with .bss and .brk */
+       pushl   $z_output_len   /* decompressed length, end of relocs */
        leal    z_extract_offset_negative(%ebx), %ebp
        pushl   %ebp            /* output address */
        pushl   $z_input_len    /* input_len */
@@ -217,7 +218,7 @@ relocated:
        pushl   %eax            /* heap area */
        pushl   %esi            /* real mode pointer */
        call    decompress_kernel /* returns kernel location in %eax */
-       addl    $24, %esp
+       addl    $28, %esp
 
 /*
  * Jump to the decompressed kernel.
index 2884e0c3e8a5880411ce63955b01c103e6eabd00..6b1766c6c08205f3bda8a527dff88097b48e77e3 100644 (file)
@@ -402,13 +402,16 @@ relocated:
  * Do the decompression, and jump to the new kernel..
  */
        pushq   %rsi                    /* Save the real mode argument */
+       movq    $z_run_size, %r9        /* size of kernel with .bss and .brk */
+       pushq   %r9
        movq    %rsi, %rdi              /* real mode address */
        leaq    boot_heap(%rip), %rsi   /* malloc area for uncompression */
        leaq    input_data(%rip), %rdx  /* input_data */
        movl    $z_input_len, %ecx      /* input_len */
        movq    %rbp, %r8               /* output target address */
-       movq    $z_output_len, %r9      /* decompressed length */
+       movq    $z_output_len, %r9      /* decompressed length, end of relocs */
        call    decompress_kernel       /* returns kernel location in %rax */
+       popq    %r9
        popq    %rsi
 
 /*
index 57ab74df7eeaa3eef4954b89f36d20b4c528afd7..30dd59a9f0b4acfd6a70587f6f4e247adbbeb8fd 100644 (file)
@@ -358,7 +358,8 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,
                                  unsigned char *input_data,
                                  unsigned long input_len,
                                  unsigned char *output,
-                                 unsigned long output_len)
+                                 unsigned long output_len,
+                                 unsigned long run_size)
 {
        real_mode = rmode;
 
@@ -381,8 +382,14 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,
        free_mem_ptr     = heap;        /* Heap */
        free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
 
-       output = choose_kernel_location(input_data, input_len,
-                                       output, output_len);
+       /*
+        * The memory hole needed for the kernel is the larger of either
+        * the entire decompressed kernel plus relocation table, or the
+        * entire decompressed kernel plus .bss and .brk sections.
+        */
+       output = choose_kernel_location(input_data, input_len, output,
+                                       output_len > run_size ? output_len
+                                                             : run_size);
 
        /* Validate memory location choices. */
        if ((unsigned long)output & (MIN_KERNEL_ALIGN - 1))
index b669ab65bf6cf2e6973d6dc50cb693a1a8568324..d8222f213182f120c6f1d4c43e9ac477b2c2ca24 100644 (file)
@@ -36,11 +36,13 @@ int main(int argc, char *argv[])
        uint32_t olen;
        long ilen;
        unsigned long offs;
+       unsigned long run_size;
        FILE *f = NULL;
        int retval = 1;
 
-       if (argc < 2) {
-               fprintf(stderr, "Usage: %s compressed_file\n", argv[0]);
+       if (argc < 3) {
+               fprintf(stderr, "Usage: %s compressed_file run_size\n",
+                               argv[0]);
                goto bail;
        }
 
@@ -74,6 +76,7 @@ int main(int argc, char *argv[])
        offs += olen >> 12;     /* Add 8 bytes for each 32K block */
        offs += 64*1024 + 128;  /* Add 64K + 128 bytes slack */
        offs = (offs+4095) & ~4095; /* Round to a 4K boundary */
+       run_size = atoi(argv[2]);
 
        printf(".section \".rodata..compressed\",\"a\",@progbits\n");
        printf(".globl z_input_len\n");
@@ -85,6 +88,8 @@ int main(int argc, char *argv[])
        /* z_extract_offset_negative allows simplification of head_32.S */
        printf(".globl z_extract_offset_negative\n");
        printf("z_extract_offset_negative = -0x%lx\n", offs);
+       printf(".globl z_run_size\n");
+       printf("z_run_size = %lu\n", run_size);
 
        printf(".globl input_data, input_data_end\n");
        printf("input_data:\n");
index 8cd27e08e23c47cec2f736b6b674b921554eb680..8cd1cc3bc8356ffef29e349f08b3de43aeb79506 100644 (file)
@@ -150,6 +150,7 @@ static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 }
 
 void cpu_disable_common(void);
+void cpu_die_common(unsigned int cpu);
 void native_smp_prepare_boot_cpu(void);
 void native_smp_prepare_cpus(unsigned int max_cpus);
 void native_smp_cpus_done(unsigned int max_cpus);
index 4b4f78c9ba1902ed87127738052135ed54071088..cfa9b5b2c27a0b72d794f4aa048deaa404e8baef 100644 (file)
@@ -146,6 +146,8 @@ EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
 
 static int __init x86_xsave_setup(char *s)
 {
+       if (strlen(s))
+               return 0;
        setup_clear_cpu_cap(X86_FEATURE_XSAVE);
        setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
        setup_clear_cpu_cap(X86_FEATURE_XSAVES);
index 7aa1acc79789aa9c38de7509dcb018132a50d901..06674473b0e66736d0a64c235c1e9fe7e774deb9 100644 (file)
@@ -108,12 +108,13 @@ static size_t compute_container_size(u8 *data, u32 total_size)
  * load_microcode_amd() to save equivalent cpu table and microcode patches in
  * kernel heap memory.
  */
-static void apply_ucode_in_initrd(void *ucode, size_t size)
+static void apply_ucode_in_initrd(void *ucode, size_t size, bool save_patch)
 {
        struct equiv_cpu_entry *eq;
        size_t *cont_sz;
        u32 *header;
        u8  *data, **cont;
+       u8 (*patch)[PATCH_MAX_SIZE];
        u16 eq_id = 0;
        int offset, left;
        u32 rev, eax, ebx, ecx, edx;
@@ -123,10 +124,12 @@ static void apply_ucode_in_initrd(void *ucode, size_t size)
        new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
        cont_sz = (size_t *)__pa_nodebug(&container_size);
        cont    = (u8 **)__pa_nodebug(&container);
+       patch   = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch);
 #else
        new_rev = &ucode_new_rev;
        cont_sz = &container_size;
        cont    = &container;
+       patch   = &amd_ucode_patch;
 #endif
 
        data   = ucode;
@@ -213,9 +216,9 @@ static void apply_ucode_in_initrd(void *ucode, size_t size)
                                rev = mc->hdr.patch_id;
                                *new_rev = rev;
 
-                               /* save ucode patch */
-                               memcpy(amd_ucode_patch, mc,
-                                      min_t(u32, header[1], PATCH_MAX_SIZE));
+                               if (save_patch)
+                                       memcpy(patch, mc,
+                                              min_t(u32, header[1], PATCH_MAX_SIZE));
                        }
                }
 
@@ -246,7 +249,7 @@ void __init load_ucode_amd_bsp(void)
        *data = cp.data;
        *size = cp.size;
 
-       apply_ucode_in_initrd(cp.data, cp.size);
+       apply_ucode_in_initrd(cp.data, cp.size, true);
 }
 
 #ifdef CONFIG_X86_32
@@ -263,7 +266,7 @@ void load_ucode_amd_ap(void)
        size_t *usize;
        void **ucode;
 
-       mc = (struct microcode_amd *)__pa(amd_ucode_patch);
+       mc = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch);
        if (mc->hdr.patch_id && mc->hdr.processor_rev_id) {
                __apply_microcode_amd(mc);
                return;
@@ -275,7 +278,7 @@ void load_ucode_amd_ap(void)
        if (!*ucode || !*usize)
                return;
 
-       apply_ucode_in_initrd(*ucode, *usize);
+       apply_ucode_in_initrd(*ucode, *usize, false);
 }
 
 static void __init collect_cpu_sig_on_bsp(void *arg)
@@ -339,7 +342,7 @@ void load_ucode_amd_ap(void)
                 * AP has a different equivalence ID than BSP, looks like
                 * mixed-steppings silicon so go through the ucode blob anew.
                 */
-               apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size);
+               apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size, false);
        }
 }
 #endif
@@ -347,7 +350,9 @@ void load_ucode_amd_ap(void)
 int __init save_microcode_in_initrd_amd(void)
 {
        unsigned long cont;
+       int retval = 0;
        enum ucode_state ret;
+       u8 *cont_va;
        u32 eax;
 
        if (!container)
@@ -355,13 +360,15 @@ int __init save_microcode_in_initrd_amd(void)
 
 #ifdef CONFIG_X86_32
        get_bsp_sig();
-       cont = (unsigned long)container;
+       cont    = (unsigned long)container;
+       cont_va = __va(container);
 #else
        /*
         * We need the physical address of the container for both bitness since
         * boot_params.hdr.ramdisk_image is a physical address.
         */
-       cont = __pa(container);
+       cont    = __pa(container);
+       cont_va = container;
 #endif
 
        /*
@@ -372,6 +379,8 @@ int __init save_microcode_in_initrd_amd(void)
        if (relocated_ramdisk)
                container = (u8 *)(__va(relocated_ramdisk) +
                             (cont - boot_params.hdr.ramdisk_image));
+       else
+               container = cont_va;
 
        if (ucode_new_rev)
                pr_info("microcode: updated early to new patch_level=0x%08x\n",
@@ -382,7 +391,7 @@ int __init save_microcode_in_initrd_amd(void)
 
        ret = load_microcode_amd(eax, container, container_size);
        if (ret != UCODE_OK)
-               return -EINVAL;
+               retval = -EINVAL;
 
        /*
         * This will be freed any msec now, stash patches for the current
@@ -391,5 +400,5 @@ int __init save_microcode_in_initrd_amd(void)
        container = NULL;
        container_size = 0;
 
-       return 0;
+       return retval;
 }
index dd9d6190b08dfae5fdaee714ab5f556040af516e..2ce9051174e608381c6a91171e7e3d0d5a6a44ca 100644 (file)
@@ -465,6 +465,14 @@ static void mc_bp_resume(void)
 
        if (uci->valid && uci->mc)
                microcode_ops->apply_microcode(cpu);
+       else if (!uci->mc)
+               /*
+                * We might resume and not have applied late microcode but still
+                * have a newer patch stashed from the early loader. We don't
+                * have it in uci->mc so we have to load it the same way we're
+                * applying patches early on the APs.
+                */
+               load_ucode_ap();
 }
 
 static struct syscore_ops mc_syscore_ops = {
index 5f28a64e71ea9e834bb835ed5fe4d8e7adaf472f..2c017f242a78144ba18499f52aa5ca0c069aa880 100644 (file)
@@ -124,7 +124,7 @@ void __init load_ucode_bsp(void)
 static bool check_loader_disabled_ap(void)
 {
 #ifdef CONFIG_X86_32
-       return __pa_nodebug(dis_ucode_ldr);
+       return *((bool *)__pa_nodebug(&dis_ucode_ldr));
 #else
        return dis_ucode_ldr;
 #endif
index adf138eac85c3384550e2f14ec5ac3377ed87000..f9ed429d6e4f83a00789ba8e5b81b704905c9764 100644 (file)
@@ -486,14 +486,17 @@ static struct attribute_group snbep_uncore_qpi_format_group = {
        .attrs = snbep_uncore_qpi_formats_attr,
 };
 
-#define SNBEP_UNCORE_MSR_OPS_COMMON_INIT()                     \
-       .init_box       = snbep_uncore_msr_init_box,            \
+#define __SNBEP_UNCORE_MSR_OPS_COMMON_INIT()                   \
        .disable_box    = snbep_uncore_msr_disable_box,         \
        .enable_box     = snbep_uncore_msr_enable_box,          \
        .disable_event  = snbep_uncore_msr_disable_event,       \
        .enable_event   = snbep_uncore_msr_enable_event,        \
        .read_counter   = uncore_msr_read_counter
 
+#define SNBEP_UNCORE_MSR_OPS_COMMON_INIT()                     \
+       __SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),                   \
+       .init_box       = snbep_uncore_msr_init_box             \
+
 static struct intel_uncore_ops snbep_uncore_msr_ops = {
        SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
 };
@@ -1919,6 +1922,30 @@ static struct intel_uncore_type hswep_uncore_cbox = {
        .format_group           = &hswep_uncore_cbox_format_group,
 };
 
+/*
+ * Write SBOX Initialization register bit by bit to avoid spurious #GPs
+ */
+static void hswep_uncore_sbox_msr_init_box(struct intel_uncore_box *box)
+{
+       unsigned msr = uncore_msr_box_ctl(box);
+
+       if (msr) {
+               u64 init = SNBEP_PMON_BOX_CTL_INT;
+               u64 flags = 0;
+               int i;
+
+               for_each_set_bit(i, (unsigned long *)&init, 64) {
+                       flags |= (1ULL << i);
+                       wrmsrl(msr, flags);
+               }
+       }
+}
+
+static struct intel_uncore_ops hswep_uncore_sbox_msr_ops = {
+       __SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
+       .init_box               = hswep_uncore_sbox_msr_init_box
+};
+
 static struct attribute *hswep_uncore_sbox_formats_attr[] = {
        &format_attr_event.attr,
        &format_attr_umask.attr,
@@ -1944,7 +1971,7 @@ static struct intel_uncore_type hswep_uncore_sbox = {
        .event_mask             = HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
        .box_ctl                = HSWEP_S0_MSR_PMON_BOX_CTL,
        .msr_offset             = HSWEP_SBOX_MSR_OFFSET,
-       .ops                    = &snbep_uncore_msr_ops,
+       .ops                    = &hswep_uncore_sbox_msr_ops,
        .format_group           = &hswep_uncore_sbox_format_group,
 };
 
@@ -2025,13 +2052,27 @@ static struct intel_uncore_type hswep_uncore_imc = {
        SNBEP_UNCORE_PCI_COMMON_INIT(),
 };
 
+static unsigned hswep_uncore_irp_ctrs[] = {0xa0, 0xa8, 0xb0, 0xb8};
+
+static u64 hswep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event)
+{
+       struct pci_dev *pdev = box->pci_dev;
+       struct hw_perf_event *hwc = &event->hw;
+       u64 count = 0;
+
+       pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx], (u32 *)&count);
+       pci_read_config_dword(pdev, hswep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1);
+
+       return count;
+}
+
 static struct intel_uncore_ops hswep_uncore_irp_ops = {
        .init_box       = snbep_uncore_pci_init_box,
        .disable_box    = snbep_uncore_pci_disable_box,
        .enable_box     = snbep_uncore_pci_enable_box,
        .disable_event  = ivbep_uncore_irp_disable_event,
        .enable_event   = ivbep_uncore_irp_enable_event,
-       .read_counter   = ivbep_uncore_irp_read_counter,
+       .read_counter   = hswep_uncore_irp_read_counter,
 };
 
 static struct intel_uncore_type hswep_uncore_irp = {
index 749b0e423419fee7b97698e725dc6d665c1aa828..e510618b2e91a7969bb8cf6c74a35f59e4bf1bea 100644 (file)
@@ -1484,7 +1484,7 @@ unsigned long syscall_trace_enter_phase1(struct pt_regs *regs, u32 arch)
         */
        if (work & _TIF_NOHZ) {
                user_exit();
-               work &= ~TIF_NOHZ;
+               work &= ~_TIF_NOHZ;
        }
 
 #ifdef CONFIG_SECCOMP
index 4d2128ac70bdab90afe6a753f090996f30f72ff1..668d8f2a8781ea11fab5110315a946171b0e274d 100644 (file)
@@ -1303,10 +1303,14 @@ static void __ref remove_cpu_from_maps(int cpu)
        numa_remove_cpu(cpu);
 }
 
+static DEFINE_PER_CPU(struct completion, die_complete);
+
 void cpu_disable_common(void)
 {
        int cpu = smp_processor_id();
 
+       init_completion(&per_cpu(die_complete, smp_processor_id()));
+
        remove_siblinginfo(cpu);
 
        /* It's now safe to remove this processor from the online map */
@@ -1316,8 +1320,6 @@ void cpu_disable_common(void)
        fixup_irqs();
 }
 
-static DEFINE_PER_CPU(struct completion, die_complete);
-
 int native_cpu_disable(void)
 {
        int ret;
@@ -1327,16 +1329,21 @@ int native_cpu_disable(void)
                return ret;
 
        clear_local_APIC();
-       init_completion(&per_cpu(die_complete, smp_processor_id()));
        cpu_disable_common();
 
        return 0;
 }
 
+void cpu_die_common(unsigned int cpu)
+{
+       wait_for_completion_timeout(&per_cpu(die_complete, cpu), HZ);
+}
+
 void native_cpu_die(unsigned int cpu)
 {
        /* We don't do anything here: idle task is faking death itself. */
-       wait_for_completion_timeout(&per_cpu(die_complete, cpu), HZ);
+
+       cpu_die_common(cpu);
 
        /* They ack this in play_dead() by setting CPU_DEAD */
        if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
index 7609e0e421ece96f6671cc7d2310e0c59402ac1b..1318f75d56e4f072885276a18ca00363f074fcd4 100644 (file)
@@ -41,9 +41,8 @@ csum_partial_copy_from_user(const void __user *src, void *dst,
                while (((unsigned long)src & 6) && len >= 2) {
                        __u16 val16;
 
-                       *errp = __get_user(val16, (const __u16 __user *)src);
-                       if (*errp)
-                               return isum;
+                       if (__get_user(val16, (const __u16 __user *)src))
+                               goto out_err;
 
                        *(__u16 *)dst = val16;
                        isum = (__force __wsum)add32_with_carry(
index 4cb8763868fc20add0018a26df9752f1cd03937d..4e5dfec750fc9296e726a213b8e097f4f885fb70 100644 (file)
@@ -1123,7 +1123,7 @@ void mark_rodata_ro(void)
        unsigned long end = (unsigned long) &__end_rodata_hpage_align;
        unsigned long text_end = PFN_ALIGN(&__stop___ex_table);
        unsigned long rodata_end = PFN_ALIGN(&__end_rodata);
-       unsigned long all_end = PFN_ALIGN(&_end);
+       unsigned long all_end;
 
        printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
               (end - start) >> 10);
@@ -1134,7 +1134,16 @@ void mark_rodata_ro(void)
        /*
         * The rodata/data/bss/brk section (but not the kernel text!)
         * should also be not-executable.
+        *
+        * We align all_end to PMD_SIZE because the existing mapping
+        * is a full PMD. If we would align _brk_end to PAGE_SIZE we
+        * split the PMD and the reminder between _brk_end and the end
+        * of the PMD will remain mapped executable.
+        *
+        * Any PMD which was setup after the one which covers _brk_end
+        * has been zapped already via cleanup_highmem().
         */
+       all_end = roundup((unsigned long)_brk_end, PMD_SIZE);
        set_memory_nx(rodata_start, (all_end - rodata_start) >> PAGE_SHIFT);
 
        rodata_test();
diff --git a/arch/x86/tools/calc_run_size.pl b/arch/x86/tools/calc_run_size.pl
new file mode 100644 (file)
index 0000000..23210ba
--- /dev/null
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+#
+# Calculate the amount of space needed to run the kernel, including room for
+# the .bss and .brk sections.
+#
+# Usage:
+# objdump -h a.out | perl calc_run_size.pl
+use strict;
+
+my $mem_size = 0;
+my $file_offset = 0;
+
+my $sections=" *[0-9]+ \.(?:bss|brk) +";
+while (<>) {
+       if (/^$sections([0-9a-f]+) +(?:[0-9a-f]+ +){2}([0-9a-f]+)/) {
+               my $size = hex($1);
+               my $offset = hex($2);
+               $mem_size += $size;
+               if ($file_offset == 0) {
+                       $file_offset = $offset;
+               } elsif ($file_offset != $offset) {
+                       # BFD linker shows the same file offset in ELF.
+                       # Gold linker shows them as consecutive.
+                       next if ($file_offset + $mem_size == $offset + $size);
+
+                       printf STDERR "file_offset: 0x%lx\n", $file_offset;
+                       printf STDERR "mem_size: 0x%lx\n", $mem_size;
+                       printf STDERR "offset: 0x%lx\n", $offset;
+                       printf STDERR "size: 0x%lx\n", $size;
+
+                       die ".bss and .brk are non-contiguous\n";
+               }
+       }
+}
+
+if ($file_offset == 0) {
+       die "Never found .bss or .brk file offset\n";
+}
+printf("%d\n", $mem_size + $file_offset);
index 8650cdb53209d0f298fa219ac617454cea0fa087..4c071aeb8417bb419a45632c7d9f9a5c96bf3e76 100644 (file)
@@ -510,6 +510,9 @@ static void xen_cpu_die(unsigned int cpu)
                current->state = TASK_UNINTERRUPTIBLE;
                schedule_timeout(HZ/10);
        }
+
+       cpu_die_common(cpu);
+
        xen_smp_intr_free(cpu);
        xen_uninit_lock_cpu(cpu);
        xen_teardown_timer(cpu);
index b3ac40aef46b317c5a432a92ba9b40c8e1942504..89b97b5e0881853054c0807c5607c20d91d90762 100644 (file)
@@ -97,19 +97,22 @@ void blk_recalc_rq_segments(struct request *rq)
 
 void blk_recount_segments(struct request_queue *q, struct bio *bio)
 {
-       bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE,
-                       &q->queue_flags);
-       bool merge_not_need = bio->bi_vcnt < queue_max_segments(q);
+       unsigned short seg_cnt;
+
+       /* estimate segment number by bi_vcnt for non-cloned bio */
+       if (bio_flagged(bio, BIO_CLONED))
+               seg_cnt = bio_segments(bio);
+       else
+               seg_cnt = bio->bi_vcnt;
 
-       if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) &&
-                       merge_not_need)
-               bio->bi_phys_segments = bio->bi_vcnt;
+       if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags) &&
+                       (seg_cnt < queue_max_segments(q)))
+               bio->bi_phys_segments = seg_cnt;
        else {
                struct bio *nxt = bio->bi_next;
 
                bio->bi_next = NULL;
-               bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio,
-                               no_sg_merge && merge_not_need);
+               bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, false);
                bio->bi_next = nxt;
        }
 
index 68929bad9a6a4048151f485cc1e44db2d655fc0f..1d016fc9a8b640c54ce7e06e9f1ce1f293b694e6 100644 (file)
@@ -107,11 +107,7 @@ static void blk_mq_usage_counter_release(struct percpu_ref *ref)
        wake_up_all(&q->mq_freeze_wq);
 }
 
-/*
- * Guarantee no request is in use, so we can change any data structure of
- * the queue afterward.
- */
-void blk_mq_freeze_queue(struct request_queue *q)
+static void blk_mq_freeze_queue_start(struct request_queue *q)
 {
        bool freeze;
 
@@ -123,9 +119,23 @@ void blk_mq_freeze_queue(struct request_queue *q)
                percpu_ref_kill(&q->mq_usage_counter);
                blk_mq_run_queues(q, false);
        }
+}
+
+static void blk_mq_freeze_queue_wait(struct request_queue *q)
+{
        wait_event(q->mq_freeze_wq, percpu_ref_is_zero(&q->mq_usage_counter));
 }
 
+/*
+ * Guarantee no request is in use, so we can change any data structure of
+ * the queue afterward.
+ */
+void blk_mq_freeze_queue(struct request_queue *q)
+{
+       blk_mq_freeze_queue_start(q);
+       blk_mq_freeze_queue_wait(q);
+}
+
 static void blk_mq_unfreeze_queue(struct request_queue *q)
 {
        bool wake;
@@ -1921,7 +1931,7 @@ void blk_mq_free_queue(struct request_queue *q)
 /* Basically redo blk_mq_init_queue with queue frozen */
 static void blk_mq_queue_reinit(struct request_queue *q)
 {
-       blk_mq_freeze_queue(q);
+       WARN_ON_ONCE(!q->mq_freeze_depth);
 
        blk_mq_sysfs_unregister(q);
 
@@ -1936,8 +1946,6 @@ static void blk_mq_queue_reinit(struct request_queue *q)
        blk_mq_map_swqueue(q);
 
        blk_mq_sysfs_register(q);
-
-       blk_mq_unfreeze_queue(q);
 }
 
 static int blk_mq_queue_reinit_notify(struct notifier_block *nb,
@@ -1956,8 +1964,25 @@ static int blk_mq_queue_reinit_notify(struct notifier_block *nb,
                return NOTIFY_OK;
 
        mutex_lock(&all_q_mutex);
+
+       /*
+        * We need to freeze and reinit all existing queues.  Freezing
+        * involves synchronous wait for an RCU grace period and doing it
+        * one by one may take a long time.  Start freezing all queues in
+        * one swoop and then wait for the completions so that freezing can
+        * take place in parallel.
+        */
+       list_for_each_entry(q, &all_q_list, all_q_node)
+               blk_mq_freeze_queue_start(q);
+       list_for_each_entry(q, &all_q_list, all_q_node)
+               blk_mq_freeze_queue_wait(q);
+
        list_for_each_entry(q, &all_q_list, all_q_node)
                blk_mq_queue_reinit(q);
+
+       list_for_each_entry(q, &all_q_list, all_q_node)
+               blk_mq_unfreeze_queue(q);
+
        mutex_unlock(&all_q_mutex);
        return NOTIFY_OK;
 }
index e50170ca7c33f446acc16e29a0d0097828919c30..31666c92b46af29919f42ea3e1093caed7127d71 100644 (file)
@@ -157,14 +157,16 @@ out:
 
 int ioprio_best(unsigned short aprio, unsigned short bprio)
 {
-       unsigned short aclass = IOPRIO_PRIO_CLASS(aprio);
-       unsigned short bclass = IOPRIO_PRIO_CLASS(bprio);
+       unsigned short aclass;
+       unsigned short bclass;
 
-       if (aclass == IOPRIO_CLASS_NONE)
-               aclass = IOPRIO_CLASS_BE;
-       if (bclass == IOPRIO_CLASS_NONE)
-               bclass = IOPRIO_CLASS_BE;
+       if (!ioprio_valid(aprio))
+               aprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, IOPRIO_NORM);
+       if (!ioprio_valid(bprio))
+               bprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, IOPRIO_NORM);
 
+       aclass = IOPRIO_PRIO_CLASS(aprio);
+       bclass = IOPRIO_PRIO_CLASS(bprio);
        if (aclass == bclass)
                return min(aprio, bprio);
        if (aclass > bclass)
index 1e053d911240b577df324912bb68af13e6174bcc..b0c2a616c8f9b859191c075526c473ea1df796bc 100644 (file)
@@ -458,7 +458,7 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
        rq = blk_get_request(q, in_len ? WRITE : READ, __GFP_WAIT);
        if (IS_ERR(rq)) {
                err = PTR_ERR(rq);
-               goto error;
+               goto error_free_buffer;
        }
        blk_rq_set_block_pc(rq);
 
@@ -531,9 +531,11 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
        }
        
 error:
+       blk_put_request(rq);
+
+error_free_buffer:
        kfree(buffer);
-       if (rq)
-               blk_put_request(rq);
+
        return err;
 }
 EXPORT_SYMBOL_GPL(sg_scsi_ioctl);
index ed122e17636e32298129a8e28429ef86cb27a4fa..7556e7c4a055cd0c2dad68fa11a3f8746e6ab16e 100644 (file)
@@ -290,6 +290,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
                    DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3446"),
                },
        },
+       {
+       .callback = dmi_disable_osi_win8,
+       .ident = "Dell Vostro 3546",
+       .matches = {
+                   DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                   DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3546"),
+               },
+       },
 
        /*
         * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
index 143ec6ea1468109a745bce176b2f15d3aaaced19..7db19316076659b493ab1d1c9a295dc88450381d 100644 (file)
@@ -878,7 +878,7 @@ int acpi_dev_suspend_late(struct device *dev)
                return 0;
 
        target_state = acpi_target_system_state();
-       wakeup = device_may_wakeup(dev);
+       wakeup = device_may_wakeup(dev) && acpi_device_can_wakeup(adev);
        error = acpi_device_wakeup(adev, target_state, wakeup);
        if (wakeup && error)
                return error;
index 5f039f1910677ff45d59cb4f7c0812f84f1dac23..e45f83789809a29a722448c589bcc6b5c60f0303 100644 (file)
@@ -60,6 +60,7 @@ enum board_ids {
        /* board IDs by feature in alphabetical order */
        board_ahci,
        board_ahci_ign_iferr,
+       board_ahci_nomsi,
        board_ahci_noncq,
        board_ahci_nosntf,
        board_ahci_yes_fbs,
@@ -121,6 +122,13 @@ static const struct ata_port_info ahci_port_info[] = {
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
+       [board_ahci_nomsi] = {
+               AHCI_HFLAGS     (AHCI_HFLAG_NO_MSI),
+               .flags          = AHCI_FLAG_COMMON,
+               .pio_mask       = ATA_PIO4,
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &ahci_ops,
+       },
        [board_ahci_noncq] = {
                AHCI_HFLAGS     (AHCI_HFLAG_NO_NCQ),
                .flags          = AHCI_FLAG_COMMON,
@@ -313,6 +321,11 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */
        { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
        { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */
+       { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */
+       { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */
+       { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
+       { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
+       { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
 
        /* JMicron 360/1/3/5/6, match class to avoid IDE function */
        { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -475,10 +488,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci },   /* ASM1062 */
 
        /*
-        * Samsung SSDs found on some macbooks.  NCQ times out.
-        * https://bugzilla.kernel.org/show_bug.cgi?id=60731
+        * Samsung SSDs found on some macbooks.  NCQ times out if MSI is
+        * enabled.  https://bugzilla.kernel.org/show_bug.cgi?id=60731
         */
-       { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_noncq },
+       { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_nomsi },
 
        /* Enmotus */
        { PCI_DEVICE(0x1c44, 0x8000), board_ahci },
@@ -514,12 +527,9 @@ MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)");
 static void ahci_pci_save_initial_config(struct pci_dev *pdev,
                                         struct ahci_host_priv *hpriv)
 {
-       unsigned int force_port_map = 0;
-       unsigned int mask_port_map = 0;
-
        if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) {
                dev_info(&pdev->dev, "JMB361 has only one port\n");
-               force_port_map = 1;
+               hpriv->force_port_map = 1;
        }
 
        /*
@@ -529,9 +539,9 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
         */
        if (hpriv->flags & AHCI_HFLAG_MV_PATA) {
                if (pdev->device == 0x6121)
-                       mask_port_map = 0x3;
+                       hpriv->mask_port_map = 0x3;
                else
-                       mask_port_map = 0xf;
+                       hpriv->mask_port_map = 0xf;
                dev_info(&pdev->dev,
                          "Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n");
        }
index 5eb61c9e63da95cbd24a54ee0604262288c8a9f6..97683e45ab043be5045ae22945a5520e845cfe4f 100644 (file)
@@ -1778,16 +1778,15 @@ static void ahci_handle_port_interrupt(struct ata_port *ap,
        }
 }
 
-static void ahci_update_intr_status(struct ata_port *ap)
+static void ahci_port_intr(struct ata_port *ap)
 {
        void __iomem *port_mmio = ahci_port_base(ap);
-       struct ahci_port_priv *pp = ap->private_data;
        u32 status;
 
        status = readl(port_mmio + PORT_IRQ_STAT);
        writel(status, port_mmio + PORT_IRQ_STAT);
 
-       atomic_or(status, &pp->intr_status);
+       ahci_handle_port_interrupt(ap, port_mmio, status);
 }
 
 static irqreturn_t ahci_port_thread_fn(int irq, void *dev_instance)
@@ -1808,34 +1807,6 @@ static irqreturn_t ahci_port_thread_fn(int irq, void *dev_instance)
        return IRQ_HANDLED;
 }
 
-irqreturn_t ahci_thread_fn(int irq, void *dev_instance)
-{
-       struct ata_host *host = dev_instance;
-       struct ahci_host_priv *hpriv = host->private_data;
-       u32 irq_masked = hpriv->port_map;
-       unsigned int i;
-
-       for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap;
-
-               if (!(irq_masked & (1 << i)))
-                       continue;
-
-               ap = host->ports[i];
-               if (ap) {
-                       ahci_port_thread_fn(irq, ap);
-                       VPRINTK("port %u\n", i);
-               } else {
-                       VPRINTK("port %u (no irq)\n", i);
-                       if (ata_ratelimit())
-                               dev_warn(host->dev,
-                                        "interrupt on disabled port %u\n", i);
-               }
-       }
-
-       return IRQ_HANDLED;
-}
-
 static irqreturn_t ahci_multi_irqs_intr(int irq, void *dev_instance)
 {
        struct ata_port *ap = dev_instance;
@@ -1875,6 +1846,8 @@ static irqreturn_t ahci_single_irq_intr(int irq, void *dev_instance)
 
        irq_masked = irq_stat & hpriv->port_map;
 
+       spin_lock(&host->lock);
+
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap;
 
@@ -1883,7 +1856,7 @@ static irqreturn_t ahci_single_irq_intr(int irq, void *dev_instance)
 
                ap = host->ports[i];
                if (ap) {
-                       ahci_update_intr_status(ap);
+                       ahci_port_intr(ap);
                        VPRINTK("port %u\n", i);
                } else {
                        VPRINTK("port %u (no irq)\n", i);
@@ -1906,9 +1879,11 @@ static irqreturn_t ahci_single_irq_intr(int irq, void *dev_instance)
         */
        writel(irq_stat, mmio + HOST_IRQ_STAT);
 
+       spin_unlock(&host->lock);
+
        VPRINTK("EXIT\n");
 
-       return handled ? IRQ_WAKE_THREAD : IRQ_NONE;
+       return IRQ_RETVAL(handled);
 }
 
 unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
@@ -2320,8 +2295,13 @@ static int ahci_port_start(struct ata_port *ap)
         */
        pp->intr_mask = DEF_PORT_IRQ;
 
-       spin_lock_init(&pp->lock);
-       ap->lock = &pp->lock;
+       /*
+        * Switch to per-port locking in case each port has its own MSI vector.
+        */
+       if ((hpriv->flags & AHCI_HFLAG_MULTI_MSI)) {
+               spin_lock_init(&pp->lock);
+               ap->lock = &pp->lock;
+       }
 
        ap->private_data = pp;
 
@@ -2482,31 +2462,6 @@ out_free_irqs:
        return rc;
 }
 
-static int ahci_host_activate_single_irq(struct ata_host *host, int irq,
-                                        struct scsi_host_template *sht)
-{
-       int i, rc;
-
-       rc = ata_host_start(host);
-       if (rc)
-               return rc;
-
-       rc = devm_request_threaded_irq(host->dev, irq, ahci_single_irq_intr,
-                                      ahci_thread_fn, IRQF_SHARED,
-                                      dev_driver_string(host->dev), host);
-       if (rc)
-               return rc;
-
-       for (i = 0; i < host->n_ports; i++)
-               ata_port_desc(host->ports[i], "irq %d", irq);
-
-       rc = ata_host_register(host, sht);
-       if (rc)
-               devm_free_irq(host->dev, irq, host);
-
-       return rc;
-}
-
 /**
  *     ahci_host_activate - start AHCI host, request IRQs and register it
  *     @host: target ATA host
@@ -2532,7 +2487,8 @@ int ahci_host_activate(struct ata_host *host, int irq,
        if (hpriv->flags & AHCI_HFLAG_MULTI_MSI)
                rc = ahci_host_activate_multi_irqs(host, irq, sht);
        else
-               rc = ahci_host_activate_single_irq(host, irq, sht);
+               rc = ata_host_activate(host, irq, ahci_single_irq_intr,
+                                      IRQF_SHARED, sht);
        return rc;
 }
 EXPORT_SYMBOL_GPL(ahci_host_activate);
index 61eb6d77dac7f507403578a283eade305378f566..ea1fbc1d4c5f1134d05e69a8e9d322c3f54d0789 100644 (file)
 enum sata_rcar_type {
        RCAR_GEN1_SATA,
        RCAR_GEN2_SATA,
+       RCAR_R8A7790_ES1_SATA,
 };
 
 struct sata_rcar_priv {
@@ -763,6 +764,9 @@ static void sata_rcar_setup_port(struct ata_host *host)
        ap->udma_mask   = ATA_UDMA6;
        ap->flags       |= ATA_FLAG_SATA;
 
+       if (priv->type == RCAR_R8A7790_ES1_SATA)
+               ap->flags       |= ATA_FLAG_NO_DIPM;
+
        ioaddr->cmd_addr = base + SDATA_REG;
        ioaddr->ctl_addr = base + SSDEVCON_REG;
        ioaddr->scr_addr = base + SCRSSTS_REG;
@@ -792,6 +796,7 @@ static void sata_rcar_init_controller(struct ata_host *host)
                sata_rcar_gen1_phy_init(priv);
                break;
        case RCAR_GEN2_SATA:
+       case RCAR_R8A7790_ES1_SATA:
                sata_rcar_gen2_phy_init(priv);
                break;
        default:
@@ -837,10 +842,18 @@ static struct of_device_id sata_rcar_match[] = {
                .compatible = "renesas,sata-r8a7790",
                .data = (void *)RCAR_GEN2_SATA
        },
+       {
+               .compatible = "renesas,sata-r8a7790-es1",
+               .data = (void *)RCAR_R8A7790_ES1_SATA
+       },
        {
                .compatible = "renesas,sata-r8a7791",
                .data = (void *)RCAR_GEN2_SATA
        },
+       {
+               .compatible = "renesas,sata-r8a7793",
+               .data = (void *)RCAR_GEN2_SATA
+       },
        { },
 };
 MODULE_DEVICE_TABLE(of, sata_rcar_match);
@@ -849,7 +862,9 @@ static const struct platform_device_id sata_rcar_id_table[] = {
        { "sata_rcar", RCAR_GEN1_SATA }, /* Deprecated by "sata-r8a7779" */
        { "sata-r8a7779", RCAR_GEN1_SATA },
        { "sata-r8a7790", RCAR_GEN2_SATA },
+       { "sata-r8a7790-es1", RCAR_R8A7790_ES1_SATA },
        { "sata-r8a7791", RCAR_GEN2_SATA },
+       { "sata-r8a7793", RCAR_GEN2_SATA },
        { },
 };
 MODULE_DEVICE_TABLE(platform, sata_rcar_id_table);
index 40bc2f4072cc28ea4138ae36b3b08cb96f2ed158..fb83d4acd400ef0c9e87fddf92f7c7f4da174487 100644 (file)
@@ -361,9 +361,19 @@ static int __pm_genpd_save_device(struct pm_domain_data *pdd,
        struct device *dev = pdd->dev;
        int ret = 0;
 
-       if (gpd_data->need_restore)
+       if (gpd_data->need_restore > 0)
                return 0;
 
+       /*
+        * If the value of the need_restore flag is still unknown at this point,
+        * we trust that pm_genpd_poweroff() has verified that the device is
+        * already runtime PM suspended.
+        */
+       if (gpd_data->need_restore < 0) {
+               gpd_data->need_restore = 1;
+               return 0;
+       }
+
        mutex_unlock(&genpd->lock);
 
        genpd_start_dev(genpd, dev);
@@ -373,7 +383,7 @@ static int __pm_genpd_save_device(struct pm_domain_data *pdd,
        mutex_lock(&genpd->lock);
 
        if (!ret)
-               gpd_data->need_restore = true;
+               gpd_data->need_restore = 1;
 
        return ret;
 }
@@ -389,12 +399,17 @@ static void __pm_genpd_restore_device(struct pm_domain_data *pdd,
 {
        struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd);
        struct device *dev = pdd->dev;
-       bool need_restore = gpd_data->need_restore;
+       int need_restore = gpd_data->need_restore;
 
-       gpd_data->need_restore = false;
+       gpd_data->need_restore = 0;
        mutex_unlock(&genpd->lock);
 
        genpd_start_dev(genpd, dev);
+
+       /*
+        * Call genpd_restore_dev() for recently added devices too (need_restore
+        * is negative then).
+        */
        if (need_restore)
                genpd_restore_dev(genpd, dev);
 
@@ -603,6 +618,7 @@ static void genpd_power_off_work_fn(struct work_struct *work)
 static int pm_genpd_runtime_suspend(struct device *dev)
 {
        struct generic_pm_domain *genpd;
+       struct generic_pm_domain_data *gpd_data;
        bool (*stop_ok)(struct device *__dev);
        int ret;
 
@@ -628,6 +644,16 @@ static int pm_genpd_runtime_suspend(struct device *dev)
                return 0;
 
        mutex_lock(&genpd->lock);
+
+       /*
+        * If we have an unknown state of the need_restore flag, it means none
+        * of the runtime PM callbacks has been invoked yet. Let's update the
+        * flag to reflect that the current state is active.
+        */
+       gpd_data = to_gpd_data(dev->power.subsys_data->domain_data);
+       if (gpd_data->need_restore < 0)
+               gpd_data->need_restore = 0;
+
        genpd->in_progress++;
        pm_genpd_poweroff(genpd);
        genpd->in_progress--;
@@ -1437,12 +1463,12 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
        spin_unlock_irq(&dev->power.lock);
 
        if (genpd->attach_dev)
-               genpd->attach_dev(dev);
+               genpd->attach_dev(genpd, dev);
 
        mutex_lock(&gpd_data->lock);
        gpd_data->base.dev = dev;
        list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
-       gpd_data->need_restore = genpd->status == GPD_STATE_POWER_OFF;
+       gpd_data->need_restore = -1;
        gpd_data->td.constraint_changed = true;
        gpd_data->td.effective_constraint_ns = -1;
        mutex_unlock(&gpd_data->lock);
@@ -1499,7 +1525,7 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
        genpd->max_off_time_changed = true;
 
        if (genpd->detach_dev)
-               genpd->detach_dev(dev);
+               genpd->detach_dev(genpd, dev);
 
        spin_lock_irq(&dev->power.lock);
 
@@ -1546,7 +1572,7 @@ void pm_genpd_dev_need_restore(struct device *dev, bool val)
 
        psd = dev_to_psd(dev);
        if (psd && psd->domain_data)
-               to_gpd_data(psd->domain_data)->need_restore = val;
+               to_gpd_data(psd->domain_data)->need_restore = val ? 1 : 0;
 
        spin_unlock_irqrestore(&dev->power.lock, flags);
 }
index 23aaf40cf37f5b6b7e5416a0125e62d581864079..f657c571b18e4e6baaa52250640aac4e1fa26267 100644 (file)
@@ -166,8 +166,8 @@ try_again:
                if (ret == -EPROBE_DEFER)
                        dev_dbg(cpu_dev, "cpu%d clock not ready, retry\n", cpu);
                else
-                       dev_err(cpu_dev, "failed to get cpu%d clock: %d\n", ret,
-                               cpu);
+                       dev_err(cpu_dev, "failed to get cpu%d clock: %d\n", cpu,
+                               ret);
        } else {
                *cdev = cpu_dev;
                *creg = cpu_reg;
index 644b54e1e7d13e8ebc863f9bb8c694278d999227..4473eba1d6b0b6084f632a8cb25e7c7cd815170b 100644 (file)
@@ -1022,7 +1022,8 @@ static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
 
        read_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
-       policy->governor = NULL;
+       if (policy)
+               policy->governor = NULL;
 
        return policy;
 }
index 4839bfa74a107a1ad4cbdfb09017d86da1fd1a41..19a99743cf524670d5906400d286cc877bcf91d6 100644 (file)
@@ -271,7 +271,7 @@ struct pl330_config {
 #define DMAC_MODE_NS   (1 << 0)
        unsigned int    mode;
        unsigned int    data_bus_width:10; /* In number of bits */
-       unsigned int    data_buf_dep:10;
+       unsigned int    data_buf_dep:11;
        unsigned int    num_chan:4;
        unsigned int    num_peri:6;
        u32             peri_ns;
@@ -2336,7 +2336,7 @@ static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len)
        int burst_len;
 
        burst_len = pl330->pcfg.data_bus_width / 8;
-       burst_len *= pl330->pcfg.data_buf_dep;
+       burst_len *= pl330->pcfg.data_buf_dep / pl330->pcfg.num_chan;
        burst_len >>= desc->rqcfg.brst_size;
 
        /* src/dst_burst_len can't be more than 16 */
@@ -2459,16 +2459,25 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
        /* Select max possible burst size */
        burst = pl330->pcfg.data_bus_width / 8;
 
-       while (burst > 1) {
-               if (!(len % burst))
-                       break;
+       /*
+        * Make sure we use a burst size that aligns with all the memcpy
+        * parameters because our DMA programming algorithm doesn't cope with
+        * transfers which straddle an entry in the DMA device's MFIFO.
+        */
+       while ((src | dst | len) & (burst - 1))
                burst /= 2;
-       }
 
        desc->rqcfg.brst_size = 0;
        while (burst != (1 << desc->rqcfg.brst_size))
                desc->rqcfg.brst_size++;
 
+       /*
+        * If burst size is smaller than bus width then make sure we only
+        * transfer one at a time to avoid a burst stradling an MFIFO entry.
+        */
+       if (desc->rqcfg.brst_size * 8 < pl330->pcfg.data_bus_width)
+               desc->rqcfg.brst_len = 1;
+
        desc->rqcfg.brst_len = get_burst_len(desc, len);
 
        desc->txd.flags = flags;
@@ -2732,7 +2741,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 
        dev_info(&adev->dev,
-               "Loaded driver for PL330 DMAC-%d\n", adev->periphid);
+               "Loaded driver for PL330 DMAC-%x\n", adev->periphid);
        dev_info(&adev->dev,
                "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n",
                pcfg->data_buf_dep, pcfg->data_bus_width / 8, pcfg->num_chan,
index 3aa10b32825491dce9d5c0ad244ddc53f78df12e..91292f5513ff2df6d051b784fcb81d276f6e6c63 100644 (file)
@@ -230,30 +230,25 @@ static inline void sun6i_dma_dump_chan_regs(struct sun6i_dma_dev *sdev,
                readl(pchan->base + DMA_CHAN_CUR_PARA));
 }
 
-static inline int convert_burst(u32 maxburst, u8 *burst)
+static inline s8 convert_burst(u32 maxburst)
 {
        switch (maxburst) {
        case 1:
-               *burst = 0;
-               break;
+               return 0;
        case 8:
-               *burst = 2;
-               break;
+               return 2;
        default:
                return -EINVAL;
        }
-
-       return 0;
 }
 
-static inline int convert_buswidth(enum dma_slave_buswidth addr_width, u8 *width)
+static inline s8 convert_buswidth(enum dma_slave_buswidth addr_width)
 {
        if ((addr_width < DMA_SLAVE_BUSWIDTH_1_BYTE) ||
            (addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES))
                return -EINVAL;
 
-       *width = addr_width >> 1;
-       return 0;
+       return addr_width >> 1;
 }
 
 static void *sun6i_dma_lli_add(struct sun6i_dma_lli *prev,
@@ -284,26 +279,25 @@ static inline int sun6i_dma_cfg_lli(struct sun6i_dma_lli *lli,
                                    struct dma_slave_config *config)
 {
        u8 src_width, dst_width, src_burst, dst_burst;
-       int ret;
 
        if (!config)
                return -EINVAL;
 
-       ret = convert_burst(config->src_maxburst, &src_burst);
-       if (ret)
-               return ret;
+       src_burst = convert_burst(config->src_maxburst);
+       if (src_burst)
+               return src_burst;
 
-       ret = convert_burst(config->dst_maxburst, &dst_burst);
-       if (ret)
-               return ret;
+       dst_burst = convert_burst(config->dst_maxburst);
+       if (dst_burst)
+               return dst_burst;
 
-       ret = convert_buswidth(config->src_addr_width, &src_width);
-       if (ret)
-               return ret;
+       src_width = convert_buswidth(config->src_addr_width);
+       if (src_width)
+               return src_width;
 
-       ret = convert_buswidth(config->dst_addr_width, &dst_width);
-       if (ret)
-               return ret;
+       dst_width = convert_buswidth(config->dst_addr_width);
+       if (dst_width)
+               return dst_width;
 
        lli->cfg = DMA_CHAN_CFG_SRC_BURST(src_burst) |
                DMA_CHAN_CFG_SRC_WIDTH(src_width) |
@@ -542,11 +536,10 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
 {
        struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(chan->device);
        struct sun6i_vchan *vchan = to_sun6i_vchan(chan);
-       struct dma_slave_config *sconfig = &vchan->cfg;
        struct sun6i_dma_lli *v_lli;
        struct sun6i_desc *txd;
        dma_addr_t p_lli;
-       int ret;
+       s8 burst, width;
 
        dev_dbg(chan2dev(chan),
                "%s; chan: %d, dest: %pad, src: %pad, len: %zu. flags: 0x%08lx\n",
@@ -565,14 +558,21 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
                goto err_txd_free;
        }
 
-       ret = sun6i_dma_cfg_lli(v_lli, src, dest, len, sconfig);
-       if (ret)
-               goto err_dma_free;
+       v_lli->src = src;
+       v_lli->dst = dest;
+       v_lli->len = len;
+       v_lli->para = NORMAL_WAIT;
 
+       burst = convert_burst(8);
+       width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES);
        v_lli->cfg |= DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) |
                DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) |
                DMA_CHAN_CFG_DST_LINEAR_MODE |
-               DMA_CHAN_CFG_SRC_LINEAR_MODE;
+               DMA_CHAN_CFG_SRC_LINEAR_MODE |
+               DMA_CHAN_CFG_SRC_BURST(burst) |
+               DMA_CHAN_CFG_SRC_WIDTH(width) |
+               DMA_CHAN_CFG_DST_BURST(burst) |
+               DMA_CHAN_CFG_DST_WIDTH(width);
 
        sun6i_dma_lli_add(NULL, v_lli, p_lli, txd);
 
@@ -580,8 +580,6 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
 
        return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
 
-err_dma_free:
-       dma_pool_free(sdev->pool, v_lli, p_lli);
 err_txd_free:
        kfree(txd);
        return NULL;
@@ -915,6 +913,7 @@ static int sun6i_dma_probe(struct platform_device *pdev)
        sdc->slave.device_prep_dma_memcpy       = sun6i_dma_prep_dma_memcpy;
        sdc->slave.device_control               = sun6i_dma_control;
        sdc->slave.chancnt                      = NR_MAX_VCHANS;
+       sdc->slave.copy_align                   = 4;
 
        sdc->slave.dev = &pdev->dev;
 
index 5d997a33907e431b895111fc27039468be244614..2a3973a7c44179457f635196696bc78e756a76e1 100644 (file)
@@ -1637,8 +1637,7 @@ static int dispatch_ioctl(struct client *client,
            _IOC_SIZE(cmd) > sizeof(buffer))
                return -ENOTTY;
 
-       if (_IOC_DIR(cmd) == _IOC_READ)
-               memset(&buffer, 0, _IOC_SIZE(cmd));
+       memset(&buffer, 0, sizeof(buffer));
 
        if (_IOC_DIR(cmd) & _IOC_WRITE)
                if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
index c57466edf45b86e39ba292c9d37117a685fdaabd..e5c4c6c8c967066dc05f9964544520e9273a6d0a 100644 (file)
@@ -495,6 +495,12 @@ static struct component_match *exynos_drm_match_add(struct device *dev)
 
        mutex_lock(&drm_component_lock);
 
+       /* Do not retry to probe if there is no any kms driver regitered. */
+       if (list_empty(&drm_component_list)) {
+               mutex_unlock(&drm_component_lock);
+               return ERR_PTR(-ENODEV);
+       }
+
        list_for_each_entry(cdev, &drm_component_list, list) {
                /*
                 * Add components to master only in case that crtc and
@@ -585,10 +591,21 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
                goto err_unregister_mixer_drv;
 #endif
 
+       match = exynos_drm_match_add(&pdev->dev);
+       if (IS_ERR(match)) {
+               ret = PTR_ERR(match);
+               goto err_unregister_hdmi_drv;
+       }
+
+       ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
+                                               match);
+       if (ret < 0)
+               goto err_unregister_hdmi_drv;
+
 #ifdef CONFIG_DRM_EXYNOS_G2D
        ret = platform_driver_register(&g2d_driver);
        if (ret < 0)
-               goto err_unregister_hdmi_drv;
+               goto err_del_component_master;
 #endif
 
 #ifdef CONFIG_DRM_EXYNOS_FIMC
@@ -619,23 +636,9 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
                goto err_unregister_ipp_drv;
 #endif
 
-       match = exynos_drm_match_add(&pdev->dev);
-       if (IS_ERR(match)) {
-               ret = PTR_ERR(match);
-               goto err_unregister_resources;
-       }
-
-       ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
-                                               match);
-       if (ret < 0)
-               goto err_unregister_resources;
-
        return ret;
 
-err_unregister_resources:
-
 #ifdef CONFIG_DRM_EXYNOS_IPP
-       exynos_platform_device_ipp_unregister();
 err_unregister_ipp_drv:
        platform_driver_unregister(&ipp_driver);
 err_unregister_gsc_drv:
@@ -658,9 +661,11 @@ err_unregister_g2d_drv:
 
 #ifdef CONFIG_DRM_EXYNOS_G2D
        platform_driver_unregister(&g2d_driver);
-err_unregister_hdmi_drv:
+err_del_component_master:
 #endif
+       component_master_del(&pdev->dev, &exynos_drm_ops);
 
+err_unregister_hdmi_drv:
 #ifdef CONFIG_DRM_EXYNOS_HDMI
        platform_driver_unregister(&hdmi_driver);
 err_unregister_mixer_drv:
@@ -741,6 +746,18 @@ static int exynos_drm_init(void)
 {
        int ret;
 
+       /*
+        * Register device object only in case of Exynos SoC.
+        *
+        * Below codes resolves temporarily infinite loop issue incurred
+        * by Exynos drm driver when using multi-platform kernel.
+        * So these codes will be replaced with more generic way later.
+        */
+       if (!of_machine_is_compatible("samsung,exynos3") &&
+                       !of_machine_is_compatible("samsung,exynos4") &&
+                       !of_machine_is_compatible("samsung,exynos5"))
+               return -ENODEV;
+
        exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1,
                                                                NULL, 0);
        if (IS_ERR(exynos_drm_pdev))
index df7a77d3eff84b769342f04114a31a040a843769..6ff8599f6cbf0beb09dc48a5a1b1c7b110a739bf 100644 (file)
@@ -302,9 +302,12 @@ static void g2d_fini_cmdlist(struct g2d_data *g2d)
        struct exynos_drm_subdrv *subdrv = &g2d->subdrv;
 
        kfree(g2d->cmdlist_node);
-       dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE,
-                       g2d->cmdlist_pool_virt,
-                       g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs);
+
+       if (g2d->cmdlist_pool_virt && g2d->cmdlist_pool) {
+               dma_free_attrs(subdrv->drm_dev->dev, G2D_CMDLIST_POOL_SIZE,
+                               g2d->cmdlist_pool_virt,
+                               g2d->cmdlist_pool, &g2d->cmdlist_dma_attrs);
+       }
 }
 
 static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d)
index 1403b01e821695cce6c42cb8b3704eb284aba17e..318ade9bb5af54d786926983eb53f36115409583 100644 (file)
@@ -1670,15 +1670,17 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
                goto out_regs;
 
        if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               ret = i915_kick_out_vgacon(dev_priv);
+               /* WARNING: Apparently we must kick fbdev drivers before vgacon,
+                * otherwise the vga fbdev driver falls over. */
+               ret = i915_kick_out_firmware_fb(dev_priv);
                if (ret) {
-                       DRM_ERROR("failed to remove conflicting VGA console\n");
+                       DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
                        goto out_gtt;
                }
 
-               ret = i915_kick_out_firmware_fb(dev_priv);
+               ret = i915_kick_out_vgacon(dev_priv);
                if (ret) {
-                       DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
+                       DRM_ERROR("failed to remove conflicting VGA console\n");
                        goto out_gtt;
                }
        }
index 2cefb597df6dc92d446557442073d5c998843a30..2b1eaa29ada448e2b6ec8b1d070482d7ee278933 100644 (file)
@@ -364,22 +364,9 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
                 * has to also include the unfenced register the GPU uses
                 * whilst executing a fenced command for an untiled object.
                 */
-
-               obj->map_and_fenceable =
-                       !i915_gem_obj_ggtt_bound(obj) ||
-                       (i915_gem_obj_ggtt_offset(obj) +
-                        obj->base.size <= dev_priv->gtt.mappable_end &&
-                        i915_gem_object_fence_ok(obj, args->tiling_mode));
-
-               /* Rebind if we need a change of alignment */
-               if (!obj->map_and_fenceable) {
-                       u32 unfenced_align =
-                               i915_gem_get_gtt_alignment(dev, obj->base.size,
-                                                           args->tiling_mode,
-                                                           false);
-                       if (i915_gem_obj_ggtt_offset(obj) & (unfenced_align - 1))
-                               ret = i915_gem_object_ggtt_unbind(obj);
-               }
+               if (obj->map_and_fenceable &&
+                   !i915_gem_object_fence_ok(obj, args->tiling_mode))
+                       ret = i915_gem_object_ggtt_unbind(obj);
 
                if (ret == 0) {
                        obj->fence_dirty =
index c27b6140bfd10e3912006f994da2bb75090c6b82..ad2fd605f76be43c847807996a0db06b8b8dbc05 100644 (file)
@@ -5469,11 +5469,6 @@ static void gen6_init_clock_gating(struct drm_device *dev)
        I915_WRITE(_3D_CHICKEN,
                   _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB));
 
-       /* WaSetupGtModeTdRowDispatch:snb */
-       if (IS_SNB_GT1(dev))
-               I915_WRITE(GEN6_GT_MODE,
-                          _MASKED_BIT_ENABLE(GEN6_TD_FOUR_ROW_DISPATCH_DISABLE));
-
        /* WaDisable_RenderCache_OperationalFlush:snb */
        I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
 
index a16024a747717e881d0d4e1464a02b1f6cdac45a..fde42e4d1b56002b733bac6f7d37ca90d6d09328 100644 (file)
@@ -26,6 +26,20 @@ struct gk20a_fb_priv {
        struct nouveau_fb base;
 };
 
+static int
+gk20a_fb_init(struct nouveau_object *object)
+{
+       struct gk20a_fb_priv *priv = (void *)object;
+       int ret;
+
+       ret = nouveau_fb_init(&priv->base);
+       if (ret)
+               return ret;
+
+       nv_mask(priv, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */
+       return 0;
+}
+
 static int
 gk20a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
             struct nouveau_oclass *oclass, void *data, u32 size,
@@ -48,7 +62,7 @@ gk20a_fb_oclass = &(struct nouveau_fb_impl) {
        .base.ofuncs = &(struct nouveau_ofuncs) {
                .ctor = gk20a_fb_ctor,
                .dtor = _nouveau_fb_dtor,
-               .init = _nouveau_fb_init,
+               .init = gk20a_fb_init,
                .fini = _nouveau_fb_fini,
        },
        .memtype = nvc0_fb_memtype_valid,
index ae873d1a8d463f7cd55da92b550eec1c44d31e25..eb8b36714fa1c2e481ae67150626f2cf6ade3847 100644 (file)
@@ -790,6 +790,22 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
        return 0;
 }
 
+static int
+nv50_crtc_set_raster_vblank_dmi(struct nouveau_crtc *nv_crtc, u32 usec)
+{
+       struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
+       u32 *push;
+
+       push = evo_wait(mast, 8);
+       if (!push)
+               return -ENOMEM;
+
+       evo_mthd(push, 0x0828 + (nv_crtc->index * 0x400), 1);
+       evo_data(push, usec);
+       evo_kick(push, mast);
+       return 0;
+}
+
 static int
 nv50_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update)
 {
@@ -1104,14 +1120,14 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode,
                        evo_mthd(push, 0x0804 + (nv_crtc->index * 0x400), 2);
                        evo_data(push, 0x00800000 | mode->clock);
                        evo_data(push, (ilace == 2) ? 2 : 0);
-                       evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 8);
+                       evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 6);
                        evo_data(push, 0x00000000);
                        evo_data(push, (vactive << 16) | hactive);
                        evo_data(push, ( vsynce << 16) | hsynce);
                        evo_data(push, (vblanke << 16) | hblanke);
                        evo_data(push, (vblanks << 16) | hblanks);
                        evo_data(push, (vblan2e << 16) | vblan2s);
-                       evo_data(push, vblankus);
+                       evo_mthd(push, 0x082c + (nv_crtc->index * 0x400), 1);
                        evo_data(push, 0x00000000);
                        evo_mthd(push, 0x0900 + (nv_crtc->index * 0x400), 2);
                        evo_data(push, 0x00000311);
@@ -1141,6 +1157,11 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode,
        nv_connector = nouveau_crtc_connector_get(nv_crtc);
        nv50_crtc_set_dither(nv_crtc, false);
        nv50_crtc_set_scale(nv_crtc, false);
+
+       /* G94 only accepts this after setting scale */
+       if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA)
+               nv50_crtc_set_raster_vblank_dmi(nv_crtc, vblankus);
+
        nv50_crtc_set_color_vibrance(nv_crtc, false);
        nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, false);
        return 0;
index 15da7ef344a4e55fa11d604c21269e97ab361386..ec1593a6a561b550d873033d1c9cd7c9e6974af4 100644 (file)
@@ -1217,7 +1217,7 @@ free:
        return ret;
 }
 
-int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
+int atom_execute_table_scratch_unlocked(struct atom_context *ctx, int index, uint32_t * params)
 {
        int r;
 
@@ -1238,6 +1238,15 @@ int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
        return r;
 }
 
+int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
+{
+       int r;
+       mutex_lock(&ctx->scratch_mutex);
+       r = atom_execute_table_scratch_unlocked(ctx, index, params);
+       mutex_unlock(&ctx->scratch_mutex);
+       return r;
+}
+
 static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 };
 
 static void atom_index_iio(struct atom_context *ctx, int base)
index feba6b8d36b346640ba09f19e571e069cb575f8f..6d014ddb6b7837f035bb332a9b9d12b22256c741 100644 (file)
@@ -125,6 +125,7 @@ struct card_info {
 struct atom_context {
        struct card_info *card;
        struct mutex mutex;
+       struct mutex scratch_mutex;
        void *bios;
        uint32_t cmd_table, data_table;
        uint16_t *iio;
@@ -145,6 +146,7 @@ extern int atom_debug;
 
 struct atom_context *atom_parse(struct card_info *, void *);
 int atom_execute_table(struct atom_context *, int, uint32_t *);
+int atom_execute_table_scratch_unlocked(struct atom_context *, int, uint32_t *);
 int atom_asic_init(struct atom_context *);
 void atom_destroy(struct atom_context *);
 bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,
index 95d5d4ab3335edd2c86146c487c9cbd7bc269182..11ba9d21b89b608788f623822bcfb6f9f14dbbf1 100644 (file)
@@ -100,6 +100,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
        memset(&args, 0, sizeof(args));
 
        mutex_lock(&chan->mutex);
+       mutex_lock(&rdev->mode_info.atom_context->scratch_mutex);
 
        base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1);
 
@@ -113,7 +114,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
        if (ASIC_IS_DCE4(rdev))
                args.v2.ucHPD_ID = chan->rec.hpd;
 
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+       atom_execute_table_scratch_unlocked(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 
        *ack = args.v1.ucReplyStatus;
 
@@ -147,6 +148,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
 
        r = recv_bytes;
 done:
+       mutex_unlock(&rdev->mode_info.atom_context->scratch_mutex);
        mutex_unlock(&chan->mutex);
 
        return r;
index 9c570fb15b8c2e49a9765787d26a58a1467c8e0e..4157780585a0e8e89811e97349d99eb7bf026202 100644 (file)
@@ -48,6 +48,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
        memset(&args, 0, sizeof(args));
 
        mutex_lock(&chan->mutex);
+       mutex_lock(&rdev->mode_info.atom_context->scratch_mutex);
 
        base = (unsigned char *)rdev->mode_info.atom_context->scratch;
 
@@ -82,7 +83,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
        args.ucSlaveAddr = slave_addr << 1;
        args.ucLineNumber = chan->rec.i2c_id;
 
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+       atom_execute_table_scratch_unlocked(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 
        /* error */
        if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) {
@@ -95,6 +96,7 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
                radeon_atom_copy_swap(buf, base, num, false);
 
 done:
+       mutex_unlock(&rdev->mode_info.atom_context->scratch_mutex);
        mutex_unlock(&chan->mutex);
 
        return r;
index f6309bd23e0156461f625aa30e8354dbf3a129dd..b5c73df8e202b76c21790eb1b20b12e410a8d696 100644 (file)
@@ -1256,7 +1256,7 @@ int r600_parse_extended_power_table(struct radeon_device *rdev)
                                        (mode_info->atom_context->bios + data_offset +
                                         le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
                                rdev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit =
-                                       ppt->usMaximumPowerDeliveryLimit;
+                                       le16_to_cpu(ppt->usMaximumPowerDeliveryLimit);
                                pt = &ppt->power_tune_table;
                        } else {
                                ATOM_PPLIB_POWERTUNE_Table *ppt = (ATOM_PPLIB_POWERTUNE_Table *)
index ea2676954dde7ce6e157aa1d628782c0906bc7c2..995a8b1770ddb9871c989c9428a554c313dbc5e9 100644 (file)
@@ -952,6 +952,7 @@ int radeon_atombios_init(struct radeon_device *rdev)
        }
 
        mutex_init(&rdev->mode_info.atom_context->mutex);
+       mutex_init(&rdev->mode_info.atom_context->scratch_mutex);
        radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
        atom_allocate_fb_scratch(rdev->mode_info.atom_context);
        return 0;
index 9a19e52cc655bf8b3c697a7116e52e81b8060096..6b670b0bc47bb9dca0238ef35dcff1cc2f686c34 100644 (file)
@@ -179,6 +179,9 @@ static void radeon_encoder_add_backlight(struct radeon_encoder *radeon_encoder,
                    (rdev->pdev->subsystem_vendor == 0x1734) &&
                    (rdev->pdev->subsystem_device == 0x1107))
                        use_bl = false;
+               /* disable native backlight control on older asics */
+               else if (rdev->family < CHIP_R600)
+                       use_bl = false;
                else
                        use_bl = true;
        }
index 6553fd238685e459deb0676114bfd9cac04f7e50..054a79f143ae156b1dbbe4841b55e59bcb6d1b0a 100644 (file)
@@ -736,7 +736,6 @@ static const struct drm_crtc_funcs tegra_crtc_funcs = {
 
 static void tegra_crtc_disable(struct drm_crtc *crtc)
 {
-       struct tegra_dc *dc = to_tegra_dc(crtc);
        struct drm_device *drm = crtc->dev;
        struct drm_plane *plane;
 
@@ -752,7 +751,7 @@ static void tegra_crtc_disable(struct drm_crtc *crtc)
                }
        }
 
-       drm_vblank_off(drm, dc->pipe);
+       drm_crtc_vblank_off(crtc);
 }
 
 static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc,
@@ -841,8 +840,6 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc,
        u32 value;
        int err;
 
-       drm_vblank_pre_modeset(crtc->dev, dc->pipe);
-
        err = tegra_crtc_setup_clk(crtc, mode);
        if (err) {
                dev_err(dc->dev, "failed to setup clock for CRTC: %d\n", err);
@@ -896,6 +893,8 @@ static void tegra_crtc_prepare(struct drm_crtc *crtc)
        unsigned int syncpt;
        unsigned long value;
 
+       drm_crtc_vblank_off(crtc);
+
        /* hardware initialization */
        reset_control_deassert(dc->rst);
        usleep_range(10000, 20000);
@@ -943,7 +942,7 @@ static void tegra_crtc_commit(struct drm_crtc *crtc)
        value = GENERAL_ACT_REQ | WIN_A_ACT_REQ;
        tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
 
-       drm_vblank_post_modeset(crtc->dev, dc->pipe);
+       drm_crtc_vblank_on(crtc);
 }
 
 static void tegra_crtc_load_lut(struct drm_crtc *crtc)
index 3effa931fce259cdf661af95f42ad1463450acf4..10641b7816f49e493dd2e1f091d0921d910c2475 100644 (file)
@@ -115,9 +115,12 @@ isert_conn_setup_qp(struct isert_conn *isert_conn, struct rdma_cm_id *cma_id,
        attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS;
        /*
         * FIXME: Use devattr.max_sge - 2 for max_send_sge as
-        * work-around for RDMA_READ..
+        * work-around for RDMA_READs with ConnectX-2.
+        *
+        * Also, still make sure to have at least two SGEs for
+        * outgoing control PDU responses.
         */
-       attr.cap.max_send_sge = device->dev_attr.max_sge - 2;
+       attr.cap.max_send_sge = max(2, device->dev_attr.max_sge - 2);
        isert_conn->max_sge = attr.cap.max_send_sge;
 
        attr.cap.max_recv_sge = 1;
@@ -225,12 +228,16 @@ isert_create_device_ib_res(struct isert_device *device)
        struct isert_cq_desc *cq_desc;
        struct ib_device_attr *dev_attr;
        int ret = 0, i, j;
+       int max_rx_cqe, max_tx_cqe;
 
        dev_attr = &device->dev_attr;
        ret = isert_query_device(ib_dev, dev_attr);
        if (ret)
                return ret;
 
+       max_rx_cqe = min(ISER_MAX_RX_CQ_LEN, dev_attr->max_cqe);
+       max_tx_cqe = min(ISER_MAX_TX_CQ_LEN, dev_attr->max_cqe);
+
        /* asign function handlers */
        if (dev_attr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS &&
            dev_attr->device_cap_flags & IB_DEVICE_SIGNATURE_HANDOVER) {
@@ -272,7 +279,7 @@ isert_create_device_ib_res(struct isert_device *device)
                                                isert_cq_rx_callback,
                                                isert_cq_event_callback,
                                                (void *)&cq_desc[i],
-                                               ISER_MAX_RX_CQ_LEN, i);
+                                               max_rx_cqe, i);
                if (IS_ERR(device->dev_rx_cq[i])) {
                        ret = PTR_ERR(device->dev_rx_cq[i]);
                        device->dev_rx_cq[i] = NULL;
@@ -284,7 +291,7 @@ isert_create_device_ib_res(struct isert_device *device)
                                                isert_cq_tx_callback,
                                                isert_cq_event_callback,
                                                (void *)&cq_desc[i],
-                                               ISER_MAX_TX_CQ_LEN, i);
+                                               max_tx_cqe, i);
                if (IS_ERR(device->dev_tx_cq[i])) {
                        ret = PTR_ERR(device->dev_tx_cq[i]);
                        device->dev_tx_cq[i] = NULL;
@@ -803,14 +810,25 @@ wake_up:
        complete(&isert_conn->conn_wait);
 }
 
-static void
+static int
 isert_disconnected_handler(struct rdma_cm_id *cma_id, bool disconnect)
 {
-       struct isert_conn *isert_conn = (struct isert_conn *)cma_id->context;
+       struct isert_conn *isert_conn;
+
+       if (!cma_id->qp) {
+               struct isert_np *isert_np = cma_id->context;
+
+               isert_np->np_cm_id = NULL;
+               return -1;
+       }
+
+       isert_conn = (struct isert_conn *)cma_id->context;
 
        isert_conn->disconnect = disconnect;
        INIT_WORK(&isert_conn->conn_logout_work, isert_disconnect_work);
        schedule_work(&isert_conn->conn_logout_work);
+
+       return 0;
 }
 
 static int
@@ -825,6 +843,9 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
        switch (event->event) {
        case RDMA_CM_EVENT_CONNECT_REQUEST:
                ret = isert_connect_request(cma_id, event);
+               if (ret)
+                       pr_err("isert_cma_handler failed RDMA_CM_EVENT: 0x%08x %d\n",
+                               event->event, ret);
                break;
        case RDMA_CM_EVENT_ESTABLISHED:
                isert_connected_handler(cma_id);
@@ -834,7 +855,7 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
        case RDMA_CM_EVENT_DEVICE_REMOVAL: /* FALLTHRU */
                disconnect = true;
        case RDMA_CM_EVENT_TIMEWAIT_EXIT:  /* FALLTHRU */
-               isert_disconnected_handler(cma_id, disconnect);
+               ret = isert_disconnected_handler(cma_id, disconnect);
                break;
        case RDMA_CM_EVENT_CONNECT_ERROR:
        default:
@@ -842,12 +863,6 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
                break;
        }
 
-       if (ret != 0) {
-               pr_err("isert_cma_handler failed RDMA_CM_EVENT: 0x%08x %d\n",
-                      event->event, ret);
-               dump_stack();
-       }
-
        return ret;
 }
 
@@ -3190,7 +3205,8 @@ isert_free_np(struct iscsi_np *np)
 {
        struct isert_np *isert_np = (struct isert_np *)np->np_context;
 
-       rdma_destroy_id(isert_np->np_cm_id);
+       if (isert_np->np_cm_id)
+               rdma_destroy_id(isert_np->np_cm_id);
 
        np->np_context = NULL;
        kfree(isert_np);
index 7206547c13ce0dc8dda59458658d843d64520327..dc829682701ad1dbae8375eb2ff9a2c97feea48f 100644 (file)
@@ -2092,6 +2092,7 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch)
        if (!qp_init)
                goto out;
 
+retry:
        ch->cq = ib_create_cq(sdev->device, srpt_completion, NULL, ch,
                              ch->rq_size + srp_sq_size, 0);
        if (IS_ERR(ch->cq)) {
@@ -2115,6 +2116,13 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch)
        ch->qp = ib_create_qp(sdev->pd, qp_init);
        if (IS_ERR(ch->qp)) {
                ret = PTR_ERR(ch->qp);
+               if (ret == -ENOMEM) {
+                       srp_sq_size /= 2;
+                       if (srp_sq_size >= MIN_SRPT_SQ_SIZE) {
+                               ib_destroy_cq(ch->cq);
+                               goto retry;
+                       }
+               }
                printk(KERN_ERR "failed to create_qp ret= %d\n", ret);
                goto err_destroy_cq;
        }
index fb3b63b2f85c3615619452ef9ee2e6f0528d8245..8400a1a34d87569a5d81febffb75e97d91365ee5 100644 (file)
@@ -85,6 +85,7 @@ static int twl4030_pwrbutton_probe(struct platform_device *pdev)
        }
 
        platform_set_drvdata(pdev, pwr);
+       device_init_wakeup(&pdev->dev, true);
 
        return 0;
 }
index 2b0ae8cc8e51bc3ca52622f66e5909b537bd0153..d125a019383f10155dcafb88903f47e0f5297080 100644 (file)
@@ -1156,7 +1156,13 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
 {
        struct alps_data *priv = psmouse->private;
 
-       if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */
+       /*
+        * Check if we are dealing with a bare PS/2 packet, presumably from
+        * a device connected to the external PS/2 port. Because bare PS/2
+        * protocol does not have enough constant bits to self-synchronize
+        * properly we only do this if the device is fully synchronized.
+        */
+       if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) {
                if (psmouse->pktcnt == 3) {
                        alps_report_bare_ps2_packet(psmouse, psmouse->packet,
                                                    true);
@@ -1180,12 +1186,27 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
        }
 
        /* Bytes 2 - pktsize should have 0 in the highest bit */
-       if ((priv->proto_version < ALPS_PROTO_V5) &&
+       if (priv->proto_version < ALPS_PROTO_V5 &&
            psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
            (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
                psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
                            psmouse->pktcnt - 1,
                            psmouse->packet[psmouse->pktcnt - 1]);
+
+               if (priv->proto_version == ALPS_PROTO_V3 &&
+                   psmouse->pktcnt == psmouse->pktsize) {
+                       /*
+                        * Some Dell boxes, such as Latitude E6440 or E7440
+                        * with closed lid, quite often smash last byte of
+                        * otherwise valid packet with 0xff. Given that the
+                        * next packet is very likely to be valid let's
+                        * report PSMOUSE_FULL_PACKET but not process data,
+                        * rather than reporting PSMOUSE_BAD_DATA and
+                        * filling the logs.
+                        */
+                       return PSMOUSE_FULL_PACKET;
+               }
+
                return PSMOUSE_BAD_DATA;
        }
 
@@ -2389,6 +2410,9 @@ int alps_init(struct psmouse *psmouse)
        /* We are having trouble resyncing ALPS touchpads so disable it for now */
        psmouse->resync_time = 0;
 
+       /* Allow 2 invalid packets without resetting device */
+       psmouse->resetafter = psmouse->pktsize * 2;
+
        return 0;
 
 init_fail:
index 06fc6e76ffbe0cf725053b8a1bdb3faaefa1c629..3fcb6b3cb0bdaea5ba0f17dfd6a228c6cbd126ad 100644 (file)
@@ -563,6 +563,7 @@ static void elantech_input_sync_v4(struct psmouse *psmouse)
        } else {
                input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
                input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+               input_report_key(dev, BTN_MIDDLE, packet[0] & 0x04);
        }
 
        input_mt_report_pointer_emulation(dev, true);
@@ -792,6 +793,9 @@ static int elantech_packet_check_v4(struct psmouse *psmouse)
        unsigned char packet_type = packet[3] & 0x03;
        bool sanity_check;
 
+       if ((packet[3] & 0x0f) == 0x06)
+               return PACKET_TRACKPOINT;
+
        /*
         * Sanity check based on the constant bits of a packet.
         * The constant bits change depending on the value of
@@ -877,10 +881,19 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
 
        case 4:
                packet_type = elantech_packet_check_v4(psmouse);
-               if (packet_type == PACKET_UNKNOWN)
+               switch (packet_type) {
+               case PACKET_UNKNOWN:
                        return PSMOUSE_BAD_DATA;
 
-               elantech_report_absolute_v4(psmouse, packet_type);
+               case PACKET_TRACKPOINT:
+                       elantech_report_trackpoint(psmouse, packet_type);
+                       break;
+
+               default:
+                       elantech_report_absolute_v4(psmouse, packet_type);
+                       break;
+               }
+
                break;
        }
 
@@ -1119,6 +1132,22 @@ static void elantech_set_buttonpad_prop(struct psmouse *psmouse)
        }
 }
 
+/*
+ * Some hw_version 4 models do have a middle button
+ */
+static const struct dmi_system_id elantech_dmi_has_middle_button[] = {
+#if defined(CONFIG_DMI) && defined(CONFIG_X86)
+       {
+               /* Fujitsu H730 has a middle button */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"),
+               },
+       },
+#endif
+       { }
+};
+
 /*
  * Set the appropriate event bits for the input subsystem
  */
@@ -1138,6 +1167,8 @@ static int elantech_set_input_params(struct psmouse *psmouse)
        __clear_bit(EV_REL, dev->evbit);
 
        __set_bit(BTN_LEFT, dev->keybit);
+       if (dmi_check_system(elantech_dmi_has_middle_button))
+               __set_bit(BTN_MIDDLE, dev->keybit);
        __set_bit(BTN_RIGHT, dev->keybit);
 
        __set_bit(BTN_TOUCH, dev->keybit);
@@ -1299,6 +1330,7 @@ ELANTECH_INT_ATTR(reg_25, 0x25);
 ELANTECH_INT_ATTR(reg_26, 0x26);
 ELANTECH_INT_ATTR(debug, 0);
 ELANTECH_INT_ATTR(paritycheck, 0);
+ELANTECH_INT_ATTR(crc_enabled, 0);
 
 static struct attribute *elantech_attrs[] = {
        &psmouse_attr_reg_07.dattr.attr,
@@ -1313,6 +1345,7 @@ static struct attribute *elantech_attrs[] = {
        &psmouse_attr_reg_26.dattr.attr,
        &psmouse_attr_debug.dattr.attr,
        &psmouse_attr_paritycheck.dattr.attr,
+       &psmouse_attr_crc_enabled.dattr.attr,
        NULL
 };
 
@@ -1438,6 +1471,22 @@ static int elantech_reconnect(struct psmouse *psmouse)
        return 0;
 }
 
+/*
+ * Some hw_version 4 models do not work with crc_disabled
+ */
+static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
+#if defined(CONFIG_DMI) && defined(CONFIG_X86)
+       {
+               /* Fujitsu H730 does not work with crc_enabled == 0 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"),
+               },
+       },
+#endif
+       { }
+};
+
 /*
  * Some hw_version 3 models go into error state when we try to set
  * bit 3 and/or bit 1 of r10.
@@ -1513,7 +1562,8 @@ static int elantech_set_properties(struct elantech_data *etd)
         * The signatures of v3 and v4 packets change depending on the
         * value of this hardware flag.
         */
-       etd->crc_enabled = ((etd->fw_version & 0x4000) == 0x4000);
+       etd->crc_enabled = (etd->fw_version & 0x4000) == 0x4000 ||
+                          dmi_check_system(elantech_dmi_force_crc_enabled);
 
        /* Enable real hardware resolution on hw_version 3 ? */
        etd->set_hw_resolution = !dmi_check_system(no_hw_res_dmi_table);
index 9031a0a28ea4f2cf0c086036334e975a3fdbdf35..2a7a9174c702a44df3072a2f61c72a4ce16ecb05 100644 (file)
@@ -135,8 +135,8 @@ static const struct min_max_quirk min_max_pnpid_table[] = {
                1232, 5710, 1156, 4696
        },
        {
-               (const char * const []){"LEN0034", "LEN0036", "LEN2002",
-                                       "LEN2004", NULL},
+               (const char * const []){"LEN0034", "LEN0036", "LEN0039",
+                                       "LEN2002", "LEN2004", NULL},
                1024, 5112, 2024, 4832
        },
        {
@@ -163,6 +163,7 @@ static const char * const topbuttonpad_pnp_ids[] = {
        "LEN0036", /* T440 */
        "LEN0037",
        "LEN0038",
+       "LEN0039", /* T440s */
        "LEN0041",
        "LEN0042", /* Yoga */
        "LEN0045",
index 4dfa15da9cb8344da4aae1fd28a78f05d84d8563..9233c71138f18a62a4c175d7acf9c3b8fd03a3d5 100644 (file)
@@ -5121,6 +5121,7 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
                printk("md: %s still in use.\n",mdname(mddev));
                if (did_freeze) {
                        clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+                       set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                        md_wakeup_thread(mddev->thread);
                }
                err = -EBUSY;
@@ -5135,6 +5136,8 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
                mddev->ro = 1;
                set_disk_ro(mddev->gendisk, 1);
                clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+               set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+               md_wakeup_thread(mddev->thread);
                sysfs_notify_dirent_safe(mddev->sysfs_state);
                err = 0;
        }
@@ -5178,6 +5181,7 @@ static int do_md_stop(struct mddev *mddev, int mode,
                mutex_unlock(&mddev->open_mutex);
                if (did_freeze) {
                        clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+                       set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                        md_wakeup_thread(mddev->thread);
                }
                return -EBUSY;
index c1d7da427a3e209ab5f6bfa275b3b0f904996f50..184c434ae3055e4b8a586c116d1274ddbccec6c5 100644 (file)
@@ -2470,7 +2470,8 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
                        bond_slave_state_change(bond);
                        if (BOND_MODE(bond) == BOND_MODE_XOR)
                                bond_update_slave_arr(bond, NULL);
-               } else if (do_failover) {
+               }
+               if (do_failover) {
                        block_netpoll_tx();
                        bond_select_active_slave(bond);
                        unblock_netpoll_tx();
index 02492d241e4c9e8cb8d49ae319067c7c0aa1f9cf..2cfe5012e4e58c3c4c51b968fba5c9c029e0db44 100644 (file)
@@ -110,7 +110,7 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
        long rate;
        u64 v64;
 
-       /* Use CIA recommended sample points */
+       /* Use CiA recommended sample points */
        if (bt->sample_point) {
                sampl_pt = bt->sample_point;
        } else {
@@ -382,7 +382,7 @@ void can_free_echo_skb(struct net_device *dev, unsigned int idx)
        BUG_ON(idx >= priv->echo_skb_max);
 
        if (priv->echo_skb[idx]) {
-               kfree_skb(priv->echo_skb[idx]);
+               dev_kfree_skb_any(priv->echo_skb[idx]);
                priv->echo_skb[idx] = NULL;
        }
 }
index fca5482c09acd43237f85e69765d3e66b96a4b86..04f20dd39007a105e329cb0168732cd8e909fd5d 100644 (file)
@@ -1,4 +1,5 @@
 config CAN_M_CAN
+       depends on HAS_IOMEM
        tristate "Bosch M_CAN devices"
        ---help---
          Say Y here if you want to support for Bosch M_CAN controller.
index 10d571eaed856814928151da898bd2053d4d899c..d7bc462aafdc27a26774aa6cb6cadb0e0d8547a3 100644 (file)
@@ -105,14 +105,36 @@ enum m_can_mram_cfg {
        MRAM_CFG_NUM,
 };
 
+/* Fast Bit Timing & Prescaler Register (FBTP) */
+#define FBTR_FBRP_MASK         0x1f
+#define FBTR_FBRP_SHIFT                16
+#define FBTR_FTSEG1_SHIFT      8
+#define FBTR_FTSEG1_MASK       (0xf << FBTR_FTSEG1_SHIFT)
+#define FBTR_FTSEG2_SHIFT      4
+#define FBTR_FTSEG2_MASK       (0x7 << FBTR_FTSEG2_SHIFT)
+#define FBTR_FSJW_SHIFT                0
+#define FBTR_FSJW_MASK         0x3
+
 /* Test Register (TEST) */
 #define TEST_LBCK      BIT(4)
 
 /* CC Control Register(CCCR) */
-#define CCCR_TEST      BIT(7)
-#define CCCR_MON       BIT(5)
-#define CCCR_CCE       BIT(1)
-#define CCCR_INIT      BIT(0)
+#define CCCR_TEST              BIT(7)
+#define CCCR_CMR_MASK          0x3
+#define CCCR_CMR_SHIFT         10
+#define CCCR_CMR_CANFD         0x1
+#define CCCR_CMR_CANFD_BRS     0x2
+#define CCCR_CMR_CAN           0x3
+#define CCCR_CME_MASK          0x3
+#define CCCR_CME_SHIFT         8
+#define CCCR_CME_CAN           0
+#define CCCR_CME_CANFD         0x1
+#define CCCR_CME_CANFD_BRS     0x2
+#define CCCR_TEST              BIT(7)
+#define CCCR_MON               BIT(5)
+#define CCCR_CCE               BIT(1)
+#define CCCR_INIT              BIT(0)
+#define CCCR_CANFD             0x10
 
 /* Bit Timing & Prescaler Register (BTP) */
 #define BTR_BRP_MASK           0x3ff
@@ -204,6 +226,7 @@ enum m_can_mram_cfg {
 
 /* Rx Buffer / FIFO Element Size Configuration (RXESC) */
 #define M_CAN_RXESC_8BYTES     0x0
+#define M_CAN_RXESC_64BYTES    0x777
 
 /* Tx Buffer Configuration(TXBC) */
 #define TXBC_NDTB_OFF          16
@@ -211,6 +234,7 @@ enum m_can_mram_cfg {
 
 /* Tx Buffer Element Size Configuration(TXESC) */
 #define TXESC_TBDS_8BYTES      0x0
+#define TXESC_TBDS_64BYTES     0x7
 
 /* Tx Event FIFO Con.guration (TXEFC) */
 #define TXEFC_EFS_OFF          16
@@ -219,11 +243,11 @@ enum m_can_mram_cfg {
 /* Message RAM Configuration (in bytes) */
 #define SIDF_ELEMENT_SIZE      4
 #define XIDF_ELEMENT_SIZE      8
-#define RXF0_ELEMENT_SIZE      16
-#define RXF1_ELEMENT_SIZE      16
+#define RXF0_ELEMENT_SIZE      72
+#define RXF1_ELEMENT_SIZE      72
 #define RXB_ELEMENT_SIZE       16
 #define TXE_ELEMENT_SIZE       8
-#define TXB_ELEMENT_SIZE       16
+#define TXB_ELEMENT_SIZE       72
 
 /* Message RAM Elements */
 #define M_CAN_FIFO_ID          0x0
@@ -231,11 +255,17 @@ enum m_can_mram_cfg {
 #define M_CAN_FIFO_DATA(n)     (0x8 + ((n) << 2))
 
 /* Rx Buffer Element */
+/* R0 */
 #define RX_BUF_ESI             BIT(31)
 #define RX_BUF_XTD             BIT(30)
 #define RX_BUF_RTR             BIT(29)
+/* R1 */
+#define RX_BUF_ANMF            BIT(31)
+#define RX_BUF_EDL             BIT(21)
+#define RX_BUF_BRS             BIT(20)
 
 /* Tx Buffer Element */
+/* R0 */
 #define TX_BUF_XTD             BIT(30)
 #define TX_BUF_RTR             BIT(29)
 
@@ -296,6 +326,7 @@ static inline void m_can_config_endisable(const struct m_can_priv *priv,
        if (enable) {
                /* enable m_can configuration */
                m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT);
+               udelay(5);
                /* CCCR.CCE can only be set/reset while CCCR.INIT = '1' */
                m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT | CCCR_CCE);
        } else {
@@ -326,41 +357,67 @@ static inline void m_can_disable_all_interrupts(const struct m_can_priv *priv)
        m_can_write(priv, M_CAN_ILE, 0x0);
 }
 
-static void m_can_read_fifo(const struct net_device *dev, struct can_frame *cf,
-                           u32 rxfs)
+static void m_can_read_fifo(struct net_device *dev, u32 rxfs)
 {
+       struct net_device_stats *stats = &dev->stats;
        struct m_can_priv *priv = netdev_priv(dev);
-       u32 id, fgi;
+       struct canfd_frame *cf;
+       struct sk_buff *skb;
+       u32 id, fgi, dlc;
+       int i;
 
        /* calculate the fifo get index for where to read data */
        fgi = (rxfs & RXFS_FGI_MASK) >> RXFS_FGI_OFF;
+       dlc = m_can_fifo_read(priv, fgi, M_CAN_FIFO_DLC);
+       if (dlc & RX_BUF_EDL)
+               skb = alloc_canfd_skb(dev, &cf);
+       else
+               skb = alloc_can_skb(dev, (struct can_frame **)&cf);
+       if (!skb) {
+               stats->rx_dropped++;
+               return;
+       }
+
+       if (dlc & RX_BUF_EDL)
+               cf->len = can_dlc2len((dlc >> 16) & 0x0F);
+       else
+               cf->len = get_can_dlc((dlc >> 16) & 0x0F);
+
        id = m_can_fifo_read(priv, fgi, M_CAN_FIFO_ID);
        if (id & RX_BUF_XTD)
                cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG;
        else
                cf->can_id = (id >> 18) & CAN_SFF_MASK;
 
-       if (id & RX_BUF_RTR) {
+       if (id & RX_BUF_ESI) {
+               cf->flags |= CANFD_ESI;
+               netdev_dbg(dev, "ESI Error\n");
+       }
+
+       if (!(dlc & RX_BUF_EDL) && (id & RX_BUF_RTR)) {
                cf->can_id |= CAN_RTR_FLAG;
        } else {
-               id = m_can_fifo_read(priv, fgi, M_CAN_FIFO_DLC);
-               cf->can_dlc = get_can_dlc((id >> 16) & 0x0F);
-               *(u32 *)(cf->data + 0) = m_can_fifo_read(priv, fgi,
-                                                        M_CAN_FIFO_DATA(0));
-               *(u32 *)(cf->data + 4) = m_can_fifo_read(priv, fgi,
-                                                        M_CAN_FIFO_DATA(1));
+               if (dlc & RX_BUF_BRS)
+                       cf->flags |= CANFD_BRS;
+
+               for (i = 0; i < cf->len; i += 4)
+                       *(u32 *)(cf->data + i) =
+                               m_can_fifo_read(priv, fgi,
+                                               M_CAN_FIFO_DATA(i / 4));
        }
 
        /* acknowledge rx fifo 0 */
        m_can_write(priv, M_CAN_RXF0A, fgi);
+
+       stats->rx_packets++;
+       stats->rx_bytes += cf->len;
+
+       netif_receive_skb(skb);
 }
 
 static int m_can_do_rx_poll(struct net_device *dev, int quota)
 {
        struct m_can_priv *priv = netdev_priv(dev);
-       struct net_device_stats *stats = &dev->stats;
-       struct sk_buff *skb;
-       struct can_frame *frame;
        u32 pkts = 0;
        u32 rxfs;
 
@@ -374,18 +431,7 @@ static int m_can_do_rx_poll(struct net_device *dev, int quota)
                if (rxfs & RXFS_RFL)
                        netdev_warn(dev, "Rx FIFO 0 Message Lost\n");
 
-               skb = alloc_can_skb(dev, &frame);
-               if (!skb) {
-                       stats->rx_dropped++;
-                       return pkts;
-               }
-
-               m_can_read_fifo(dev, frame, rxfs);
-
-               stats->rx_packets++;
-               stats->rx_bytes += frame->can_dlc;
-
-               netif_receive_skb(skb);
+               m_can_read_fifo(dev, rxfs);
 
                quota--;
                pkts++;
@@ -481,11 +527,23 @@ static int m_can_handle_lec_err(struct net_device *dev,
        return 1;
 }
 
+static int __m_can_get_berr_counter(const struct net_device *dev,
+                                   struct can_berr_counter *bec)
+{
+       struct m_can_priv *priv = netdev_priv(dev);
+       unsigned int ecr;
+
+       ecr = m_can_read(priv, M_CAN_ECR);
+       bec->rxerr = (ecr & ECR_REC_MASK) >> ECR_REC_SHIFT;
+       bec->txerr = ecr & ECR_TEC_MASK;
+
+       return 0;
+}
+
 static int m_can_get_berr_counter(const struct net_device *dev,
                                  struct can_berr_counter *bec)
 {
        struct m_can_priv *priv = netdev_priv(dev);
-       unsigned int ecr;
        int err;
 
        err = clk_prepare_enable(priv->hclk);
@@ -498,9 +556,7 @@ static int m_can_get_berr_counter(const struct net_device *dev,
                return err;
        }
 
-       ecr = m_can_read(priv, M_CAN_ECR);
-       bec->rxerr = (ecr & ECR_REC_MASK) >> ECR_REC_SHIFT;
-       bec->txerr = ecr & ECR_TEC_MASK;
+       __m_can_get_berr_counter(dev, bec);
 
        clk_disable_unprepare(priv->cclk);
        clk_disable_unprepare(priv->hclk);
@@ -544,7 +600,7 @@ static int m_can_handle_state_change(struct net_device *dev,
        if (unlikely(!skb))
                return 0;
 
-       m_can_get_berr_counter(dev, &bec);
+       __m_can_get_berr_counter(dev, &bec);
 
        switch (new_state) {
        case CAN_STATE_ERROR_ACTIVE:
@@ -596,14 +652,14 @@ static int m_can_handle_state_errors(struct net_device *dev, u32 psr)
 
        if ((psr & PSR_EP) &&
            (priv->can.state != CAN_STATE_ERROR_PASSIVE)) {
-               netdev_dbg(dev, "entered error warning state\n");
+               netdev_dbg(dev, "entered error passive state\n");
                work_done += m_can_handle_state_change(dev,
                                                       CAN_STATE_ERROR_PASSIVE);
        }
 
        if ((psr & PSR_BO) &&
            (priv->can.state != CAN_STATE_BUS_OFF)) {
-               netdev_dbg(dev, "entered error warning state\n");
+               netdev_dbg(dev, "entered error bus off state\n");
                work_done += m_can_handle_state_change(dev,
                                                       CAN_STATE_BUS_OFF);
        }
@@ -615,7 +671,7 @@ static void m_can_handle_other_err(struct net_device *dev, u32 irqstatus)
 {
        if (irqstatus & IR_WDI)
                netdev_err(dev, "Message RAM Watchdog event due to missing READY\n");
-       if (irqstatus & IR_BEU)
+       if (irqstatus & IR_ELO)
                netdev_err(dev, "Error Logging Overflow\n");
        if (irqstatus & IR_BEU)
                netdev_err(dev, "Bit Error Uncorrected\n");
@@ -733,10 +789,23 @@ static const struct can_bittiming_const m_can_bittiming_const = {
        .brp_inc = 1,
 };
 
+static const struct can_bittiming_const m_can_data_bittiming_const = {
+       .name = KBUILD_MODNAME,
+       .tseg1_min = 2,         /* Time segment 1 = prop_seg + phase_seg1 */
+       .tseg1_max = 16,
+       .tseg2_min = 1,         /* Time segment 2 = phase_seg2 */
+       .tseg2_max = 8,
+       .sjw_max = 4,
+       .brp_min = 1,
+       .brp_max = 32,
+       .brp_inc = 1,
+};
+
 static int m_can_set_bittiming(struct net_device *dev)
 {
        struct m_can_priv *priv = netdev_priv(dev);
        const struct can_bittiming *bt = &priv->can.bittiming;
+       const struct can_bittiming *dbt = &priv->can.data_bittiming;
        u16 brp, sjw, tseg1, tseg2;
        u32 reg_btp;
 
@@ -747,7 +816,17 @@ static int m_can_set_bittiming(struct net_device *dev)
        reg_btp = (brp << BTR_BRP_SHIFT) | (sjw << BTR_SJW_SHIFT) |
                        (tseg1 << BTR_TSEG1_SHIFT) | (tseg2 << BTR_TSEG2_SHIFT);
        m_can_write(priv, M_CAN_BTP, reg_btp);
-       netdev_dbg(dev, "setting BTP 0x%x\n", reg_btp);
+
+       if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
+               brp = dbt->brp - 1;
+               sjw = dbt->sjw - 1;
+               tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1;
+               tseg2 = dbt->phase_seg2 - 1;
+               reg_btp = (brp << FBTR_FBRP_SHIFT) | (sjw << FBTR_FSJW_SHIFT) |
+                               (tseg1 << FBTR_FTSEG1_SHIFT) |
+                               (tseg2 << FBTR_FTSEG2_SHIFT);
+               m_can_write(priv, M_CAN_FBTP, reg_btp);
+       }
 
        return 0;
 }
@@ -767,8 +846,8 @@ static void m_can_chip_config(struct net_device *dev)
 
        m_can_config_endisable(priv, true);
 
-       /* RX Buffer/FIFO Element Size 8 bytes data field */
-       m_can_write(priv, M_CAN_RXESC, M_CAN_RXESC_8BYTES);
+       /* RX Buffer/FIFO Element Size 64 bytes data field */
+       m_can_write(priv, M_CAN_RXESC, M_CAN_RXESC_64BYTES);
 
        /* Accept Non-matching Frames Into FIFO 0 */
        m_can_write(priv, M_CAN_GFC, 0x0);
@@ -777,8 +856,8 @@ static void m_can_chip_config(struct net_device *dev)
        m_can_write(priv, M_CAN_TXBC, (1 << TXBC_NDTB_OFF) |
                    priv->mcfg[MRAM_TXB].off);
 
-       /* only support 8 bytes firstly */
-       m_can_write(priv, M_CAN_TXESC, TXESC_TBDS_8BYTES);
+       /* support 64 bytes payload */
+       m_can_write(priv, M_CAN_TXESC, TXESC_TBDS_64BYTES);
 
        m_can_write(priv, M_CAN_TXEFC, (1 << TXEFC_EFS_OFF) |
                    priv->mcfg[MRAM_TXE].off);
@@ -793,7 +872,8 @@ static void m_can_chip_config(struct net_device *dev)
                    RXFC_FWM_1 | priv->mcfg[MRAM_RXF1].off);
 
        cccr = m_can_read(priv, M_CAN_CCCR);
-       cccr &= ~(CCCR_TEST | CCCR_MON);
+       cccr &= ~(CCCR_TEST | CCCR_MON | (CCCR_CMR_MASK << CCCR_CMR_SHIFT) |
+               (CCCR_CME_MASK << CCCR_CME_SHIFT));
        test = m_can_read(priv, M_CAN_TEST);
        test &= ~TEST_LBCK;
 
@@ -805,6 +885,9 @@ static void m_can_chip_config(struct net_device *dev)
                test |= TEST_LBCK;
        }
 
+       if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
+               cccr |= CCCR_CME_CANFD_BRS << CCCR_CME_SHIFT;
+
        m_can_write(priv, M_CAN_CCCR, cccr);
        m_can_write(priv, M_CAN_TEST, test);
 
@@ -869,11 +952,13 @@ static struct net_device *alloc_m_can_dev(void)
 
        priv->dev = dev;
        priv->can.bittiming_const = &m_can_bittiming_const;
+       priv->can.data_bittiming_const = &m_can_data_bittiming_const;
        priv->can.do_set_mode = m_can_set_mode;
        priv->can.do_get_berr_counter = m_can_get_berr_counter;
        priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
                                        CAN_CTRLMODE_LISTENONLY |
-                                       CAN_CTRLMODE_BERR_REPORTING;
+                                       CAN_CTRLMODE_BERR_REPORTING |
+                                       CAN_CTRLMODE_FD;
 
        return dev;
 }
@@ -956,8 +1041,9 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
                                    struct net_device *dev)
 {
        struct m_can_priv *priv = netdev_priv(dev);
-       struct can_frame *cf = (struct can_frame *)skb->data;
-       u32 id;
+       struct canfd_frame *cf = (struct canfd_frame *)skb->data;
+       u32 id, cccr;
+       int i;
 
        if (can_dropped_invalid_skb(dev, skb))
                return NETDEV_TX_OK;
@@ -976,11 +1062,28 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
 
        /* message ram configuration */
        m_can_fifo_write(priv, 0, M_CAN_FIFO_ID, id);
-       m_can_fifo_write(priv, 0, M_CAN_FIFO_DLC, cf->can_dlc << 16);
-       m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0), *(u32 *)(cf->data + 0));
-       m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1), *(u32 *)(cf->data + 4));
+       m_can_fifo_write(priv, 0, M_CAN_FIFO_DLC, can_len2dlc(cf->len) << 16);
+
+       for (i = 0; i < cf->len; i += 4)
+               m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(i / 4),
+                                *(u32 *)(cf->data + i));
+
        can_put_echo_skb(skb, dev, 0);
 
+       if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
+               cccr = m_can_read(priv, M_CAN_CCCR);
+               cccr &= ~(CCCR_CMR_MASK << CCCR_CMR_SHIFT);
+               if (can_is_canfd_skb(skb)) {
+                       if (cf->flags & CANFD_BRS)
+                               cccr |= CCCR_CMR_CANFD_BRS << CCCR_CMR_SHIFT;
+                       else
+                               cccr |= CCCR_CMR_CANFD << CCCR_CMR_SHIFT;
+               } else {
+                       cccr |= CCCR_CMR_CAN << CCCR_CMR_SHIFT;
+               }
+               m_can_write(priv, M_CAN_CCCR, cccr);
+       }
+
        /* enable first TX buffer to start transfer  */
        m_can_write(priv, M_CAN_TXBTIE, 0x1);
        m_can_write(priv, M_CAN_TXBAR, 0x1);
@@ -992,6 +1095,7 @@ static const struct net_device_ops m_can_netdev_ops = {
        .ndo_open = m_can_open,
        .ndo_stop = m_can_close,
        .ndo_start_xmit = m_can_start_xmit,
+       .ndo_change_mtu = can_change_mtu,
 };
 
 static int register_m_can_dev(struct net_device *dev)
@@ -1009,7 +1113,7 @@ static int m_can_of_parse_mram(struct platform_device *pdev,
        struct resource *res;
        void __iomem *addr;
        u32 out_val[MRAM_CFG_LEN];
-       int ret;
+       int i, start, end, ret;
 
        /* message ram could be shared */
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "message_ram");
@@ -1060,6 +1164,15 @@ static int m_can_of_parse_mram(struct platform_device *pdev,
                priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num,
                priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num);
 
+       /* initialize the entire Message RAM in use to avoid possible
+        * ECC/parity checksum errors when reading an uninitialized buffer
+        */
+       start = priv->mcfg[MRAM_SIDF].off;
+       end = priv->mcfg[MRAM_TXB].off +
+               priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE;
+       for (i = start; i < end; i += 4)
+               writel(0x0, priv->mram_base + i);
+
        return 0;
 }
 
index 1abe133d159428e0e098d611e8898bdaabb04c71..9718248e55f1e7c95c748b33538a4fb90a6f8d01 100644 (file)
@@ -628,6 +628,7 @@ static const struct net_device_ops rcar_can_netdev_ops = {
        .ndo_open = rcar_can_open,
        .ndo_stop = rcar_can_close,
        .ndo_start_xmit = rcar_can_start_xmit,
+       .ndo_change_mtu = can_change_mtu,
 };
 
 static void rcar_can_rx_pkt(struct rcar_can_priv *priv)
index 8ff3424d51472bc1df5753c025c6cd73f9ab1ed0..15c00faeec61001ab02c22689709efb523a96eb0 100644 (file)
@@ -214,7 +214,7 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel,
        struct net_device *dev;
        struct sja1000_priv *priv;
        struct kvaser_pci *board;
-       int err, init_step;
+       int err;
 
        dev = alloc_sja1000dev(sizeof(struct kvaser_pci));
        if (dev == NULL)
@@ -235,7 +235,6 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel,
        if (channel == 0) {
                board->xilinx_ver =
                        ioread8(board->res_addr + XILINX_VERINT) >> 4;
-               init_step = 2;
 
                /* Assert PTADR# - we're in passive mode so the other bits are
                   not important */
@@ -264,8 +263,6 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel,
        priv->irq_flags = IRQF_SHARED;
        dev->irq = pdev->irq;
 
-       init_step = 4;
-
        dev_info(&pdev->dev, "reg_base=%p conf_addr=%p irq=%d\n",
                 priv->reg_base, board->conf_addr, dev->irq);
 
index 00f2534dde736f1dd8cda9b016bd6a78f79eeab0..29d3f0938eb836b4da53a0898f574ebf42721ae2 100644 (file)
@@ -434,10 +434,9 @@ static void ems_usb_read_bulk_callback(struct urb *urb)
        if (urb->actual_length > CPC_HEADER_SIZE) {
                struct ems_cpc_msg *msg;
                u8 *ibuf = urb->transfer_buffer;
-               u8 msg_count, again, start;
+               u8 msg_count, start;
 
                msg_count = ibuf[0] & ~0x80;
-               again = ibuf[0] & 0x80;
 
                start = CPC_HEADER_SIZE;
 
index b7c9e8b11460a3d6bd0e4fe7836f0e07e73eb586..c063a54ab8dd8a598f36e5a7e712722bb5931df1 100644 (file)
@@ -464,7 +464,6 @@ static void esd_usb2_write_bulk_callback(struct urb *urb)
 {
        struct esd_tx_urb_context *context = urb->context;
        struct esd_usb2_net_priv *priv;
-       struct esd_usb2 *dev;
        struct net_device *netdev;
        size_t size = sizeof(struct esd_usb2_msg);
 
@@ -472,7 +471,6 @@ static void esd_usb2_write_bulk_callback(struct urb *urb)
 
        priv = context->priv;
        netdev = priv->netdev;
-       dev = priv->usb2;
 
        /* free up our allocated buffer */
        usb_free_coherent(urb->dev, size,
@@ -1143,6 +1141,7 @@ static void esd_usb2_disconnect(struct usb_interface *intf)
                        }
                }
                unlink_all_urbs(dev);
+               kfree(dev);
        }
 }
 
index 04b0f84612f0cf12fd1cfc59925a60c448423fa2..009acc8641fc557cb580cb688983daf041519e4b 100644 (file)
@@ -718,6 +718,7 @@ static const struct net_device_ops gs_usb_netdev_ops = {
        .ndo_open = gs_can_open,
        .ndo_stop = gs_can_close,
        .ndo_start_xmit = gs_can_start_xmit,
+       .ndo_change_mtu = can_change_mtu,
 };
 
 static struct gs_can *gs_make_candev(unsigned int channel, struct usb_interface *intf)
index 5e8b5609c067c53c2283a94dacd820fac8f1c565..8a998e3884ce0d502d9ebb19e7abde941ab85d3e 100644 (file)
@@ -300,7 +300,8 @@ static int xcan_set_bittiming(struct net_device *ndev)
 static int xcan_chip_start(struct net_device *ndev)
 {
        struct xcan_priv *priv = netdev_priv(ndev);
-       u32 err, reg_msr, reg_sr_mask;
+       u32 reg_msr, reg_sr_mask;
+       int err;
        unsigned long timeout;
 
        /* Check if it is in reset mode */
@@ -961,6 +962,7 @@ static const struct net_device_ops xcan_netdev_ops = {
        .ndo_open       = xcan_open,
        .ndo_stop       = xcan_close,
        .ndo_start_xmit = xcan_start_xmit,
+       .ndo_change_mtu = can_change_mtu,
 };
 
 /**
index cca6049940037331911ba26bb5fe4c35b48e5059..4fe33606f372755efb2bcef46f28c68b7d763312 100644 (file)
@@ -1082,7 +1082,7 @@ static int cxgb4_cee_peer_getpg(struct net_device *dev, struct cee_pg *pg)
        pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
 
        for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
-               pg->prio_pg[i] = (pgid >> (i * 4)) & 0xF;
+               pg->prio_pg[7 - i] = (pgid >> (i * 4)) & 0xF;
 
        INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
        pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
index d02fbc7694ea73ba8f958ee5a00807d1c663b15f..9070b98e15c4d34a7715f8a9b1752463a352466c 100644 (file)
@@ -4423,6 +4423,11 @@ static void be_del_vxlan_port(struct net_device *netdev, sa_family_t sa_family,
                 "Disabled VxLAN offloads for UDP port %d\n",
                 be16_to_cpu(port));
 }
+
+static bool be_gso_check(struct sk_buff *skb, struct net_device *dev)
+{
+       return vxlan_gso_check(skb);
+}
 #endif
 
 static const struct net_device_ops be_netdev_ops = {
@@ -4452,6 +4457,7 @@ static const struct net_device_ops be_netdev_ops = {
 #ifdef CONFIG_BE2NET_VXLAN
        .ndo_add_vxlan_port     = be_add_vxlan_port,
        .ndo_del_vxlan_port     = be_del_vxlan_port,
+       .ndo_gso_check          = be_gso_check,
 #endif
 };
 
index f3df9b350d87fadc8f6fc3c9037c48dedfd0ecdd..89440cb25ad8e932346ffd2d31a47e21b2e07fd6 100644 (file)
@@ -1693,7 +1693,7 @@ int mlx4_en_start_port(struct net_device *dev)
        mlx4_set_stats_bitmap(mdev->dev, &priv->stats_bitmap);
 
 #ifdef CONFIG_MLX4_EN_VXLAN
-       if (priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS)
+       if (priv->mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN)
                vxlan_get_rx_port(dev);
 #endif
        priv->port_up = true;
@@ -2365,6 +2365,11 @@ static void mlx4_en_del_vxlan_port(struct  net_device *dev,
 
        queue_work(priv->mdev->workqueue, &priv->vxlan_del_task);
 }
+
+static bool mlx4_en_gso_check(struct sk_buff *skb, struct net_device *dev)
+{
+       return vxlan_gso_check(skb);
+}
 #endif
 
 static const struct net_device_ops mlx4_netdev_ops = {
@@ -2396,6 +2401,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
 #ifdef CONFIG_MLX4_EN_VXLAN
        .ndo_add_vxlan_port     = mlx4_en_add_vxlan_port,
        .ndo_del_vxlan_port     = mlx4_en_del_vxlan_port,
+       .ndo_gso_check          = mlx4_en_gso_check,
 #endif
 };
 
@@ -2426,6 +2432,11 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
        .ndo_rx_flow_steer      = mlx4_en_filter_rfs,
 #endif
        .ndo_get_phys_port_id   = mlx4_en_get_phys_port_id,
+#ifdef CONFIG_MLX4_EN_VXLAN
+       .ndo_add_vxlan_port     = mlx4_en_add_vxlan_port,
+       .ndo_del_vxlan_port     = mlx4_en_del_vxlan_port,
+       .ndo_gso_check          = mlx4_en_gso_check,
+#endif
 };
 
 int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
index f5e29f7bdae39b77eed8abc0b8e73360ceeda698..a913b3ad2f899e791a9abd3c5e518d1f7410ceeb 100644 (file)
@@ -503,6 +503,11 @@ static void qlcnic_del_vxlan_port(struct net_device *netdev,
 
        adapter->flags |= QLCNIC_DEL_VXLAN_PORT;
 }
+
+static bool qlcnic_gso_check(struct sk_buff *skb, struct net_device *dev)
+{
+       return vxlan_gso_check(skb);
+}
 #endif
 
 static const struct net_device_ops qlcnic_netdev_ops = {
@@ -526,6 +531,7 @@ static const struct net_device_ops qlcnic_netdev_ops = {
 #ifdef CONFIG_QLCNIC_VXLAN
        .ndo_add_vxlan_port     = qlcnic_add_vxlan_port,
        .ndo_del_vxlan_port     = qlcnic_del_vxlan_port,
+       .ndo_gso_check          = qlcnic_gso_check,
 #endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller = qlcnic_poll_controller,
index d8794488f80a78cbc4171c7ac57d942eb36ab521..c560f9aeb55d691f23c65dae362c18defa1e9e44 100644 (file)
@@ -129,9 +129,9 @@ do {                                                                \
 #define CPSW_VLAN_AWARE                BIT(1)
 #define CPSW_ALE_VLAN_AWARE    1
 
-#define CPSW_FIFO_NORMAL_MODE          (0 << 15)
-#define CPSW_FIFO_DUAL_MAC_MODE                (1 << 15)
-#define CPSW_FIFO_RATE_LIMIT_MODE      (2 << 15)
+#define CPSW_FIFO_NORMAL_MODE          (0 << 16)
+#define CPSW_FIFO_DUAL_MAC_MODE                (1 << 16)
+#define CPSW_FIFO_RATE_LIMIT_MODE      (2 << 16)
 
 #define CPSW_INTPACEEN         (0x3f << 16)
 #define CPSW_INTPRESCALE_MASK  (0x7FF << 0)
index 1aff970be33ec88ec8ff6781467155f68cf5b3b4..1dc628ffce2b52a565354f060dca84467d67e4b9 100644 (file)
@@ -506,7 +506,9 @@ static int pptp_getname(struct socket *sock, struct sockaddr *uaddr,
        int len = sizeof(struct sockaddr_pppox);
        struct sockaddr_pppox sp;
 
-       sp.sa_family      = AF_PPPOX;
+       memset(&sp.sa_addr, 0, sizeof(sp.sa_addr));
+
+       sp.sa_family    = AF_PPPOX;
        sp.sa_protocol  = PX_PROTO_PPTP;
        sp.sa_addr.pptp = pppox_sk(sock->sk)->proto.pptp.src_addr;
 
index 22756db53dcacc3138fd000cad8dbda968948fb8..b8a82b86f909095632c7d5747b9bf25cb81c970e 100644 (file)
@@ -780,6 +780,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x413c, 0x81a4, 8)},    /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
        {QMI_FIXED_INTF(0x413c, 0x81a8, 8)},    /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */
        {QMI_FIXED_INTF(0x413c, 0x81a9, 8)},    /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
+       {QMI_FIXED_INTF(0x03f0, 0x581d, 4)},    /* HP lt4112 LTE/HSPA+ Gobi 4G Module (Huawei me906e) */
 
        /* 4. Gobi 1000 devices */
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},    /* Acer Gobi Modem Device */
index ec2a8b41ed41a1484c697f1897e0286f5d5d845a..b0bc8ead47de240c8f27605488eb300d0445c4fb 100644 (file)
@@ -1673,6 +1673,40 @@ static const struct attribute_group virtio_net_mrg_rx_group = {
 };
 #endif
 
+static bool virtnet_fail_on_feature(struct virtio_device *vdev,
+                                   unsigned int fbit,
+                                   const char *fname, const char *dname)
+{
+       if (!virtio_has_feature(vdev, fbit))
+               return false;
+
+       dev_err(&vdev->dev, "device advertises feature %s but not %s",
+               fname, dname);
+
+       return true;
+}
+
+#define VIRTNET_FAIL_ON(vdev, fbit, dbit)                      \
+       virtnet_fail_on_feature(vdev, fbit, #fbit, dbit)
+
+static bool virtnet_validate_features(struct virtio_device *vdev)
+{
+       if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ) &&
+           (VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_RX,
+                            "VIRTIO_NET_F_CTRL_VQ") ||
+            VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_VLAN,
+                            "VIRTIO_NET_F_CTRL_VQ") ||
+            VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_GUEST_ANNOUNCE,
+                            "VIRTIO_NET_F_CTRL_VQ") ||
+            VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_MQ, "VIRTIO_NET_F_CTRL_VQ") ||
+            VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR,
+                            "VIRTIO_NET_F_CTRL_VQ"))) {
+               return false;
+       }
+
+       return true;
+}
+
 static int virtnet_probe(struct virtio_device *vdev)
 {
        int i, err;
@@ -1680,6 +1714,9 @@ static int virtnet_probe(struct virtio_device *vdev)
        struct virtnet_info *vi;
        u16 max_queue_pairs;
 
+       if (!virtnet_validate_features(vdev))
+               return -EINVAL;
+
        /* Find if host supports multiqueue virtio_net device */
        err = virtio_cread_feature(vdev, VIRTIO_NET_F_MQ,
                                   struct virtio_net_config,
index 64d45fa3d99787eb64c05cd36d3931b7e8cd545f..e9f81d4636598f681f40cce219d41937140278d8 100644 (file)
 
 #define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */
 
-/* VXLAN protocol header */
-struct vxlanhdr {
-       __be32 vx_flags;
-       __be32 vx_vni;
-};
-
 /* UDP port for VXLAN traffic.
  * The IANA assigned port is 4789, but the Linux default is 8472
  * for compatibility with early adopters.
index 7c63976b5b0c4182c9fe72284a3c6860ff3b0630..ebbbfc7a193b00b3250b20334bfd12cb55ad2ee1 100644 (file)
@@ -996,9 +996,8 @@ void ath9k_calculate_iter_data(struct ath_softc *sc,
        struct ath_vif *avp;
 
        /*
-        * Pick the MAC address of the first interface as the new hardware
-        * MAC address. The hardware will use it together with the BSSID mask
-        * when matching addresses.
+        * The hardware will use primary station addr together with the
+        * BSSID mask when matching addresses.
         */
        memset(iter_data, 0, sizeof(*iter_data));
        memset(&iter_data->mask, 0xff, ETH_ALEN);
@@ -1228,6 +1227,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
                list_add_tail(&avp->list, &avp->chanctx->vifs);
        }
 
+       ath9k_calculate_summary_state(sc, avp->chanctx);
+
        ath9k_assign_hw_queues(hw, vif);
 
        an->sc = sc;
@@ -1297,6 +1298,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
 
        ath_tx_node_cleanup(sc, &avp->mcast_node);
 
+       ath9k_calculate_summary_state(sc, avp->chanctx);
+
        mutex_unlock(&sc->mutex);
 }
 
index eb3fce82a2231612b4b4c1a3991ef84b24d103db..c824570ddea3208b1f20230a6eecbc193dd68c50 100644 (file)
@@ -40,8 +40,8 @@ void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev)
                return;
 
        irq = irq_of_parse_and_map(np, 0);
-       if (irq < 0) {
-               brcmf_err("interrupt could not be mapped: err=%d\n", irq);
+       if (!irq) {
+               brcmf_err("interrupt could not be mapped\n");
                devm_kfree(dev, sdiodev->pdata);
                return;
        }
index b0ae7993e2e885d6ce81da3a2a8c9a1b95f5d009..138691a1365af6534b0458bf3b0bc44066372059 100644 (file)
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
-#include <linux/unaligned/access_ok.h>
 #include <linux/interrupt.h>
 #include <linux/bcma/bcma.h>
 #include <linux/sched.h>
+#include <asm/unaligned.h>
 
 #include <soc.h>
 #include <chipcommon.h>
index 5265aa70b094f3a3ae541532056e9ff5ad76a75c..4572defc280fa42e7100115540a32581912bf2e2 100644 (file)
@@ -738,10 +738,12 @@ static int brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
                goto finalize;
        }
 
-       if (!brcmf_usb_ioctl_resp_wait(devinfo))
+       if (!brcmf_usb_ioctl_resp_wait(devinfo)) {
+               usb_kill_urb(devinfo->ctl_urb);
                ret = -ETIMEDOUT;
-       else
+       } else {
                memcpy(buffer, tmpbuf, buflen);
+       }
 
 finalize:
        kfree(tmpbuf);
index afdb78299f61f8d5465ec1d203d482d0674fe31d..06af494184d657456df3c353b9e61e380ec98dec 100644 (file)
@@ -450,6 +450,21 @@ static struct of_bus *of_match_bus(struct device_node *np)
        return NULL;
 }
 
+static int of_empty_ranges_quirk(void)
+{
+       if (IS_ENABLED(CONFIG_PPC)) {
+               /* To save cycles, we cache the result */
+               static int quirk_state = -1;
+
+               if (quirk_state < 0)
+                       quirk_state =
+                               of_machine_is_compatible("Power Macintosh") ||
+                               of_machine_is_compatible("MacRISC");
+               return quirk_state;
+       }
+       return false;
+}
+
 static int of_translate_one(struct device_node *parent, struct of_bus *bus,
                            struct of_bus *pbus, __be32 *addr,
                            int na, int ns, int pna, const char *rprop)
@@ -475,12 +490,10 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
         * This code is only enabled on powerpc. --gcl
         */
        ranges = of_get_property(parent, rprop, &rlen);
-#if !defined(CONFIG_PPC)
-       if (ranges == NULL) {
+       if (ranges == NULL && !of_empty_ranges_quirk()) {
                pr_err("OF: no ranges; cannot translate\n");
                return 1;
        }
-#endif /* !defined(CONFIG_PPC) */
        if (ranges == NULL || rlen == 0) {
                offset = of_read_number(addr, na);
                memset(addr, 0, pna * 4);
index f297891d852908ae3e78fe9bfa2bfe5b231875e6..d4994177dec25506e454bf1556050ffc2754d084 100644 (file)
@@ -247,7 +247,7 @@ void of_node_release(struct kobject *kobj)
  * @allocflags:        Allocation flags (typically pass GFP_KERNEL)
  *
  * Copy a property by dynamically allocating the memory of both the
- * property stucture and the property name & contents. The property's
+ * property structure and the property name & contents. The property's
  * flags have the OF_DYNAMIC bit set so that we can differentiate between
  * dynamically allocated properties and not.
  * Returns the newly allocated property or NULL on out of memory error.
index d1ffca8b34eac51853c812a230cfd438862f8cff..30e97bcc4f88293ff902df937446d0983db6d4f3 100644 (file)
@@ -773,7 +773,7 @@ int __init early_init_dt_scan_chosen_serial(void)
        if (offset < 0)
                return -ENODEV;
 
-       while (match->compatible) {
+       while (match->compatible[0]) {
                unsigned long addr;
                if (fdt_node_check_compatible(fdt, offset, match->compatible)) {
                        match++;
index 11b873c54a776c5fd819d05875fce54b6d00f9ce..e2d79afa9dc6153613c4281570eb620332249c8c 100644 (file)
@@ -896,10 +896,14 @@ static void selftest_data_remove(void)
                return;
        }
 
-       while (last_node_index >= 0) {
+       while (last_node_index-- > 0) {
                if (nodes[last_node_index]) {
                        np = of_find_node_by_path(nodes[last_node_index]->full_name);
-                       if (strcmp(np->full_name, "/aliases") != 0) {
+                       if (np == nodes[last_node_index]) {
+                               if (of_aliases == np) {
+                                       of_node_put(of_aliases);
+                                       of_aliases = NULL;
+                               }
                                detach_node_and_children(np);
                        } else {
                                for_each_property_of_node(np, prop) {
@@ -908,7 +912,6 @@ static void selftest_data_remove(void)
                                }
                        }
                }
-               last_node_index--;
        }
 }
 
@@ -921,6 +924,8 @@ static int __init of_selftest(void)
        res = selftest_data_add();
        if (res)
                return res;
+       if (!of_aliases)
+               of_aliases = of_find_node_by_path("/aliases");
 
        np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
        if (!np) {
index d292d7cb3417062643379805a969f5d29718de2f..49dd766852ba58f5ebad21199e38f1e2a912b498 100644 (file)
@@ -444,7 +444,7 @@ static inline int pcie_cap_version(const struct pci_dev *dev)
        return pcie_caps_reg(dev) & PCI_EXP_FLAGS_VERS;
 }
 
-static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
+bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
 {
        int type = pci_pcie_type(dev);
 
index 9ecabfa8c6343a83afba9d33b101bc4161b6bd3f..2988fe136c1e3ede0240e90db80d6e4e013e6e8a 100644 (file)
@@ -631,10 +631,15 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       bus = pci_scan_root_bus(&pdev->dev, 0, &xgene_pcie_ops, port, &res);
+       bus = pci_create_root_bus(&pdev->dev, 0,
+                                       &xgene_pcie_ops, port, &res);
        if (!bus)
                return -ENOMEM;
 
+       pci_scan_child_bus(bus);
+       pci_assign_unassigned_bus_resources(bus);
+       pci_bus_add_devices(bus);
+
        platform_set_drvdata(pdev, port);
        return 0;
 }
index 0601890db22de96131af2d67fd872651ab608133..4a3902d8e6fec7984bb483b55aee4115101cc1f4 100644 (file)
@@ -6,6 +6,8 @@
 
 extern const unsigned char pcie_link_speed[];
 
+bool pcie_cap_has_lnkctl(const struct pci_dev *dev);
+
 /* Functions internal to the PCI core code */
 
 int pci_create_sysfs_dev_files(struct pci_dev *pdev);
index 5ed99309c75800938b666c5c523d7ea3ca07d51f..c8ca98c2b480a41d57676ef21e97cd6612134110 100644 (file)
@@ -407,15 +407,16 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
 {
        struct pci_dev *dev = child->self;
        u16 mem_base_lo, mem_limit_lo;
-       unsigned long base, limit;
+       u64 base64, limit64;
+       dma_addr_t base, limit;
        struct pci_bus_region region;
        struct resource *res;
 
        res = child->resource[2];
        pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
        pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);
-       base = ((unsigned long) mem_base_lo & PCI_PREF_RANGE_MASK) << 16;
-       limit = ((unsigned long) mem_limit_lo & PCI_PREF_RANGE_MASK) << 16;
+       base64 = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16;
+       limit64 = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16;
 
        if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
                u32 mem_base_hi, mem_limit_hi;
@@ -429,17 +430,20 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
                 * this, just assume they are not being used.
                 */
                if (mem_base_hi <= mem_limit_hi) {
-#if BITS_PER_LONG == 64
-                       base |= ((unsigned long) mem_base_hi) << 32;
-                       limit |= ((unsigned long) mem_limit_hi) << 32;
-#else
-                       if (mem_base_hi || mem_limit_hi) {
-                               dev_err(&dev->dev, "can't handle 64-bit address space for bridge\n");
-                               return;
-                       }
-#endif
+                       base64 |= (u64) mem_base_hi << 32;
+                       limit64 |= (u64) mem_limit_hi << 32;
                }
        }
+
+       base = (dma_addr_t) base64;
+       limit = (dma_addr_t) limit64;
+
+       if (base != base64) {
+               dev_err(&dev->dev, "can't handle bridge window above 4GB (bus address %#010llx)\n",
+                       (unsigned long long) base64);
+               return;
+       }
+
        if (base <= limit) {
                res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) |
                                         IORESOURCE_MEM | IORESOURCE_PREFETCH;
@@ -1323,7 +1327,7 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
                        ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or);
 
        /* Initialize Link Control Register */
-       if (dev->subordinate)
+       if (pcie_cap_has_lnkctl(dev))
                pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
                        ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or);
 
index 4dcfb7116a0487656bf489a45c6345c18ea1e219..a2eabe6ff9ada9b7bff3991a0116c8137a78b92d 100644 (file)
@@ -202,6 +202,7 @@ config TC1100_WMI
 config HP_ACCEL
        tristate "HP laptop accelerometer"
        depends on INPUT && ACPI
+       depends on SERIO_I8042
        select SENSORS_LIS3LV02D
        select NEW_LEDS
        select LEDS_CLASS
index 13e14ec1d3d7118c4e4ab63ac98a2ef0c1258118..6bec745b6b92dc6e3f849a12da003b639d1900ed 100644 (file)
@@ -37,6 +37,8 @@
 #include <linux/leds.h>
 #include <linux/atomic.h>
 #include <linux/acpi.h>
+#include <linux/i8042.h>
+#include <linux/serio.h>
 #include "../../misc/lis3lv02d/lis3lv02d.h"
 
 #define DRIVER_NAME     "hp_accel"
@@ -73,6 +75,13 @@ static inline void delayed_sysfs_set(struct led_classdev *led_cdev,
 
 /* HP-specific accelerometer driver ------------------------------------ */
 
+/* e0 25, e0 26, e0 27, e0 28 are scan codes that the accelerometer with acpi id
+ * HPQ6000 sends through the keyboard bus */
+#define ACCEL_1 0x25
+#define ACCEL_2 0x26
+#define ACCEL_3 0x27
+#define ACCEL_4 0x28
+
 /* For automatic insertion of the module */
 static const struct acpi_device_id lis3lv02d_device_ids[] = {
        {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */
@@ -294,6 +303,35 @@ static void lis3lv02d_enum_resources(struct acpi_device *device)
                printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n");
 }
 
+static bool hp_accel_i8042_filter(unsigned char data, unsigned char str,
+                                 struct serio *port)
+{
+       static bool extended;
+
+       if (str & I8042_STR_AUXDATA)
+               return false;
+
+       if (data == 0xe0) {
+               extended = true;
+               return true;
+       } else if (unlikely(extended)) {
+               extended = false;
+
+               switch (data) {
+               case ACCEL_1:
+               case ACCEL_2:
+               case ACCEL_3:
+               case ACCEL_4:
+                       return true;
+               default:
+                       serio_interrupt(port, 0xe0, 0);
+                       return false;
+               }
+       }
+
+       return false;
+}
+
 static int lis3lv02d_add(struct acpi_device *device)
 {
        int ret;
@@ -326,6 +364,11 @@ static int lis3lv02d_add(struct acpi_device *device)
        if (ret)
                return ret;
 
+       /* filter to remove HPQ6000 accelerometer data
+        * from keyboard bus stream */
+       if (strstr(dev_name(&device->dev), "HPQ6000"))
+               i8042_install_filter(hp_accel_i8042_filter);
+
        INIT_WORK(&hpled_led.work, delayed_set_status_worker);
        ret = led_classdev_register(NULL, &hpled_led.led_classdev);
        if (ret) {
@@ -343,6 +386,7 @@ static int lis3lv02d_remove(struct acpi_device *device)
        if (!device)
                return -EINVAL;
 
+       i8042_remove_filter(hp_accel_i8042_filter);
        lis3lv02d_joystick_disable(&lis3_dev);
        lis3lv02d_poweroff(&lis3_dev);
 
index 217da4b2ca8639ee5f2d5ced62615bfc558aed4f..99a78d365ceb11f2c3c6308296f62ce4db6c2a5d 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/time.h>
+#include <linux/time64.h>
 #include <linux/of.h>
 #include <linux/completion.h>
 #include <linux/mfd/core.h>
@@ -108,7 +109,7 @@ enum ab8500_fg_calibration_state {
 struct ab8500_fg_avg_cap {
        int avg;
        int samples[NBR_AVG_SAMPLES];
-       __kernel_time_t time_stamps[NBR_AVG_SAMPLES];
+       time64_t time_stamps[NBR_AVG_SAMPLES];
        int pos;
        int nbr_samples;
        int sum;
@@ -386,15 +387,15 @@ static int ab8500_fg_is_low_curr(struct ab8500_fg *di, int curr)
  */
 static int ab8500_fg_add_cap_sample(struct ab8500_fg *di, int sample)
 {
-       struct timespec ts;
+       struct timespec64 ts64;
        struct ab8500_fg_avg_cap *avg = &di->avg_cap;
 
-       getnstimeofday(&ts);
+       getnstimeofday64(&ts64);
 
        do {
                avg->sum += sample - avg->samples[avg->pos];
                avg->samples[avg->pos] = sample;
-               avg->time_stamps[avg->pos] = ts.tv_sec;
+               avg->time_stamps[avg->pos] = ts64.tv_sec;
                avg->pos++;
 
                if (avg->pos == NBR_AVG_SAMPLES)
@@ -407,7 +408,7 @@ static int ab8500_fg_add_cap_sample(struct ab8500_fg *di, int sample)
                 * Check the time stamp for each sample. If too old,
                 * replace with latest sample
                 */
-       } while (ts.tv_sec - VALID_CAPACITY_SEC > avg->time_stamps[avg->pos]);
+       } while (ts64.tv_sec - VALID_CAPACITY_SEC > avg->time_stamps[avg->pos]);
 
        avg->avg = avg->sum / avg->nbr_samples;
 
@@ -446,14 +447,14 @@ static void ab8500_fg_clear_cap_samples(struct ab8500_fg *di)
 static void ab8500_fg_fill_cap_sample(struct ab8500_fg *di, int sample)
 {
        int i;
-       struct timespec ts;
+       struct timespec64 ts64;
        struct ab8500_fg_avg_cap *avg = &di->avg_cap;
 
-       getnstimeofday(&ts);
+       getnstimeofday64(&ts64);
 
        for (i = 0; i < NBR_AVG_SAMPLES; i++) {
                avg->samples[i] = sample;
-               avg->time_stamps[i] = ts.tv_sec;
+               avg->time_stamps[i] = ts64.tv_sec;
        }
 
        avg->pos = 0;
index e384844a1ae1957ffd3687e7f54d0ff3eba2b59f..1f49986fc6057c8c4db858735ec8d9fd38326f8a 100644 (file)
@@ -1579,8 +1579,15 @@ static int bq2415x_probe(struct i2c_client *client,
        if (np) {
                bq->notify_psy = power_supply_get_by_phandle(np, "ti,usb-charger-detection");
 
-               if (!bq->notify_psy)
-                       return -EPROBE_DEFER;
+               if (IS_ERR(bq->notify_psy)) {
+                       dev_info(&client->dev,
+                               "no 'ti,usb-charger-detection' property (err=%ld)\n",
+                               PTR_ERR(bq->notify_psy));
+                       bq->notify_psy = NULL;
+               } else if (!bq->notify_psy) {
+                       ret = -EPROBE_DEFER;
+                       goto error_2;
+               }
        }
        else if (pdata->notify_device)
                bq->notify_psy = power_supply_get_by_name(pdata->notify_device);
@@ -1602,27 +1609,27 @@ static int bq2415x_probe(struct i2c_client *client,
                ret = of_property_read_u32(np, "ti,current-limit",
                                &bq->init_data.current_limit);
                if (ret)
-                       return ret;
+                       goto error_2;
                ret = of_property_read_u32(np, "ti,weak-battery-voltage",
                                &bq->init_data.weak_battery_voltage);
                if (ret)
-                       return ret;
+                       goto error_2;
                ret = of_property_read_u32(np, "ti,battery-regulation-voltage",
                                &bq->init_data.battery_regulation_voltage);
                if (ret)
-                       return ret;
+                       goto error_2;
                ret = of_property_read_u32(np, "ti,charge-current",
                                &bq->init_data.charge_current);
                if (ret)
-                       return ret;
+                       goto error_2;
                ret = of_property_read_u32(np, "ti,termination-current",
                                &bq->init_data.termination_current);
                if (ret)
-                       return ret;
+                       goto error_2;
                ret = of_property_read_u32(np, "ti,resistor-sense",
                                &bq->init_data.resistor_sense);
                if (ret)
-                       return ret;
+                       goto error_2;
        } else {
                memcpy(&bq->init_data, pdata, sizeof(bq->init_data));
        }
index 7098a1ce2d3c1068e2ef6cc5fbbe4d185ece9850..ef8094a61f1e91caa16fdcb204ce4ced9485334e 100644 (file)
@@ -97,6 +97,7 @@ static struct charger_global_desc *g_desc; /* init with setup_charger_manager */
 static bool is_batt_present(struct charger_manager *cm)
 {
        union power_supply_propval val;
+       struct power_supply *psy;
        bool present = false;
        int i, ret;
 
@@ -107,16 +108,27 @@ static bool is_batt_present(struct charger_manager *cm)
        case CM_NO_BATTERY:
                break;
        case CM_FUEL_GAUGE:
-               ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+               psy = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
+               if (!psy)
+                       break;
+
+               ret = psy->get_property(psy,
                                POWER_SUPPLY_PROP_PRESENT, &val);
                if (ret == 0 && val.intval)
                        present = true;
                break;
        case CM_CHARGER_STAT:
-               for (i = 0; cm->charger_stat[i]; i++) {
-                       ret = cm->charger_stat[i]->get_property(
-                                       cm->charger_stat[i],
-                                       POWER_SUPPLY_PROP_PRESENT, &val);
+               for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
+                       psy = power_supply_get_by_name(
+                                       cm->desc->psy_charger_stat[i]);
+                       if (!psy) {
+                               dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
+                                       cm->desc->psy_charger_stat[i]);
+                               continue;
+                       }
+
+                       ret = psy->get_property(psy, POWER_SUPPLY_PROP_PRESENT,
+                                       &val);
                        if (ret == 0 && val.intval) {
                                present = true;
                                break;
@@ -139,14 +151,20 @@ static bool is_batt_present(struct charger_manager *cm)
 static bool is_ext_pwr_online(struct charger_manager *cm)
 {
        union power_supply_propval val;
+       struct power_supply *psy;
        bool online = false;
        int i, ret;
 
        /* If at least one of them has one, it's yes. */
-       for (i = 0; cm->charger_stat[i]; i++) {
-               ret = cm->charger_stat[i]->get_property(
-                               cm->charger_stat[i],
-                               POWER_SUPPLY_PROP_ONLINE, &val);
+       for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
+               psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]);
+               if (!psy) {
+                       dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
+                                       cm->desc->psy_charger_stat[i]);
+                       continue;
+               }
+
+               ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val);
                if (ret == 0 && val.intval) {
                        online = true;
                        break;
@@ -167,12 +185,14 @@ static bool is_ext_pwr_online(struct charger_manager *cm)
 static int get_batt_uV(struct charger_manager *cm, int *uV)
 {
        union power_supply_propval val;
+       struct power_supply *fuel_gauge;
        int ret;
 
-       if (!cm->fuel_gauge)
+       fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
+       if (!fuel_gauge)
                return -ENODEV;
 
-       ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+       ret = fuel_gauge->get_property(fuel_gauge,
                                POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
        if (ret)
                return ret;
@@ -189,6 +209,7 @@ static bool is_charging(struct charger_manager *cm)
 {
        int i, ret;
        bool charging = false;
+       struct power_supply *psy;
        union power_supply_propval val;
 
        /* If there is no battery, it cannot be charged */
@@ -196,17 +217,22 @@ static bool is_charging(struct charger_manager *cm)
                return false;
 
        /* If at least one of the charger is charging, return yes */
-       for (i = 0; cm->charger_stat[i]; i++) {
+       for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
                /* 1. The charger sholuld not be DISABLED */
                if (cm->emergency_stop)
                        continue;
                if (!cm->charger_enabled)
                        continue;
 
+               psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]);
+               if (!psy) {
+                       dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
+                                       cm->desc->psy_charger_stat[i]);
+                       continue;
+               }
+
                /* 2. The charger should be online (ext-power) */
-               ret = cm->charger_stat[i]->get_property(
-                               cm->charger_stat[i],
-                               POWER_SUPPLY_PROP_ONLINE, &val);
+               ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val);
                if (ret) {
                        dev_warn(cm->dev, "Cannot read ONLINE value from %s\n",
                                 cm->desc->psy_charger_stat[i]);
@@ -219,9 +245,7 @@ static bool is_charging(struct charger_manager *cm)
                 * 3. The charger should not be FULL, DISCHARGING,
                 * or NOT_CHARGING.
                 */
-               ret = cm->charger_stat[i]->get_property(
-                               cm->charger_stat[i],
-                               POWER_SUPPLY_PROP_STATUS, &val);
+               ret = psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &val);
                if (ret) {
                        dev_warn(cm->dev, "Cannot read STATUS value from %s\n",
                                 cm->desc->psy_charger_stat[i]);
@@ -248,6 +272,7 @@ static bool is_full_charged(struct charger_manager *cm)
 {
        struct charger_desc *desc = cm->desc;
        union power_supply_propval val;
+       struct power_supply *fuel_gauge;
        int ret = 0;
        int uV;
 
@@ -255,11 +280,15 @@ static bool is_full_charged(struct charger_manager *cm)
        if (!is_batt_present(cm))
                return false;
 
-       if (cm->fuel_gauge && desc->fullbatt_full_capacity > 0) {
+       fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
+       if (!fuel_gauge)
+               return false;
+
+       if (desc->fullbatt_full_capacity > 0) {
                val.intval = 0;
 
                /* Not full if capacity of fuel gauge isn't full */
-               ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+               ret = fuel_gauge->get_property(fuel_gauge,
                                POWER_SUPPLY_PROP_CHARGE_FULL, &val);
                if (!ret && val.intval > desc->fullbatt_full_capacity)
                        return true;
@@ -273,10 +302,10 @@ static bool is_full_charged(struct charger_manager *cm)
        }
 
        /* Full, if the capacity is more than fullbatt_soc */
-       if (cm->fuel_gauge && desc->fullbatt_soc > 0) {
+       if (desc->fullbatt_soc > 0) {
                val.intval = 0;
 
-               ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+               ret = fuel_gauge->get_property(fuel_gauge,
                                POWER_SUPPLY_PROP_CAPACITY, &val);
                if (!ret && val.intval >= desc->fullbatt_soc)
                        return true;
@@ -551,6 +580,20 @@ static int check_charging_duration(struct charger_manager *cm)
        return ret;
 }
 
+static int cm_get_battery_temperature_by_psy(struct charger_manager *cm,
+                                       int *temp)
+{
+       struct power_supply *fuel_gauge;
+
+       fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
+       if (!fuel_gauge)
+               return -ENODEV;
+
+       return fuel_gauge->get_property(fuel_gauge,
+                               POWER_SUPPLY_PROP_TEMP,
+                               (union power_supply_propval *)temp);
+}
+
 static int cm_get_battery_temperature(struct charger_manager *cm,
                                        int *temp)
 {
@@ -560,15 +603,18 @@ static int cm_get_battery_temperature(struct charger_manager *cm,
                return -ENODEV;
 
 #ifdef CONFIG_THERMAL
-       ret = thermal_zone_get_temp(cm->tzd_batt, (unsigned long *)temp);
-       if (!ret)
-               /* Calibrate temperature unit */
-               *temp /= 100;
-#else
-       ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
-                               POWER_SUPPLY_PROP_TEMP,
-                               (union power_supply_propval *)temp);
+       if (cm->tzd_batt) {
+               ret = thermal_zone_get_temp(cm->tzd_batt, (unsigned long *)temp);
+               if (!ret)
+                       /* Calibrate temperature unit */
+                       *temp /= 100;
+       } else
 #endif
+       {
+               /* if-else continued from CONFIG_THERMAL */
+               ret = cm_get_battery_temperature_by_psy(cm, temp);
+       }
+
        return ret;
 }
 
@@ -827,6 +873,7 @@ static int charger_get_property(struct power_supply *psy,
        struct charger_manager *cm = container_of(psy,
                        struct charger_manager, charger_psy);
        struct charger_desc *desc = cm->desc;
+       struct power_supply *fuel_gauge;
        int ret = 0;
        int uV;
 
@@ -857,14 +904,20 @@ static int charger_get_property(struct power_supply *psy,
                ret = get_batt_uV(cm, &val->intval);
                break;
        case POWER_SUPPLY_PROP_CURRENT_NOW:
-               ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+               fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
+               if (!fuel_gauge) {
+                       ret = -ENODEV;
+                       break;
+               }
+               ret = fuel_gauge->get_property(fuel_gauge,
                                POWER_SUPPLY_PROP_CURRENT_NOW, val);
                break;
        case POWER_SUPPLY_PROP_TEMP:
        case POWER_SUPPLY_PROP_TEMP_AMBIENT:
                return cm_get_battery_temperature(cm, &val->intval);
        case POWER_SUPPLY_PROP_CAPACITY:
-               if (!cm->fuel_gauge) {
+               fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
+               if (!fuel_gauge) {
                        ret = -ENODEV;
                        break;
                }
@@ -875,7 +928,7 @@ static int charger_get_property(struct power_supply *psy,
                        break;
                }
 
-               ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+               ret = fuel_gauge->get_property(fuel_gauge,
                                        POWER_SUPPLY_PROP_CAPACITY, val);
                if (ret)
                        break;
@@ -924,7 +977,14 @@ static int charger_get_property(struct power_supply *psy,
                break;
        case POWER_SUPPLY_PROP_CHARGE_NOW:
                if (is_charging(cm)) {
-                       ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+                       fuel_gauge = power_supply_get_by_name(
+                                       cm->desc->psy_fuel_gauge);
+                       if (!fuel_gauge) {
+                               ret = -ENODEV;
+                               break;
+                       }
+
+                       ret = fuel_gauge->get_property(fuel_gauge,
                                                POWER_SUPPLY_PROP_CHARGE_NOW,
                                                val);
                        if (ret) {
@@ -970,6 +1030,7 @@ static struct power_supply psy_default = {
        .properties = default_charger_props,
        .num_properties = ARRAY_SIZE(default_charger_props),
        .get_property = charger_get_property,
+       .no_thermal = true,
 };
 
 /**
@@ -1485,14 +1546,15 @@ err:
        return ret;
 }
 
-static int cm_init_thermal_data(struct charger_manager *cm)
+static int cm_init_thermal_data(struct charger_manager *cm,
+               struct power_supply *fuel_gauge)
 {
        struct charger_desc *desc = cm->desc;
        union power_supply_propval val;
        int ret;
 
        /* Verify whether fuel gauge provides battery temperature */
-       ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+       ret = fuel_gauge->get_property(fuel_gauge,
                                        POWER_SUPPLY_PROP_TEMP, &val);
 
        if (!ret) {
@@ -1502,8 +1564,6 @@ static int cm_init_thermal_data(struct charger_manager *cm)
                cm->desc->measure_battery_temp = true;
        }
 #ifdef CONFIG_THERMAL
-       cm->tzd_batt = cm->fuel_gauge->tzd;
-
        if (ret && desc->thermal_zone) {
                cm->tzd_batt =
                        thermal_zone_get_zone_by_name(desc->thermal_zone);
@@ -1666,6 +1726,7 @@ static int charger_manager_probe(struct platform_device *pdev)
        int ret = 0, i = 0;
        int j = 0;
        union power_supply_propval val;
+       struct power_supply *fuel_gauge;
 
        if (g_desc && !rtc_dev && g_desc->rtc_name) {
                rtc_dev = rtc_class_open(g_desc->rtc_name);
@@ -1729,23 +1790,20 @@ static int charger_manager_probe(struct platform_device *pdev)
        while (desc->psy_charger_stat[i])
                i++;
 
-       cm->charger_stat = devm_kzalloc(&pdev->dev,
-                               sizeof(struct power_supply *) * i, GFP_KERNEL);
-       if (!cm->charger_stat)
-               return -ENOMEM;
-
+       /* Check if charger's supplies are present at probe */
        for (i = 0; desc->psy_charger_stat[i]; i++) {
-               cm->charger_stat[i] = power_supply_get_by_name(
-                                       desc->psy_charger_stat[i]);
-               if (!cm->charger_stat[i]) {
+               struct power_supply *psy;
+
+               psy = power_supply_get_by_name(desc->psy_charger_stat[i]);
+               if (!psy) {
                        dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
                                desc->psy_charger_stat[i]);
                        return -ENODEV;
                }
        }
 
-       cm->fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
-       if (!cm->fuel_gauge) {
+       fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
+       if (!fuel_gauge) {
                dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
                        desc->psy_fuel_gauge);
                return -ENODEV;
@@ -1788,13 +1846,13 @@ static int charger_manager_probe(struct platform_device *pdev)
        cm->charger_psy.num_properties = psy_default.num_properties;
 
        /* Find which optional psy-properties are available */
-       if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
+       if (!fuel_gauge->get_property(fuel_gauge,
                                          POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {
                cm->charger_psy.properties[cm->charger_psy.num_properties] =
                                POWER_SUPPLY_PROP_CHARGE_NOW;
                cm->charger_psy.num_properties++;
        }
-       if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
+       if (!fuel_gauge->get_property(fuel_gauge,
                                          POWER_SUPPLY_PROP_CURRENT_NOW,
                                          &val)) {
                cm->charger_psy.properties[cm->charger_psy.num_properties] =
@@ -1802,7 +1860,7 @@ static int charger_manager_probe(struct platform_device *pdev)
                cm->charger_psy.num_properties++;
        }
 
-       ret = cm_init_thermal_data(cm);
+       ret = cm_init_thermal_data(cm, fuel_gauge);
        if (ret) {
                dev_err(&pdev->dev, "Failed to initialize thermal data\n");
                cm->desc->measure_battery_temp = false;
@@ -2066,8 +2124,8 @@ static bool find_power_supply(struct charger_manager *cm,
        int i;
        bool found = false;
 
-       for (i = 0; cm->charger_stat[i]; i++) {
-               if (psy == cm->charger_stat[i]) {
+       for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
+               if (!strcmp(psy->name, cm->desc->psy_charger_stat[i])) {
                        found = true;
                        break;
                }
index 6cb7fe5c022d48ca237e31eb89e78f8f70665776..694e8cddd5c13e1760e7c9cd5fc0170876a9df04 100644 (file)
@@ -417,6 +417,9 @@ static int psy_register_thermal(struct power_supply *psy)
 {
        int i;
 
+       if (psy->no_thermal)
+               return 0;
+
        /* Register battery zone device psy reports temperature */
        for (i = 0; i < psy->num_properties; i++) {
                if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) {
index ca75c7ca25590cdb15ae562bd9bd87cd28fcce9b..ef355c13ccc47c9a9f05cde438408e4e56b3eb3d 100644 (file)
@@ -480,9 +480,7 @@ void bnx2fc_rec_compl(struct bnx2fc_els_cb_arg *cb_arg)
                        bnx2fc_initiate_cleanup(orig_io_req);
                        /* Post a new IO req with the same sc_cmd */
                        BNX2FC_IO_DBG(rec_req, "Post IO request again\n");
-                       spin_unlock_bh(&tgt->tgt_lock);
                        rc = bnx2fc_post_io_req(tgt, new_io_req);
-                       spin_lock_bh(&tgt->tgt_lock);
                        if (!rc)
                                goto free_frame;
                        BNX2FC_IO_DBG(rec_req, "REC: io post err\n");
index 0679782d9d15e05b5d536c95b25dd643249f142e..5b99844ef6bf73209518c8e586825bbc1486866e 100644 (file)
@@ -1894,18 +1894,24 @@ int bnx2fc_queuecommand(struct Scsi_Host *host,
                        goto exit_qcmd;
                }
        }
+
+       spin_lock_bh(&tgt->tgt_lock);
+
        io_req = bnx2fc_cmd_alloc(tgt);
        if (!io_req) {
                rc = SCSI_MLQUEUE_HOST_BUSY;
-               goto exit_qcmd;
+               goto exit_qcmd_tgtlock;
        }
        io_req->sc_cmd = sc_cmd;
 
        if (bnx2fc_post_io_req(tgt, io_req)) {
                printk(KERN_ERR PFX "Unable to post io_req\n");
                rc = SCSI_MLQUEUE_HOST_BUSY;
-               goto exit_qcmd;
+               goto exit_qcmd_tgtlock;
        }
+
+exit_qcmd_tgtlock:
+       spin_unlock_bh(&tgt->tgt_lock);
 exit_qcmd:
        return rc;
 }
@@ -2020,6 +2026,8 @@ int bnx2fc_post_io_req(struct bnx2fc_rport *tgt,
        int task_idx, index;
        u16 xid;
 
+       /* bnx2fc_post_io_req() is called with the tgt_lock held */
+
        /* Initialize rest of io_req fields */
        io_req->cmd_type = BNX2FC_SCSI_CMD;
        io_req->port = port;
@@ -2047,9 +2055,7 @@ int bnx2fc_post_io_req(struct bnx2fc_rport *tgt,
        /* Build buffer descriptor list for firmware from sg list */
        if (bnx2fc_build_bd_list_from_sg(io_req)) {
                printk(KERN_ERR PFX "BD list creation failed\n");
-               spin_lock_bh(&tgt->tgt_lock);
                kref_put(&io_req->refcount, bnx2fc_cmd_release);
-               spin_unlock_bh(&tgt->tgt_lock);
                return -EAGAIN;
        }
 
@@ -2061,19 +2067,15 @@ int bnx2fc_post_io_req(struct bnx2fc_rport *tgt,
        task = &(task_page[index]);
        bnx2fc_init_task(io_req, task);
 
-       spin_lock_bh(&tgt->tgt_lock);
-
        if (tgt->flush_in_prog) {
                printk(KERN_ERR PFX "Flush in progress..Host Busy\n");
                kref_put(&io_req->refcount, bnx2fc_cmd_release);
-               spin_unlock_bh(&tgt->tgt_lock);
                return -EAGAIN;
        }
 
        if (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) {
                printk(KERN_ERR PFX "Session not ready...post_io\n");
                kref_put(&io_req->refcount, bnx2fc_cmd_release);
-               spin_unlock_bh(&tgt->tgt_lock);
                return -EAGAIN;
        }
 
@@ -2091,6 +2093,5 @@ int bnx2fc_post_io_req(struct bnx2fc_rport *tgt,
 
        /* Ring doorbell */
        bnx2fc_ring_doorbell(tgt);
-       spin_unlock_bh(&tgt->tgt_lock);
        return 0;
 }
index ed0e16866dc7e0a27d93c070fe0570c3a99e50b1..dd5f4e088efe82e77245ce2c029fe4de96a3b1f9 100644 (file)
@@ -830,6 +830,8 @@ static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
        if (status == CPL_ERR_RTX_NEG_ADVICE)
                goto rel_skb;
 
+       module_put(THIS_MODULE);
+
        if (status && status != CPL_ERR_TCAM_FULL &&
            status != CPL_ERR_CONN_EXIST &&
            status != CPL_ERR_ARP_MISS)
@@ -938,20 +940,23 @@ static void do_abort_req_rss(struct cxgbi_device *cdev, struct sk_buff *skb)
        cxgbi_sock_get(csk);
        spin_lock_bh(&csk->lock);
 
-       if (!cxgbi_sock_flag(csk, CTPF_ABORT_REQ_RCVD)) {
-               cxgbi_sock_set_flag(csk, CTPF_ABORT_REQ_RCVD);
-               cxgbi_sock_set_state(csk, CTP_ABORTING);
-               goto done;
+       cxgbi_sock_clear_flag(csk, CTPF_ABORT_REQ_RCVD);
+
+       if (!cxgbi_sock_flag(csk, CTPF_TX_DATA_SENT)) {
+               send_tx_flowc_wr(csk);
+               cxgbi_sock_set_flag(csk, CTPF_TX_DATA_SENT);
        }
 
-       cxgbi_sock_clear_flag(csk, CTPF_ABORT_REQ_RCVD);
+       cxgbi_sock_set_flag(csk, CTPF_ABORT_REQ_RCVD);
+       cxgbi_sock_set_state(csk, CTP_ABORTING);
+
        send_abort_rpl(csk, rst_status);
 
        if (!cxgbi_sock_flag(csk, CTPF_ABORT_RPL_PENDING)) {
                csk->err = abort_status_to_errno(csk, req->status, &rst_status);
                cxgbi_sock_closed(csk);
        }
-done:
+
        spin_unlock_bh(&csk->lock);
        cxgbi_sock_put(csk);
 rel_skb:
index 674d498b46ab0ba380655fa4e9649b3fabf5e49d..7da59c38a69ec97cf15507876122151222e52fe1 100644 (file)
@@ -816,7 +816,7 @@ static void cxgbi_inform_iscsi_conn_closing(struct cxgbi_sock *csk)
                read_lock_bh(&csk->callback_lock);
                if (csk->user_data)
                        iscsi_conn_failure(csk->user_data,
-                                       ISCSI_ERR_CONN_FAILED);
+                                       ISCSI_ERR_TCP_CONN_CLOSE);
                read_unlock_bh(&csk->callback_lock);
        }
 }
@@ -905,18 +905,16 @@ void cxgbi_sock_rcv_abort_rpl(struct cxgbi_sock *csk)
 {
        cxgbi_sock_get(csk);
        spin_lock_bh(&csk->lock);
+
+       cxgbi_sock_set_flag(csk, CTPF_ABORT_RPL_RCVD);
        if (cxgbi_sock_flag(csk, CTPF_ABORT_RPL_PENDING)) {
-               if (!cxgbi_sock_flag(csk, CTPF_ABORT_RPL_RCVD))
-                       cxgbi_sock_set_flag(csk, CTPF_ABORT_RPL_RCVD);
-               else {
-                       cxgbi_sock_clear_flag(csk, CTPF_ABORT_RPL_RCVD);
-                       cxgbi_sock_clear_flag(csk, CTPF_ABORT_RPL_PENDING);
-                       if (cxgbi_sock_flag(csk, CTPF_ABORT_REQ_RCVD))
-                               pr_err("csk 0x%p,%u,0x%lx,%u,ABT_RPL_RSS.\n",
-                                       csk, csk->state, csk->flags, csk->tid);
-                       cxgbi_sock_closed(csk);
-               }
+               cxgbi_sock_clear_flag(csk, CTPF_ABORT_RPL_PENDING);
+               if (cxgbi_sock_flag(csk, CTPF_ABORT_REQ_RCVD))
+                       pr_err("csk 0x%p,%u,0x%lx,%u,ABT_RPL_RSS.\n",
+                              csk, csk->state, csk->flags, csk->tid);
+               cxgbi_sock_closed(csk);
        }
+
        spin_unlock_bh(&csk->lock);
        cxgbi_sock_put(csk);
 }
index e99507ed0e3c9ab5ad36cf19f26814d61a78ec76..fd78bdc535280a0eebcefc527221ebf091300e8f 100644 (file)
@@ -474,6 +474,13 @@ static int alua_check_sense(struct scsi_device *sdev,
                         * LUN Not Ready -- Offline
                         */
                        return SUCCESS;
+               if (sdev->allow_restart &&
+                   sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x02)
+                       /*
+                        * if the device is not started, we need to wake
+                        * the error handler to start the motor
+                        */
+                       return FAILED;
                break;
        case UNIT_ATTENTION:
                if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00)
index f6a69a3b1b3f0c8fb1bd805e8970beb2800feaef..5640ad1c8214eb9d12cd4f1495d20ad5c1cc1984 100644 (file)
@@ -4453,7 +4453,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
                        instance->msixentry[i].entry = i;
                i = pci_enable_msix_range(instance->pdev, instance->msixentry,
                                          1, instance->msix_vectors);
-               if (i)
+               if (i > 0)
                        instance->msix_vectors = i;
                else
                        instance->msix_vectors = 0;
index 9a6f8468225f372bae07f36d4779f8c19f27c6e3..bc5ff6ff9c796bfa9101ba7d73b4e834af9d0b33 100644 (file)
@@ -459,14 +459,6 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
        if (! scsi_command_normalize_sense(scmd, &sshdr))
                return FAILED;  /* no valid sense data */
 
-       if (scmd->cmnd[0] == TEST_UNIT_READY && scmd->scsi_done != scsi_eh_done)
-               /*
-                * nasty: for mid-layer issued TURs, we need to return the
-                * actual sense data without any recovery attempt.  For eh
-                * issued ones, we need to try to recover and interpret
-                */
-               return SUCCESS;
-
        scsi_report_sense(sdev, &sshdr);
 
        if (scsi_sense_is_deferred(&sshdr))
@@ -482,6 +474,14 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
                /* handler does not care. Drop down to default handling */
        }
 
+       if (scmd->cmnd[0] == TEST_UNIT_READY && scmd->scsi_done != scsi_eh_done)
+               /*
+                * nasty: for mid-layer issued TURs, we need to return the
+                * actual sense data without any recovery attempt.  For eh
+                * issued ones, we need to try to recover and interpret
+                */
+               return SUCCESS;
+
        /*
         * Previous logic looked for FILEMARK, EOM or ILI which are
         * mainly associated with tapes and returned SUCCESS.
@@ -2001,8 +2001,10 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
         * is no point trying to lock the door of an off-line device.
         */
        shost_for_each_device(sdev, shost) {
-               if (scsi_device_online(sdev) && sdev->locked)
+               if (scsi_device_online(sdev) && sdev->was_reset && sdev->locked) {
                        scsi_eh_lock_door(sdev);
+                       sdev->was_reset = 0;
+               }
        }
 
        /*
index b19e4329ba00739503215124ec768e8c99d843c3..73e58d22e325d8780d17470a9a9851a732669f89 100644 (file)
@@ -3491,7 +3491,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
                                len = sprintf(buf, "TargetAddress="
                                        "%s:%hu,%hu",
                                        inaddr_any ? conn->local_ip : np->np_ip,
-                                       inaddr_any ? conn->local_port : np->np_port,
+                                       np->np_port,
                                        tpg->tpgt);
                                len += 1;
 
index 8c60a1a1ae8dab96a63a382b572ecb7e83e1baf6..9f93b82340952d452ffe4807be7e06082c1e535a 100644 (file)
@@ -2738,7 +2738,8 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
        struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder;
        struct t10_reservation *pr_tmpl = &dev->t10_pr;
        u32 pr_res_mapped_lun = 0;
-       int all_reg = 0, calling_it_nexus = 0, released_regs = 0;
+       int all_reg = 0, calling_it_nexus = 0;
+       bool sa_res_key_unmatched = sa_res_key != 0;
        int prh_type = 0, prh_scope = 0;
 
        if (!se_sess)
@@ -2813,6 +2814,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
                        if (!all_reg) {
                                if (pr_reg->pr_res_key != sa_res_key)
                                        continue;
+                               sa_res_key_unmatched = false;
 
                                calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
                                pr_reg_nacl = pr_reg->pr_reg_nacl;
@@ -2820,7 +2822,6 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
                                __core_scsi3_free_registration(dev, pr_reg,
                                        (preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list :
                                                NULL, calling_it_nexus);
-                               released_regs++;
                        } else {
                                /*
                                 * Case for any existing all registrants type
@@ -2838,6 +2839,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
                                if ((sa_res_key) &&
                                     (pr_reg->pr_res_key != sa_res_key))
                                        continue;
+                               sa_res_key_unmatched = false;
 
                                calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
                                if (calling_it_nexus)
@@ -2848,7 +2850,6 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
                                __core_scsi3_free_registration(dev, pr_reg,
                                        (preempt_type == PREEMPT_AND_ABORT) ? &preempt_and_abort_list :
                                                NULL, 0);
-                               released_regs++;
                        }
                        if (!calling_it_nexus)
                                core_scsi3_ua_allocate(pr_reg_nacl,
@@ -2863,7 +2864,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
                 * registered reservation key, then the device server shall
                 * complete the command with RESERVATION CONFLICT status.
                 */
-               if (!released_regs) {
+               if (sa_res_key_unmatched) {
                        spin_unlock(&dev->dev_reservation_lock);
                        core_scsi3_put_pr_reg(pr_reg_n);
                        return TCM_RESERVATION_CONFLICT;
index 9ea0d5f03f7a566fbbe4191a93ad1312cbcfa5af..be877bf6f7304a88fabb3506d65ac75542471b01 100644 (file)
@@ -2292,7 +2292,7 @@ transport_generic_new_cmd(struct se_cmd *cmd)
         * and let it call back once the write buffers are ready.
         */
        target_add_to_state_list(cmd);
-       if (cmd->data_direction != DMA_TO_DEVICE) {
+       if (cmd->data_direction != DMA_TO_DEVICE || cmd->data_length == 0) {
                target_execute_cmd(cmd);
                return 0;
        }
index 69906cacd04fdc8b3d5236dc030e8bcf749c541f..a17f11850669b461130610692d558dd7e499258b 100644 (file)
@@ -1312,6 +1312,7 @@ static int
 vhost_scsi_set_endpoint(struct vhost_scsi *vs,
                        struct vhost_scsi_target *t)
 {
+       struct se_portal_group *se_tpg;
        struct tcm_vhost_tport *tv_tport;
        struct tcm_vhost_tpg *tpg;
        struct tcm_vhost_tpg **vs_tpg;
@@ -1359,6 +1360,21 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
                                ret = -EEXIST;
                                goto out;
                        }
+                       /*
+                        * In order to ensure individual vhost-scsi configfs
+                        * groups cannot be removed while in use by vhost ioctl,
+                        * go ahead and take an explicit se_tpg->tpg_group.cg_item
+                        * dependency now.
+                        */
+                       se_tpg = &tpg->se_tpg;
+                       ret = configfs_depend_item(se_tpg->se_tpg_tfo->tf_subsys,
+                                                  &se_tpg->tpg_group.cg_item);
+                       if (ret) {
+                               pr_warn("configfs_depend_item() failed: %d\n", ret);
+                               kfree(vs_tpg);
+                               mutex_unlock(&tpg->tv_tpg_mutex);
+                               goto out;
+                       }
                        tpg->tv_tpg_vhost_count++;
                        tpg->vhost_scsi = vs;
                        vs_tpg[tpg->tport_tpgt] = tpg;
@@ -1401,6 +1417,7 @@ static int
 vhost_scsi_clear_endpoint(struct vhost_scsi *vs,
                          struct vhost_scsi_target *t)
 {
+       struct se_portal_group *se_tpg;
        struct tcm_vhost_tport *tv_tport;
        struct tcm_vhost_tpg *tpg;
        struct vhost_virtqueue *vq;
@@ -1449,6 +1466,13 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs,
                vs->vs_tpg[target] = NULL;
                match = true;
                mutex_unlock(&tpg->tv_tpg_mutex);
+               /*
+                * Release se_tpg->tpg_group.cg_item configfs dependency now
+                * to allow vhost-scsi WWPN se_tpg->tpg_group shutdown to occur.
+                */
+               se_tpg = &tpg->se_tpg;
+               configfs_undepend_item(se_tpg->se_tpg_tfo->tf_subsys,
+                                      &se_tpg->tpg_group.cg_item);
        }
        if (match) {
                for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) {
index 5228f201d3d53ed93966bc99e682077b9c78f107..4f46f7a05289ba957e219df793b68dfa2f037bb5 100644 (file)
@@ -378,7 +378,7 @@ bl_write_pagelist(struct nfs_pgio_header *header, int sync)
        loff_t offset = header->args.offset;
        size_t count = header->args.count;
        struct page **pages = header->args.pages;
-       int pg_index = pg_index = header->args.pgbase >> PAGE_CACHE_SHIFT;
+       int pg_index = header->args.pgbase >> PAGE_CACHE_SHIFT;
        unsigned int pg_len;
        struct blk_plug plug;
        int i;
index e966c023b1b74df4161461a7cad843e6b9bcfbda..acbf9ca4018ccb6c7cd3bf6d6281ae566cbe4448 100644 (file)
@@ -65,17 +65,18 @@ bl_resolve_deviceid(struct nfs_server *server, struct pnfs_block_volume *b,
 
        dprintk("%s CREATING PIPEFS MESSAGE\n", __func__);
 
+       mutex_lock(&nn->bl_mutex);
        bl_pipe_msg.bl_wq = &nn->bl_wq;
 
        b->simple.len += 4;     /* single volume */
        if (b->simple.len > PAGE_SIZE)
-               return -EIO;
+               goto out_unlock;
 
        memset(msg, 0, sizeof(*msg));
        msg->len = sizeof(*bl_msg) + b->simple.len;
        msg->data = kzalloc(msg->len, gfp_mask);
        if (!msg->data)
-               goto out;
+               goto out_free_data;
 
        bl_msg = msg->data;
        bl_msg->type = BL_DEVICE_MOUNT,
@@ -87,7 +88,7 @@ bl_resolve_deviceid(struct nfs_server *server, struct pnfs_block_volume *b,
        rc = rpc_queue_upcall(nn->bl_device_pipe, msg);
        if (rc < 0) {
                remove_wait_queue(&nn->bl_wq, &wq);
-               goto out;
+               goto out_free_data;
        }
 
        set_current_state(TASK_UNINTERRUPTIBLE);
@@ -97,12 +98,14 @@ bl_resolve_deviceid(struct nfs_server *server, struct pnfs_block_volume *b,
        if (reply->status != BL_DEVICE_REQUEST_PROC) {
                printk(KERN_WARNING "%s failed to decode device: %d\n",
                        __func__, reply->status);
-               goto out;
+               goto out_free_data;
        }
 
        dev = MKDEV(reply->major, reply->minor);
-out:
+out_free_data:
        kfree(msg->data);
+out_unlock:
+       mutex_unlock(&nn->bl_mutex);
        return dev;
 }
 
@@ -232,6 +235,7 @@ static int nfs4blocklayout_net_init(struct net *net)
        struct nfs_net *nn = net_generic(net, nfs_net_id);
        struct dentry *dentry;
 
+       mutex_init(&nn->bl_mutex);
        init_waitqueue_head(&nn->bl_wq);
        nn->bl_device_pipe = rpc_mkpipe_data(&bl_upcall_ops, 0);
        if (IS_ERR(nn->bl_device_pipe))
index 5853f53db73246df670ce9daedb73e10d62d2da3..7f3f60641344437ab4f493eebf6093e39957c3be 100644 (file)
@@ -125,6 +125,8 @@ again:
                        continue;
                if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
                        continue;
+               if (!nfs4_valid_open_stateid(state))
+                       continue;
                if (!nfs4_stateid_match(&state->stateid, stateid))
                        continue;
                get_nfs_open_context(ctx);
@@ -193,7 +195,11 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *
 {
        int res = 0;
 
-       res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid, issync);
+       if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
+               res = nfs4_proc_delegreturn(inode,
+                               delegation->cred,
+                               &delegation->stateid,
+                               issync);
        nfs_free_delegation(delegation);
        return res;
 }
@@ -380,11 +386,13 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation
 {
        struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
        struct nfs_inode *nfsi = NFS_I(inode);
-       int err;
+       int err = 0;
 
        if (delegation == NULL)
                return 0;
        do {
+               if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
+                       break;
                err = nfs_delegation_claim_opens(inode, &delegation->stateid);
                if (!issync || err != -EAGAIN)
                        break;
@@ -605,10 +613,23 @@ static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *cl
        rcu_read_unlock();
 }
 
+static void nfs_revoke_delegation(struct inode *inode)
+{
+       struct nfs_delegation *delegation;
+       rcu_read_lock();
+       delegation = rcu_dereference(NFS_I(inode)->delegation);
+       if (delegation != NULL) {
+               set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
+               nfs_mark_return_delegation(NFS_SERVER(inode), delegation);
+       }
+       rcu_read_unlock();
+}
+
 void nfs_remove_bad_delegation(struct inode *inode)
 {
        struct nfs_delegation *delegation;
 
+       nfs_revoke_delegation(inode);
        delegation = nfs_inode_detach_delegation(inode);
        if (delegation) {
                nfs_inode_find_state_and_recover(inode, &delegation->stateid);
index 5c1cce39297f68fb178b4a125a83001aeac4afde..e3c20a3ccc937453b678e9bb02d1a46827f11be0 100644 (file)
@@ -31,6 +31,7 @@ enum {
        NFS_DELEGATION_RETURN_IF_CLOSED,
        NFS_DELEGATION_REFERENCED,
        NFS_DELEGATION_RETURNING,
+       NFS_DELEGATION_REVOKED,
 };
 
 int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
index 06e8cfcbb67053759d9b2b17e4c68a4547b257da..6e62155abf26d43c242c6e7de7250c120a5f1567 100644 (file)
@@ -1527,6 +1527,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
                case -ENOENT:
                        d_drop(dentry);
                        d_add(dentry, NULL);
+                       nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
                        break;
                case -EISDIR:
                case -ENOTDIR:
index 20cffc830468d993b7222a05eba469a6637d09fa..10bf07280f4ab2715845003334b73d80bde15f44 100644 (file)
@@ -266,6 +266,7 @@ static void nfs_direct_req_free(struct kref *kref)
 {
        struct nfs_direct_req *dreq = container_of(kref, struct nfs_direct_req, kref);
 
+       nfs_free_pnfs_ds_cinfo(&dreq->ds_cinfo);
        if (dreq->l_ctx != NULL)
                nfs_put_lock_context(dreq->l_ctx);
        if (dreq->ctx != NULL)
index 46fab1cb455aa4b7deb177eb0e6bb87b786e06d9..7afb52f6a25a1b412bffac5829705bd8137eafbc 100644 (file)
@@ -145,9 +145,6 @@ static int filelayout_async_handle_error(struct rpc_task *task,
        case -NFS4ERR_DELEG_REVOKED:
        case -NFS4ERR_ADMIN_REVOKED:
        case -NFS4ERR_BAD_STATEID:
-               if (state == NULL)
-                       break;
-               nfs_remove_bad_delegation(state->inode);
        case -NFS4ERR_OPENMODE:
                if (state == NULL)
                        break;
index 6388a59f2add0683d759606c1925c35546e914c1..00689a8a85e44677d9a23c092b209ab6600928e4 100644 (file)
@@ -626,7 +626,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 {
        struct inode *inode = dentry->d_inode;
        int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
-       int err;
+       int err = 0;
 
        trace_nfs_getattr_enter(inode);
        /* Flush out writes to the server in order to update c/mtime.  */
index ef221fb8a18301d05282aa36a3c99ba2b1288b7c..f0e06e4acbef188988547eb4d8bf66178e6d3183 100644 (file)
@@ -19,6 +19,7 @@ struct nfs_net {
        struct rpc_pipe *bl_device_pipe;
        struct bl_dev_msg bl_mount_reply;
        wait_queue_head_t bl_wq;
+       struct mutex bl_mutex;
        struct list_head nfs_client_list;
        struct list_head nfs_volume_list;
 #if IS_ENABLED(CONFIG_NFS_V4)
index 405bd95c1f588739a511fb1566ed47f1513e696f..69dc20a743f9d35a8bc4b090b96e2c727c186e54 100644 (file)
@@ -370,11 +370,6 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
                case -NFS4ERR_DELEG_REVOKED:
                case -NFS4ERR_ADMIN_REVOKED:
                case -NFS4ERR_BAD_STATEID:
-                       if (inode != NULL && nfs4_have_delegation(inode, FMODE_READ)) {
-                               nfs_remove_bad_delegation(inode);
-                               exception->retry = 1;
-                               break;
-                       }
                        if (state == NULL)
                                break;
                        ret = nfs4_schedule_stateid_recovery(server, state);
@@ -1654,7 +1649,7 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
                        nfs_inode_find_state_and_recover(state->inode,
                                        stateid);
                        nfs4_schedule_stateid_recovery(server, state);
-                       return 0;
+                       return -EAGAIN;
                case -NFS4ERR_DELAY:
                case -NFS4ERR_GRACE:
                        set_bit(NFS_DELEGATED_STATE, &state->flags);
@@ -2109,46 +2104,60 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta
        return ret;
 }
 
+static void nfs_finish_clear_delegation_stateid(struct nfs4_state *state)
+{
+       nfs_remove_bad_delegation(state->inode);
+       write_seqlock(&state->seqlock);
+       nfs4_stateid_copy(&state->stateid, &state->open_stateid);
+       write_sequnlock(&state->seqlock);
+       clear_bit(NFS_DELEGATED_STATE, &state->flags);
+}
+
+static void nfs40_clear_delegation_stateid(struct nfs4_state *state)
+{
+       if (rcu_access_pointer(NFS_I(state->inode)->delegation) != NULL)
+               nfs_finish_clear_delegation_stateid(state);
+}
+
+static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
+{
+       /* NFSv4.0 doesn't allow for delegation recovery on open expire */
+       nfs40_clear_delegation_stateid(state);
+       return nfs4_open_expired(sp, state);
+}
+
 #if defined(CONFIG_NFS_V4_1)
-static void nfs41_clear_delegation_stateid(struct nfs4_state *state)
+static void nfs41_check_delegation_stateid(struct nfs4_state *state)
 {
        struct nfs_server *server = NFS_SERVER(state->inode);
-       nfs4_stateid *stateid = &state->stateid;
+       nfs4_stateid stateid;
        struct nfs_delegation *delegation;
-       struct rpc_cred *cred = NULL;
-       int status = -NFS4ERR_BAD_STATEID;
-
-       /* If a state reset has been done, test_stateid is unneeded */
-       if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
-               return;
+       struct rpc_cred *cred;
+       int status;
 
        /* Get the delegation credential for use by test/free_stateid */
        rcu_read_lock();
        delegation = rcu_dereference(NFS_I(state->inode)->delegation);
-       if (delegation != NULL &&
-           nfs4_stateid_match(&delegation->stateid, stateid)) {
-               cred = get_rpccred(delegation->cred);
-               rcu_read_unlock();
-               status = nfs41_test_stateid(server, stateid, cred);
-               trace_nfs4_test_delegation_stateid(state, NULL, status);
-       } else
+       if (delegation == NULL) {
                rcu_read_unlock();
+               return;
+       }
+
+       nfs4_stateid_copy(&stateid, &delegation->stateid);
+       cred = get_rpccred(delegation->cred);
+       rcu_read_unlock();
+       status = nfs41_test_stateid(server, &stateid, cred);
+       trace_nfs4_test_delegation_stateid(state, NULL, status);
 
        if (status != NFS_OK) {
                /* Free the stateid unless the server explicitly
                 * informs us the stateid is unrecognized. */
                if (status != -NFS4ERR_BAD_STATEID)
-                       nfs41_free_stateid(server, stateid, cred);
-               nfs_remove_bad_delegation(state->inode);
-
-               write_seqlock(&state->seqlock);
-               nfs4_stateid_copy(&state->stateid, &state->open_stateid);
-               write_sequnlock(&state->seqlock);
-               clear_bit(NFS_DELEGATED_STATE, &state->flags);
+                       nfs41_free_stateid(server, &stateid, cred);
+               nfs_finish_clear_delegation_stateid(state);
        }
 
-       if (cred != NULL)
-               put_rpccred(cred);
+       put_rpccred(cred);
 }
 
 /**
@@ -2192,7 +2201,7 @@ static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
 {
        int status;
 
-       nfs41_clear_delegation_stateid(state);
+       nfs41_check_delegation_stateid(state);
        status = nfs41_check_open_stateid(state);
        if (status != NFS_OK)
                status = nfs4_open_expired(sp, state);
@@ -2231,19 +2240,8 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
        seq = raw_seqcount_begin(&sp->so_reclaim_seqcount);
 
        ret = _nfs4_proc_open(opendata);
-       if (ret != 0) {
-               if (ret == -ENOENT) {
-                       dentry = opendata->dentry;
-                       if (dentry->d_inode)
-                               d_delete(dentry);
-                       else if (d_unhashed(dentry))
-                               d_add(dentry, NULL);
-
-                       nfs_set_verifier(dentry,
-                                        nfs_save_change_attribute(opendata->dir->d_inode));
-               }
+       if (ret != 0)
                goto out;
-       }
 
        state = nfs4_opendata_to_nfs4_state(opendata);
        ret = PTR_ERR(state);
@@ -4841,9 +4839,6 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
                case -NFS4ERR_DELEG_REVOKED:
                case -NFS4ERR_ADMIN_REVOKED:
                case -NFS4ERR_BAD_STATEID:
-                       if (state == NULL)
-                               break;
-                       nfs_remove_bad_delegation(state->inode);
                case -NFS4ERR_OPENMODE:
                        if (state == NULL)
                                break;
@@ -8341,7 +8336,7 @@ static const struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
 static const struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = {
        .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE,
        .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
-       .recover_open   = nfs4_open_expired,
+       .recover_open   = nfs40_open_expired,
        .recover_lock   = nfs4_lock_expired,
        .establish_clid = nfs4_init_clientid,
 };
@@ -8408,8 +8403,7 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
                | NFS_CAP_CHANGE_ATTR
                | NFS_CAP_POSIX_LOCK
                | NFS_CAP_STATEID_NFSV41
-               | NFS_CAP_ATOMIC_OPEN_V1
-               | NFS_CAP_SEEK,
+               | NFS_CAP_ATOMIC_OPEN_V1,
        .init_client = nfs41_init_client,
        .shutdown_client = nfs41_shutdown_client,
        .match_stateid = nfs41_match_stateid,
@@ -8431,7 +8425,8 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
                | NFS_CAP_CHANGE_ATTR
                | NFS_CAP_POSIX_LOCK
                | NFS_CAP_STATEID_NFSV41
-               | NFS_CAP_ATOMIC_OPEN_V1,
+               | NFS_CAP_ATOMIC_OPEN_V1
+               | NFS_CAP_SEEK,
        .init_client = nfs41_init_client,
        .shutdown_client = nfs41_shutdown_client,
        .match_stateid = nfs41_match_stateid,
index 12493846a2d3ccc68323f11e34a396bbb487fe22..f83b02dc9166d1aaf48b76f816f96a1b908bcec1 100644 (file)
@@ -715,8 +715,6 @@ static void nfs_inode_remove_request(struct nfs_page *req)
 
        if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags))
                nfs_release_request(req);
-       else
-               WARN_ON_ONCE(1);
 }
 
 static void
index 3d33794e4f3edd75950e58cb7d5c49f69e33795b..7448edff4723101b44877090ce9463bdb98d6d9c 100644 (file)
@@ -40,8 +40,8 @@
 
 /* Active pin states */
 #define PIN_OUTPUT             (0 | PULL_DIS)
-#define PIN_OUTPUT_PULLUP      (PIN_OUTPUT | PULL_ENA | PULL_UP)
-#define PIN_OUTPUT_PULLDOWN    (PIN_OUTPUT | PULL_ENA)
+#define PIN_OUTPUT_PULLUP      (PULL_UP)
+#define PIN_OUTPUT_PULLDOWN    (0)
 #define PIN_INPUT              (INPUT_EN | PULL_DIS)
 #define PIN_INPUT_SLEW         (INPUT_EN | SLEWCONTROL)
 #define PIN_INPUT_PULLUP       (PULL_ENA | INPUT_EN | PULL_UP)
index be5fd38bd5a05d83eaac250055defcccacafe054..5d858e02997f5248d8a50150d870248e8146f4e6 100644 (file)
  * position @h. For example
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
-#define GENMASK(h, l)          (((U32_C(1) << ((h) - (l) + 1)) - 1) << (l))
-#define GENMASK_ULL(h, l)      (((U64_C(1) << ((h) - (l) + 1)) - 1) << (l))
+#define GENMASK(h, l) \
+       (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
+
+#define GENMASK_ULL(h, l) \
+       (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
 
 extern unsigned int __sw_hweight8(unsigned int w);
 extern unsigned int __sw_hweight16(unsigned int w);
index 6992afc6ba7f96fda9dba202f771fe7e28f807fe..b37ea95bc348f15b16a9c0d095588379b12edbee 100644 (file)
@@ -99,6 +99,12 @@ inval_skb:
        return 1;
 }
 
+static inline bool can_is_canfd_skb(const struct sk_buff *skb)
+{
+       /* the CAN specific type of skb is identified by its data length */
+       return skb->len == CANFD_MTU;
+}
+
 /* get data length from can_dlc with sanitized can_dlc */
 u8 can_dlc2len(u8 can_dlc);
 
index 0068708161ffa6954f320d7de7d4ebb86dd2a889..0a21fbefdfbec1a693ed09c3d256b8059760655e 100644 (file)
@@ -242,7 +242,7 @@ static inline void in_dev_put(struct in_device *idev)
 static __inline__ __be32 inet_make_mask(int logmask)
 {
        if (logmask)
-               return htonl(~((1<<(32-logmask))-1));
+               return htonl(~((1U<<(32-logmask))-1));
        return 0;
 }
 
index 8422b4ed6882be8e8ece65f9a1bcd2ceb5af2bfb..b9376cd5a187e818c28c09935eb022a1920848a8 100644 (file)
@@ -77,11 +77,6 @@ static inline unsigned int kstat_cpu_irqs_sum(unsigned int cpu)
        return kstat_cpu(cpu).irqs_sum;
 }
 
-/*
- * Lock/unlock the current runqueue - to extract task statistics:
- */
-extern unsigned long long task_delta_exec(struct task_struct *);
-
 extern void account_user_time(struct task_struct *, cputime_t, cputime_t);
 extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t);
 extern void account_steal_time(cputime_t);
index 983876f24aed06ce26c7e33d8c83d77fa4736381..47ebb4fafd87f7ba0f37b36b22f54952f6f823c8 100644 (file)
@@ -1224,11 +1224,22 @@ struct nfs41_free_stateid_res {
        unsigned int                    status;
 };
 
+static inline void
+nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo)
+{
+       kfree(cinfo->buckets);
+}
+
 #else
 
 struct pnfs_ds_commit_info {
 };
 
+static inline void
+nfs_free_pnfs_ds_cinfo(struct pnfs_ds_commit_info *cinfo)
+{
+}
+
 #endif /* CONFIG_NFS_V4_1 */
 
 #ifdef CONFIG_NFS_V4_2
index 73e938b7e9374c68ac00fd99c65247eac9241fd4..2e0e06daf8c0692c16561eb35928b1502647f1ff 100644 (file)
@@ -72,8 +72,10 @@ struct generic_pm_domain {
        bool max_off_time_changed;
        bool cached_power_down_ok;
        struct gpd_cpuidle_data *cpuidle_data;
-       void (*attach_dev)(struct device *dev);
-       void (*detach_dev)(struct device *dev);
+       int (*attach_dev)(struct generic_pm_domain *domain,
+                         struct device *dev);
+       void (*detach_dev)(struct generic_pm_domain *domain,
+                          struct device *dev);
 };
 
 static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
@@ -104,7 +106,7 @@ struct generic_pm_domain_data {
        struct notifier_block nb;
        struct mutex lock;
        unsigned int refcount;
-       bool need_restore;
+       int need_restore;
 };
 
 #ifdef CONFIG_PM_GENERIC_DOMAINS
index 07e7945a1ff292048da586ac9709d17691a29fca..e97fc656a058c07d7c0c79a807cb3e04bec6dbf1 100644 (file)
@@ -253,9 +253,6 @@ struct charger_manager {
        struct device *dev;
        struct charger_desc *desc;
 
-       struct power_supply *fuel_gauge;
-       struct power_supply **charger_stat;
-
 #ifdef CONFIG_THERMAL
        struct thermal_zone_device *tzd_batt;
 #endif
index 3ed0496730229556921e3e77a5deeeecbb20bbac..096dbced02ac4b7cb9d18de6a8aa65e0592d78e9 100644 (file)
@@ -200,6 +200,12 @@ struct power_supply {
        void (*external_power_changed)(struct power_supply *psy);
        void (*set_charged)(struct power_supply *psy);
 
+       /*
+        * Set if thermal zone should not be created for this power supply.
+        * For example for virtual supplies forwarding calls to actual
+        * sensors or other supplies.
+        */
+       bool no_thermal;
        /* For APM emulation, think legacy userspace. */
        int use_for_apm;
 
index 845c596bf594c5ac297320c1a3dfe8f34cf702b4..3ae969e3acf016474413e1209381c60091befe1a 100644 (file)
@@ -396,14 +396,12 @@ struct nft_rule {
 /**
  *     struct nft_trans - nf_tables object update in transaction
  *
- *     @rcu_head: rcu head to defer release of transaction data
  *     @list: used internally
  *     @msg_type: message type
  *     @ctx: transaction context
  *     @data: internal information related to the transaction
  */
 struct nft_trans {
-       struct rcu_head                 rcu_head;
        struct list_head                list;
        int                             msg_type;
        struct nft_ctx                  ctx;
index d5f59f3fc35df67141c8234a8741ab5b49501ad1..57cccd0052e58dd124ec997174d8cd9ff885be99 100644 (file)
@@ -8,6 +8,12 @@
 #define VNI_HASH_BITS  10
 #define VNI_HASH_SIZE  (1<<VNI_HASH_BITS)
 
+/* VXLAN protocol header */
+struct vxlanhdr {
+       __be32 vx_flags;
+       __be32 vx_vni;
+};
+
 struct vxlan_sock;
 typedef void (vxlan_rcv_t)(struct vxlan_sock *vh, struct sk_buff *skb, __be32 key);
 
@@ -45,6 +51,18 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
                   __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
                   __be16 src_port, __be16 dst_port, __be32 vni, bool xnet);
 
+static inline bool vxlan_gso_check(struct sk_buff *skb)
+{
+       if ((skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) &&
+           (skb->inner_protocol_type != ENCAP_TYPE_ETHER ||
+            skb->inner_protocol != htons(ETH_P_TEB) ||
+            (skb_inner_mac_header(skb) - skb_transport_header(skb) !=
+             sizeof(struct udphdr) + sizeof(struct vxlanhdr))))
+               return false;
+
+       return true;
+}
+
 /* IP header + UDP + VXLAN + Ethernet header */
 #define VXLAN_HEADROOM (20 + 8 + 8 + 14)
 /* IPv6 header + UDP + VXLAN + Ethernet header */
index 2883a7a6f9f3a932b38843d20a8887986804fc00..98f2ade0266eb9a28ae6340b2908bd8fabea0eca 100644 (file)
@@ -102,6 +102,8 @@ struct snd_soc_dpcm_runtime {
        /* state and update */
        enum snd_soc_dpcm_update runtime_update;
        enum snd_soc_dpcm_state state;
+
+       int trigger_pending; /* trigger cmd + 1 if pending, 0 if not */
 };
 
 /* can this BE stop and free */
index 2b02c9fda790d667c29c304bca011901a4e30189..1cd5eef1fcddf3f53149522b0a482b7989e5a7a8 100644 (file)
@@ -1562,8 +1562,10 @@ static void perf_remove_from_context(struct perf_event *event, bool detach_group
 
        if (!task) {
                /*
-                * Per cpu events are removed via an smp call and
-                * the removal is always successful.
+                * Per cpu events are removed via an smp call. The removal can
+                * fail if the CPU is currently offline, but in that case we
+                * already called __perf_remove_from_context from
+                * perf_event_exit_cpu.
                 */
                cpu_function_call(event->cpu, __perf_remove_from_context, &re);
                return;
@@ -8117,7 +8119,7 @@ static void perf_pmu_rotate_stop(struct pmu *pmu)
 
 static void __perf_event_exit_context(void *__info)
 {
-       struct remove_event re = { .detach_group = false };
+       struct remove_event re = { .detach_group = true };
        struct perf_event_context *ctx = __info;
 
        perf_pmu_rotate_stop(ctx->pmu);
index 4ca9a33ff62020e63d15219ce9f097611ebf6507..c347e3ce3a55df9efe054caaffd08bed4bb9e886 100644 (file)
@@ -146,7 +146,7 @@ static int platform_suspend_prepare(suspend_state_t state)
 
 static int platform_suspend_prepare_late(suspend_state_t state)
 {
-       return state == PM_SUSPEND_FREEZE && freeze_ops->prepare ?
+       return state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->prepare ?
                freeze_ops->prepare() : 0;
 }
 
@@ -164,7 +164,7 @@ static void platform_resume_noirq(suspend_state_t state)
 
 static void platform_resume_early(suspend_state_t state)
 {
-       if (state == PM_SUSPEND_FREEZE && freeze_ops->restore)
+       if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->restore)
                freeze_ops->restore();
 }
 
index 240157c13ddc88508a4aafa87d8350394b38e94b..24beb9bb4c3e228ac17e8b931f37c44091987d18 100644 (file)
@@ -2474,44 +2474,6 @@ DEFINE_PER_CPU(struct kernel_cpustat, kernel_cpustat);
 EXPORT_PER_CPU_SYMBOL(kstat);
 EXPORT_PER_CPU_SYMBOL(kernel_cpustat);
 
-/*
- * Return any ns on the sched_clock that have not yet been accounted in
- * @p in case that task is currently running.
- *
- * Called with task_rq_lock() held on @rq.
- */
-static u64 do_task_delta_exec(struct task_struct *p, struct rq *rq)
-{
-       u64 ns = 0;
-
-       /*
-        * Must be ->curr _and_ ->on_rq.  If dequeued, we would
-        * project cycles that may never be accounted to this
-        * thread, breaking clock_gettime().
-        */
-       if (task_current(rq, p) && task_on_rq_queued(p)) {
-               update_rq_clock(rq);
-               ns = rq_clock_task(rq) - p->se.exec_start;
-               if ((s64)ns < 0)
-                       ns = 0;
-       }
-
-       return ns;
-}
-
-unsigned long long task_delta_exec(struct task_struct *p)
-{
-       unsigned long flags;
-       struct rq *rq;
-       u64 ns = 0;
-
-       rq = task_rq_lock(p, &flags);
-       ns = do_task_delta_exec(p, rq);
-       task_rq_unlock(rq, p, &flags);
-
-       return ns;
-}
-
 /*
  * Return accounted runtime for the task.
  * In case the task is currently running, return the runtime plus current's
@@ -2521,7 +2483,7 @@ unsigned long long task_sched_runtime(struct task_struct *p)
 {
        unsigned long flags;
        struct rq *rq;
-       u64 ns = 0;
+       u64 ns;
 
 #if defined(CONFIG_64BIT) && defined(CONFIG_SMP)
        /*
@@ -2540,7 +2502,16 @@ unsigned long long task_sched_runtime(struct task_struct *p)
 #endif
 
        rq = task_rq_lock(p, &flags);
-       ns = p->se.sum_exec_runtime + do_task_delta_exec(p, rq);
+       /*
+        * Must be ->curr _and_ ->on_rq.  If dequeued, we would
+        * project cycles that may never be accounted to this
+        * thread, breaking clock_gettime().
+        */
+       if (task_current(rq, p) && task_on_rq_queued(p)) {
+               update_rq_clock(rq);
+               p->sched_class->update_curr(rq);
+       }
+       ns = p->se.sum_exec_runtime;
        task_rq_unlock(rq, p, &flags);
 
        return ns;
@@ -6368,6 +6339,10 @@ static void sched_init_numa(void)
                if (!sched_debug())
                        break;
        }
+
+       if (!level)
+               return;
+
        /*
         * 'level' contains the number of unique distances, excluding the
         * identity distance node_distance(i,i).
@@ -7444,8 +7419,12 @@ void sched_move_task(struct task_struct *tsk)
        if (unlikely(running))
                put_prev_task(rq, tsk);
 
-       tg = container_of(task_css_check(tsk, cpu_cgrp_id,
-                               lockdep_is_held(&tsk->sighand->siglock)),
+       /*
+        * All callers are synchronized by task_rq_lock(); we do not use RCU
+        * which is pointless here. Thus, we pass "true" to task_css_check()
+        * to prevent lockdep warnings.
+        */
+       tg = container_of(task_css_check(tsk, cpu_cgrp_id, true),
                          struct task_group, css);
        tg = autogroup_task_group(tsk, tg);
        tsk->sched_task_group = tg;
index 5285332392d5b599788a90faa37615ccddc386d5..28fa9d9e92012a9245b2e95ce85bf301d320f8cc 100644 (file)
@@ -1701,4 +1701,6 @@ const struct sched_class dl_sched_class = {
        .prio_changed           = prio_changed_dl,
        .switched_from          = switched_from_dl,
        .switched_to            = switched_to_dl,
+
+       .update_curr            = update_curr_dl,
 };
index 34baa60f8a7bd11f03ccb1f754a08eb1029c46be..ef2b104b254cb8c60d954a92e62f0f8a626ed024 100644 (file)
@@ -726,6 +726,11 @@ static void update_curr(struct cfs_rq *cfs_rq)
        account_cfs_rq_runtime(cfs_rq, delta_exec);
 }
 
+static void update_curr_fair(struct rq *rq)
+{
+       update_curr(cfs_rq_of(&rq->curr->se));
+}
+
 static inline void
 update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
@@ -1179,6 +1184,13 @@ static void task_numa_compare(struct task_numa_env *env,
                cur = NULL;
        raw_spin_unlock_irq(&dst_rq->lock);
 
+       /*
+        * Because we have preemption enabled we can get migrated around and
+        * end try selecting ourselves (current == env->p) as a swap candidate.
+        */
+       if (cur == env->p)
+               goto unlock;
+
        /*
         * "imp" is the fault differential for the source task between the
         * source and destination node. Calculate the total differential for
@@ -7949,6 +7961,8 @@ const struct sched_class fair_sched_class = {
 
        .get_rr_interval        = get_rr_interval_fair,
 
+       .update_curr            = update_curr_fair,
+
 #ifdef CONFIG_FAIR_GROUP_SCHED
        .task_move_group        = task_move_group_fair,
 #endif
index d024e6ce30baf50037eac7c256dacc5bf27856f4..20bca398084ae770b36945e9aef238d954a6796e 100644 (file)
@@ -2128,6 +2128,8 @@ const struct sched_class rt_sched_class = {
 
        .prio_changed           = prio_changed_rt,
        .switched_to            = switched_to_rt,
+
+       .update_curr            = update_curr_rt,
 };
 
 #ifdef CONFIG_SCHED_DEBUG
index 24156c8434d1ebbe679a3fa6df45725aa7db3647..2df8ef067cc54ddd7a25c0b1cf45267214a2c31c 100644 (file)
@@ -1135,6 +1135,8 @@ struct sched_class {
        unsigned int (*get_rr_interval) (struct rq *rq,
                                         struct task_struct *task);
 
+       void (*update_curr) (struct rq *rq);
+
 #ifdef CONFIG_FAIR_GROUP_SCHED
        void (*task_move_group) (struct task_struct *p, int on_rq);
 #endif
index 492b986195d53350abe899b0ecd059f91edb77a4..a16b67859e2a79929331c5008f96fd7f29ebbfc1 100644 (file)
@@ -553,7 +553,7 @@ static int cpu_timer_sample_group(const clockid_t which_clock,
                *sample = cputime_to_expires(cputime.utime);
                break;
        case CPUCLOCK_SCHED:
-               *sample = cputime.sum_exec_runtime + task_delta_exec(p);
+               *sample = cputime.sum_exec_runtime;
                break;
        }
        return 0;
index 7512dc978f1872fe4a395868ed0f3cbd30de2ad0..0211d2bd5e17551856da7ca97aea0849528b2ead 100644 (file)
@@ -10,7 +10,7 @@ endif
 lib-y := ctype.o string.o vsprintf.o cmdline.o \
         rbtree.o radix-tree.o dump_stack.o timerqueue.o\
         idr.o int_sqrt.o extable.o \
-        sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \
+        sha1.o md5.o irq_regs.o argv_split.o \
         proportions.o flex_proportions.o ratelimit.o show_mem.o \
         is_single_threaded.o plist.o decompress.o kobject_uevent.o \
         earlycpio.o
@@ -26,7 +26,7 @@ obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
         bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
         gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \
         bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \
-        percpu-refcount.o percpu_ida.o hash.o rhashtable.o
+        percpu-refcount.o percpu_ida.o hash.o rhashtable.o reciprocal_div.o
 obj-y += string_helpers.o
 obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
 obj-y += kstrtox.o
index eafcf60f6b832b202a48f8a9ba66ac0d87989443..e34a3cb6aad6cb078c0801efc6891ba83f5db155 100644 (file)
@@ -911,9 +911,9 @@ size_t iov_iter_single_seg_count(const struct iov_iter *i)
        if (i->nr_segs == 1)
                return i->count;
        else if (i->type & ITER_BVEC)
-               return min(i->count, i->iov->iov_len - i->iov_offset);
-       else
                return min(i->count, i->bvec->bv_len - i->iov_offset);
+       else
+               return min(i->count, i->iov->iov_len - i->iov_offset);
 }
 EXPORT_SYMBOL(iov_iter_single_seg_count);
 
index 648d79ccf46244a5769c1703361cf35db4cfeb09..c465876c7861814ba545cf83783c7ba11bbd91eb 100644 (file)
@@ -813,10 +813,9 @@ static void __br_multicast_send_query(struct net_bridge *br,
                return;
 
        if (port) {
-               __skb_push(skb, sizeof(struct ethhdr));
                skb->dev = port->dev;
                NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
-                       dev_queue_xmit);
+                       br_dev_queue_push_xmit);
        } else {
                br_multicast_select_own_querier(br, ip, skb);
                netif_rx(skb);
index c906c5f4bf692518df26928ad54739cfdb1d358c..92116dfe827c08b756a1d3662f360e91a414987a 100644 (file)
@@ -552,20 +552,13 @@ static void kfree_skbmem(struct sk_buff *skb)
        case SKB_FCLONE_CLONE:
                fclones = container_of(skb, struct sk_buff_fclones, skb2);
 
-               /* Warning : We must perform the atomic_dec_and_test() before
-                * setting skb->fclone back to SKB_FCLONE_FREE, otherwise
-                * skb_clone() could set clone_ref to 2 before our decrement.
-                * Anyway, if we are going to free the structure, no need to
-                * rewrite skb->fclone.
+               /* The clone portion is available for
+                * fast-cloning again.
                 */
-               if (atomic_dec_and_test(&fclones->fclone_ref)) {
+               skb->fclone = SKB_FCLONE_FREE;
+
+               if (atomic_dec_and_test(&fclones->fclone_ref))
                        kmem_cache_free(skbuff_fclone_cache, fclones);
-               } else {
-                       /* The clone portion is available for
-                        * fast-cloning again.
-                        */
-                       skb->fclone = SKB_FCLONE_FREE;
-               }
                break;
        }
 }
@@ -887,11 +880,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
        if (skb->fclone == SKB_FCLONE_ORIG &&
            n->fclone == SKB_FCLONE_FREE) {
                n->fclone = SKB_FCLONE_CLONE;
-               /* As our fastclone was free, clone_ref must be 1 at this point.
-                * We could use atomic_inc() here, but it is faster
-                * to set the final value.
-                */
-               atomic_set(&fclones->fclone_ref, 2);
+               atomic_inc(&fclones->fclone_ref);
        } else {
                if (skb_pfmemalloc(skb))
                        gfp_mask |= __GFP_MEMALLOC;
index ca11d283bbebe3ae02345ecd72cb022ae7c43667..93ea80196f0ec383cca46d28bf8c4c96d0310b25 100644 (file)
@@ -1080,13 +1080,13 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
        if (!app)
                return -EMSGSIZE;
 
-       spin_lock(&dcb_lock);
+       spin_lock_bh(&dcb_lock);
        list_for_each_entry(itr, &dcb_app_list, list) {
                if (itr->ifindex == netdev->ifindex) {
                        err = nla_put(skb, DCB_ATTR_IEEE_APP, sizeof(itr->app),
                                         &itr->app);
                        if (err) {
-                               spin_unlock(&dcb_lock);
+                               spin_unlock_bh(&dcb_lock);
                                return -EMSGSIZE;
                        }
                }
@@ -1097,7 +1097,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
        else
                dcbx = -EOPNOTSUPP;
 
-       spin_unlock(&dcb_lock);
+       spin_unlock_bh(&dcb_lock);
        nla_nest_end(skb, app);
 
        /* get peer info if available */
@@ -1234,7 +1234,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
        }
 
        /* local app */
-       spin_lock(&dcb_lock);
+       spin_lock_bh(&dcb_lock);
        app = nla_nest_start(skb, DCB_ATTR_CEE_APP_TABLE);
        if (!app)
                goto dcb_unlock;
@@ -1271,7 +1271,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
        else
                dcbx = -EOPNOTSUPP;
 
-       spin_unlock(&dcb_lock);
+       spin_unlock_bh(&dcb_lock);
 
        /* features flags */
        if (ops->getfeatcfg) {
@@ -1326,7 +1326,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
        return 0;
 
 dcb_unlock:
-       spin_unlock(&dcb_lock);
+       spin_unlock_bh(&dcb_lock);
 nla_put_failure:
        return err;
 }
@@ -1762,10 +1762,10 @@ u8 dcb_getapp(struct net_device *dev, struct dcb_app *app)
        struct dcb_app_type *itr;
        u8 prio = 0;
 
-       spin_lock(&dcb_lock);
+       spin_lock_bh(&dcb_lock);
        if ((itr = dcb_app_lookup(app, dev->ifindex, 0)))
                prio = itr->app.priority;
-       spin_unlock(&dcb_lock);
+       spin_unlock_bh(&dcb_lock);
 
        return prio;
 }
@@ -1789,7 +1789,7 @@ int dcb_setapp(struct net_device *dev, struct dcb_app *new)
        if (dev->dcbnl_ops->getdcbx)
                event.dcbx = dev->dcbnl_ops->getdcbx(dev);
 
-       spin_lock(&dcb_lock);
+       spin_lock_bh(&dcb_lock);
        /* Search for existing match and replace */
        if ((itr = dcb_app_lookup(new, dev->ifindex, 0))) {
                if (new->priority)
@@ -1804,7 +1804,7 @@ int dcb_setapp(struct net_device *dev, struct dcb_app *new)
        if (new->priority)
                err = dcb_app_add(new, dev->ifindex);
 out:
-       spin_unlock(&dcb_lock);
+       spin_unlock_bh(&dcb_lock);
        if (!err)
                call_dcbevent_notifiers(DCB_APP_EVENT, &event);
        return err;
@@ -1823,10 +1823,10 @@ u8 dcb_ieee_getapp_mask(struct net_device *dev, struct dcb_app *app)
        struct dcb_app_type *itr;
        u8 prio = 0;
 
-       spin_lock(&dcb_lock);
+       spin_lock_bh(&dcb_lock);
        if ((itr = dcb_app_lookup(app, dev->ifindex, 0)))
                prio |= 1 << itr->app.priority;
-       spin_unlock(&dcb_lock);
+       spin_unlock_bh(&dcb_lock);
 
        return prio;
 }
@@ -1850,7 +1850,7 @@ int dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new)
        if (dev->dcbnl_ops->getdcbx)
                event.dcbx = dev->dcbnl_ops->getdcbx(dev);
 
-       spin_lock(&dcb_lock);
+       spin_lock_bh(&dcb_lock);
        /* Search for existing match and abort if found */
        if (dcb_app_lookup(new, dev->ifindex, new->priority)) {
                err = -EEXIST;
@@ -1859,7 +1859,7 @@ int dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new)
 
        err = dcb_app_add(new, dev->ifindex);
 out:
-       spin_unlock(&dcb_lock);
+       spin_unlock_bh(&dcb_lock);
        if (!err)
                call_dcbevent_notifiers(DCB_APP_EVENT, &event);
        return err;
@@ -1882,7 +1882,7 @@ int dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del)
        if (dev->dcbnl_ops->getdcbx)
                event.dcbx = dev->dcbnl_ops->getdcbx(dev);
 
-       spin_lock(&dcb_lock);
+       spin_lock_bh(&dcb_lock);
        /* Search for existing match and remove it. */
        if ((itr = dcb_app_lookup(del, dev->ifindex, del->priority))) {
                list_del(&itr->list);
@@ -1890,7 +1890,7 @@ int dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del)
                err = 0;
        }
 
-       spin_unlock(&dcb_lock);
+       spin_unlock_bh(&dcb_lock);
        if (!err)
                call_dcbevent_notifiers(DCB_APP_EVENT, &event);
        return err;
@@ -1902,12 +1902,12 @@ static void dcb_flushapp(void)
        struct dcb_app_type *app;
        struct dcb_app_type *tmp;
 
-       spin_lock(&dcb_lock);
+       spin_lock_bh(&dcb_lock);
        list_for_each_entry_safe(app, tmp, &dcb_app_list, list) {
                list_del(&app->list);
                kfree(app);
        }
-       spin_unlock(&dcb_lock);
+       spin_unlock_bh(&dcb_lock);
 }
 
 static int __init dcbnl_init(void)
index f2e15738534d316ed0c50b8be2e1976fa03052c5..8f7bd56955b0dc35bb89e4fd0d3fe19fe9b53a47 100644 (file)
@@ -62,6 +62,10 @@ int __fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res)
        else
                res->tclassid = 0;
 #endif
+
+       if (err == -ESRCH)
+               err = -ENETUNREACH;
+
        return err;
 }
 EXPORT_SYMBOL_GPL(__fib_lookup);
index c1023c4459201ad63394606cab4b42fae61257aa..665de06561cd51e0933aa8436438b499d3c5066c 100644 (file)
@@ -24,6 +24,7 @@ static void nft_masq_ipv4_eval(const struct nft_expr *expr,
        struct nf_nat_range range;
        unsigned int verdict;
 
+       memset(&range, 0, sizeof(range));
        range.flags = priv->flags;
 
        verdict = nf_nat_masquerade_ipv4(pkt->skb, pkt->ops->hooknum,
index d91436ba17eaa7cb9d3d8df61a48d42a625df87d..d22a31f27ab4f16d40d5a168cbb7b01dbe20a2c5 100644 (file)
@@ -5232,7 +5232,7 @@ slow_path:
        if (len < (th->doff << 2) || tcp_checksum_complete_user(sk, skb))
                goto csum_error;
 
-       if (!th->ack && !th->rst)
+       if (!th->ack && !th->rst && !th->syn)
                goto discard;
 
        /*
@@ -5651,7 +5651,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                        goto discard;
        }
 
-       if (!th->ack && !th->rst)
+       if (!th->ack && !th->rst && !th->syn)
                goto discard;
 
        if (!tcp_validate_incoming(sk, skb, th, 0))
index 467f310dbbb3b48685d484baabffd2809f8bb326..722669754bbfb89ab04ea7677f1744a967c7e13e 100644 (file)
@@ -1439,6 +1439,10 @@ reg_pernet_fail:
 
 void ip6_mr_cleanup(void)
 {
+       rtnl_unregister(RTNL_FAMILY_IP6MR, RTM_GETROUTE);
+#ifdef CONFIG_IPV6_PIMSM_V2
+       inet6_del_protocol(&pim6_protocol, IPPROTO_PIM);
+#endif
        unregister_netdevice_notifier(&ip6_mr_notifier);
        unregister_pernet_subsys(&ip6mr_net_ops);
        kmem_cache_destroy(mrt_cachep);
index 8a7ac685076d91b18baf91e9ab386a98415ee009..529c119cbb14c9eff00c7a5fb63148ef0bc9f740 100644 (file)
@@ -25,6 +25,7 @@ static void nft_masq_ipv6_eval(const struct nft_expr *expr,
        struct nf_nat_range range;
        unsigned int verdict;
 
+       memset(&range, 0, sizeof(range));
        range.flags = priv->flags;
 
        verdict = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out);
index a0c75366c93b427b2c51b71a558832642e8e40b0..97dc4320ac1526be1ec32a2840490d4b4bbb020a 100644 (file)
@@ -1764,6 +1764,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
        struct ipxhdr *ipx = NULL;
        struct sk_buff *skb;
        int copied, rc;
+       bool locked = true;
 
        lock_sock(sk);
        /* put the autobinding in */
@@ -1790,6 +1791,8 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (sock_flag(sk, SOCK_ZAPPED))
                goto out;
 
+       release_sock(sk);
+       locked = false;
        skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
                                flags & MSG_DONTWAIT, &rc);
        if (!skb) {
@@ -1825,7 +1828,8 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
 out_free:
        skb_free_datagram(sk, skb);
 out:
-       release_sock(sk);
+       if (locked)
+               release_sock(sk);
        return rc;
 }
 
index 62ff7cfb27236aa994401395e609b5767ae3878b..d013429af7cee7b04aa0d8b2efdf135ba303c9da 100644 (file)
@@ -394,19 +394,16 @@ minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u16 index,
        cur_thr = mi->groups[cur_group].rates[cur_idx].cur_tp;
        cur_prob = mi->groups[cur_group].rates[cur_idx].probability;
 
-       tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
-       tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
-       tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp;
-       tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability;
-
-       while (j > 0 && (cur_thr > tmp_thr ||
-             (cur_thr == tmp_thr && cur_prob > tmp_prob))) {
-               j--;
+       do {
                tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
                tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
                tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp;
                tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability;
-       }
+               if (cur_thr < tmp_thr ||
+                   (cur_thr == tmp_thr && cur_prob <= tmp_prob))
+                       break;
+               j--;
+       } while (j > 0);
 
        if (j < MAX_THR_RATES - 1) {
                memmove(&tp_list[j + 1], &tp_list[j], (sizeof(*tp_list) *
index 86f9d76b1464b1b0d5e8b5fc9f9c0c129713bd57..d259da3ce67a6b18f6e4a345a5729876e373efc0 100644 (file)
@@ -1863,6 +1863,12 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
        if (*op < IP_SET_OP_VERSION) {
                /* Check the version at the beginning of operations */
                struct ip_set_req_version *req_version = data;
+
+               if (*len < sizeof(struct ip_set_req_version)) {
+                       ret = -EINVAL;
+                       goto done;
+               }
+
                if (req_version->version != IPSET_PROTOCOL) {
                        ret = -EPROTO;
                        goto done;
index 437a3663ad0346e13cfbc0017be20b4bad73c218..bd90bf8107dacb4e7e0683110bb2146faf168b26 100644 (file)
@@ -846,6 +846,8 @@ ip_vs_prepare_tunneled_skb(struct sk_buff *skb, int skb_af,
                new_skb = skb_realloc_headroom(skb, max_headroom);
                if (!new_skb)
                        goto error;
+               if (skb->sk)
+                       skb_set_owner_w(new_skb, skb->sk);
                consume_skb(skb);
                skb = new_skb;
        }
index 5016a6929085ebdbf151a1f47582d36195885540..2c699757bccf2fce427c5e825625c90328568967 100644 (file)
@@ -611,12 +611,16 @@ __nf_conntrack_confirm(struct sk_buff *skb)
         */
        NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
        pr_debug("Confirming conntrack %p\n", ct);
-       /* We have to check the DYING flag inside the lock to prevent
-          a race against nf_ct_get_next_corpse() possibly called from
-          user context, else we insert an already 'dead' hash, blocking
-          further use of that particular connection -JM */
+
+       /* We have to check the DYING flag after unlink to prevent
+        * a race against nf_ct_get_next_corpse() possibly called from
+        * user context, else we insert an already 'dead' hash, blocking
+        * further use of that particular connection -JM.
+        */
+       nf_ct_del_from_dying_or_unconfirmed_list(ct);
 
        if (unlikely(nf_ct_is_dying(ct))) {
+               nf_ct_add_to_dying_list(ct);
                nf_conntrack_double_unlock(hash, reply_hash);
                local_bh_enable();
                return NF_ACCEPT;
@@ -636,8 +640,6 @@ __nf_conntrack_confirm(struct sk_buff *skb)
                    zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)))
                        goto out;
 
-       nf_ct_del_from_dying_or_unconfirmed_list(ct);
-
        /* Timer relative to confirmation time, not original
           setting time, otherwise we'd get timer wrap in
           weird delay cases. */
index 11ab4b078f3bb68323b1f050f3a1d5e83d271f36..66e8425dbfe77b11e41eb7c97c68f3778ee0c9e7 100644 (file)
@@ -3484,13 +3484,8 @@ static void nft_chain_commit_update(struct nft_trans *trans)
        }
 }
 
-/* Schedule objects for release via rcu to make sure no packets are accesing
- * removed rules.
- */
-static void nf_tables_commit_release_rcu(struct rcu_head *rt)
+static void nf_tables_commit_release(struct nft_trans *trans)
 {
-       struct nft_trans *trans = container_of(rt, struct nft_trans, rcu_head);
-
        switch (trans->msg_type) {
        case NFT_MSG_DELTABLE:
                nf_tables_table_destroy(&trans->ctx);
@@ -3612,10 +3607,11 @@ static int nf_tables_commit(struct sk_buff *skb)
                }
        }
 
+       synchronize_rcu();
+
        list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
                list_del(&trans->list);
-               trans->ctx.nla = NULL;
-               call_rcu(&trans->rcu_head, nf_tables_commit_release_rcu);
+               nf_tables_commit_release(trans);
        }
 
        nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
@@ -3623,13 +3619,8 @@ static int nf_tables_commit(struct sk_buff *skb)
        return 0;
 }
 
-/* Schedule objects for release via rcu to make sure no packets are accesing
- * aborted rules.
- */
-static void nf_tables_abort_release_rcu(struct rcu_head *rt)
+static void nf_tables_abort_release(struct nft_trans *trans)
 {
-       struct nft_trans *trans = container_of(rt, struct nft_trans, rcu_head);
-
        switch (trans->msg_type) {
        case NFT_MSG_NEWTABLE:
                nf_tables_table_destroy(&trans->ctx);
@@ -3725,11 +3716,12 @@ static int nf_tables_abort(struct sk_buff *skb)
                }
        }
 
+       synchronize_rcu();
+
        list_for_each_entry_safe_reverse(trans, next,
                                         &net->nft.commit_list, list) {
                list_del(&trans->list);
-               trans->ctx.nla = NULL;
-               call_rcu(&trans->rcu_head, nf_tables_abort_release_rcu);
+               nf_tables_abort_release(trans);
        }
 
        return 0;
index 6c5a915cfa758bb4d8187dac9dc606201e99b458..13c2e17bbe279e6660a0a04fc804a6e1dd0a7707 100644 (file)
@@ -47,6 +47,8 @@ static const int nfnl_group2type[NFNLGRP_MAX+1] = {
        [NFNLGRP_CONNTRACK_EXP_NEW]     = NFNL_SUBSYS_CTNETLINK_EXP,
        [NFNLGRP_CONNTRACK_EXP_UPDATE]  = NFNL_SUBSYS_CTNETLINK_EXP,
        [NFNLGRP_CONNTRACK_EXP_DESTROY] = NFNL_SUBSYS_CTNETLINK_EXP,
+       [NFNLGRP_NFTABLES]              = NFNL_SUBSYS_NFTABLES,
+       [NFNLGRP_ACCT_QUOTA]            = NFNL_SUBSYS_ACCT,
 };
 
 void nfnl_lock(__u8 subsys_id)
@@ -464,7 +466,12 @@ static void nfnetlink_rcv(struct sk_buff *skb)
 static int nfnetlink_bind(int group)
 {
        const struct nfnetlink_subsystem *ss;
-       int type = nfnl_group2type[group];
+       int type;
+
+       if (group <= NFNLGRP_NONE || group > NFNLGRP_MAX)
+               return -EINVAL;
+
+       type = nfnl_group2type[group];
 
        rcu_read_lock();
        ss = nfnetlink_get_subsys(type);
@@ -514,6 +521,9 @@ static int __init nfnetlink_init(void)
 {
        int i;
 
+       for (i = NFNLGRP_NONE + 1; i <= NFNLGRP_MAX; i++)
+               BUG_ON(nfnl_group2type[i] == NFNL_SUBSYS_NONE);
+
        for (i=0; i<NFNL_SUBSYS_COUNT; i++)
                mutex_init(&table[i].mutex);
 
index 9d6d6f60a80fc6b23da9bb140c90e085a4fa675a..265e190f22187d83de1a9ed07913ef153cf1f03f 100644 (file)
 #include <linux/netfilter_ipv6/ip6_tables.h>
 #include <net/netfilter/nf_tables.h>
 
-static const struct {
-       const char      *name;
-       u8              type;
-} table_to_chaintype[] = {
-       { "filter",     NFT_CHAIN_T_DEFAULT },
-       { "raw",        NFT_CHAIN_T_DEFAULT },
-       { "security",   NFT_CHAIN_T_DEFAULT },
-       { "mangle",     NFT_CHAIN_T_ROUTE },
-       { "nat",        NFT_CHAIN_T_NAT },
-       { },
-};
-
-static int nft_compat_table_to_chaintype(const char *table)
-{
-       int i;
-
-       for (i = 0; table_to_chaintype[i].name != NULL; i++) {
-               if (strcmp(table_to_chaintype[i].name, table) == 0)
-                       return table_to_chaintype[i].type;
-       }
-
-       return -1;
-}
-
 static int nft_compat_chain_validate_dependency(const char *tablename,
                                                const struct nft_chain *chain)
 {
-       enum nft_chain_type type;
        const struct nft_base_chain *basechain;
 
        if (!tablename || !(chain->flags & NFT_BASE_CHAIN))
                return 0;
 
-       type = nft_compat_table_to_chaintype(tablename);
-       if (type < 0)
-               return -EINVAL;
-
        basechain = nft_base_chain(chain);
-       if (basechain->type->type != type)
+       if (strcmp(tablename, "nat") == 0 &&
+           basechain->type->type != NFT_CHAIN_T_NAT)
                return -EINVAL;
 
        return 0;
@@ -117,7 +89,7 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par,
                           struct xt_target *target, void *info,
                           union nft_entry *entry, u8 proto, bool inv)
 {
-       par->net        = &init_net;
+       par->net        = ctx->net;
        par->table      = ctx->table->name;
        switch (ctx->afi->family) {
        case AF_INET:
@@ -324,7 +296,7 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
                          struct xt_match *match, void *info,
                          union nft_entry *entry, u8 proto, bool inv)
 {
-       par->net        = &init_net;
+       par->net        = ctx->net;
        par->table      = ctx->table->name;
        switch (ctx->afi->family) {
        case AF_INET:
@@ -374,7 +346,7 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
        union nft_entry e = {};
        int ret;
 
-       ret = nft_compat_chain_validate_dependency(match->name, ctx->chain);
+       ret = nft_compat_chain_validate_dependency(match->table, ctx->chain);
        if (ret < 0)
                goto err;
 
@@ -448,7 +420,7 @@ static int nft_match_validate(const struct nft_ctx *ctx,
                if (!(hook_mask & match->hooks))
                        return -EINVAL;
 
-               ret = nft_compat_chain_validate_dependency(match->name,
+               ret = nft_compat_chain_validate_dependency(match->table,
                                                           ctx->chain);
                if (ret < 0)
                        return ret;
index 4e05ea1c2d11c2aec9aeff98d6ff7ecdec6c6aa6..764fdc39c63b6565d29d2c4a1d1ed7629924c412 100644 (file)
@@ -281,11 +281,11 @@ static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto,
 {
        int transport_len = skb->len - skb_transport_offset(skb);
 
-       if (l4_proto == IPPROTO_TCP) {
+       if (l4_proto == NEXTHDR_TCP) {
                if (likely(transport_len >= sizeof(struct tcphdr)))
                        inet_proto_csum_replace16(&tcp_hdr(skb)->check, skb,
                                                  addr, new_addr, 1);
-       } else if (l4_proto == IPPROTO_UDP) {
+       } else if (l4_proto == NEXTHDR_UDP) {
                if (likely(transport_len >= sizeof(struct udphdr))) {
                        struct udphdr *uh = udp_hdr(skb);
 
@@ -296,6 +296,10 @@ static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto,
                                        uh->check = CSUM_MANGLED_0;
                        }
                }
+       } else if (l4_proto == NEXTHDR_ICMP) {
+               if (likely(transport_len >= sizeof(struct icmp6hdr)))
+                       inet_proto_csum_replace16(&icmp6_hdr(skb)->icmp6_cksum,
+                                                 skb, addr, new_addr, 1);
        }
 }
 
@@ -815,8 +819,6 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
 
                case OVS_ACTION_ATTR_SAMPLE:
                        err = sample(dp, skb, key, a);
-                       if (unlikely(err)) /* skb already freed. */
-                               return err;
                        break;
                }
 
index f37ca3e5824c66df5e0e31afb88a0637b08ccfd3..332b5a0317392002a18b86dadfd4671e18fb6896 100644 (file)
@@ -1316,7 +1316,7 @@ static size_t ovs_dp_cmd_msg_size(void)
        return msgsize;
 }
 
-/* Called with ovs_mutex or RCU read lock. */
+/* Called with ovs_mutex. */
 static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
                                u32 portid, u32 seq, u32 flags, u8 cmd)
 {
@@ -1604,7 +1604,7 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
        if (!reply)
                return -ENOMEM;
 
-       rcu_read_lock();
+       ovs_lock();
        dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
        if (IS_ERR(dp)) {
                err = PTR_ERR(dp);
@@ -1613,12 +1613,12 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
        err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
                                   info->snd_seq, 0, OVS_DP_CMD_NEW);
        BUG_ON(err < 0);
-       rcu_read_unlock();
+       ovs_unlock();
 
        return genlmsg_reply(reply, info);
 
 err_unlock_free:
-       rcu_read_unlock();
+       ovs_unlock();
        kfree_skb(reply);
        return err;
 }
@@ -1630,8 +1630,8 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
        int skip = cb->args[0];
        int i = 0;
 
-       rcu_read_lock();
-       list_for_each_entry_rcu(dp, &ovs_net->dps, list_node) {
+       ovs_lock();
+       list_for_each_entry(dp, &ovs_net->dps, list_node) {
                if (i >= skip &&
                    ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid,
                                         cb->nlh->nlmsg_seq, NLM_F_MULTI,
@@ -1639,7 +1639,7 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
                        break;
                i++;
        }
-       rcu_read_unlock();
+       ovs_unlock();
 
        cb->args[0] = i;
 
index c8fccdded865454ff982ebb36a1d650d186d89d7..df3c7f20fceec0f131c33e97d1628d147f9f426b 100644 (file)
@@ -140,7 +140,7 @@ static bool match_validate(const struct sw_flow_match *match,
        if (match->key->eth.type == htons(ETH_P_ARP)
                        || match->key->eth.type == htons(ETH_P_RARP)) {
                key_expected |= 1 << OVS_KEY_ATTR_ARP;
-               if (match->mask && (match->mask->key.eth.type == htons(0xffff)))
+               if (match->mask && (match->mask->key.tp.src == htons(0xff)))
                        mask_allowed |= 1 << OVS_KEY_ATTR_ARP;
        }
 
@@ -772,6 +772,13 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs,
                                  ipv6_key->ipv6_frag, OVS_FRAG_TYPE_MAX);
                        return -EINVAL;
                }
+
+               if (!is_mask && ipv6_key->ipv6_label & htonl(0xFFF00000)) {
+                       OVS_NLERR(log, "IPv6 flow label %x is out of range (max=%x).\n",
+                                 ntohl(ipv6_key->ipv6_label), (1 << 20) - 1);
+                       return -EINVAL;
+               }
+
                SW_FLOW_KEY_PUT(match, ipv6.label,
                                ipv6_key->ipv6_label, is_mask);
                SW_FLOW_KEY_PUT(match, ip.proto,
index afb292cd797decf08561492925d87d34d09e485b..53ed8d3f88970a877b2799e6ecb2dc9de6893304 100644 (file)
@@ -1353,6 +1353,7 @@ gss_stringify_acceptor(struct rpc_cred *cred)
        char *string = NULL;
        struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
        struct gss_cl_ctx *ctx;
+       unsigned int len;
        struct xdr_netobj *acceptor;
 
        rcu_read_lock();
@@ -1360,15 +1361,39 @@ gss_stringify_acceptor(struct rpc_cred *cred)
        if (!ctx)
                goto out;
 
-       acceptor = &ctx->gc_acceptor;
+       len = ctx->gc_acceptor.len;
+       rcu_read_unlock();
 
        /* no point if there's no string */
-       if (!acceptor->len)
-               goto out;
-
-       string = kmalloc(acceptor->len + 1, GFP_KERNEL);
+       if (!len)
+               return NULL;
+realloc:
+       string = kmalloc(len + 1, GFP_KERNEL);
        if (!string)
+               return NULL;
+
+       rcu_read_lock();
+       ctx = rcu_dereference(gss_cred->gc_ctx);
+
+       /* did the ctx disappear or was it replaced by one with no acceptor? */
+       if (!ctx || !ctx->gc_acceptor.len) {
+               kfree(string);
+               string = NULL;
                goto out;
+       }
+
+       acceptor = &ctx->gc_acceptor;
+
+       /*
+        * Did we find a new acceptor that's longer than the original? Allocate
+        * a longer buffer and try again.
+        */
+       if (len < acceptor->len) {
+               len = acceptor->len;
+               rcu_read_unlock();
+               kfree(string);
+               goto realloc;
+       }
 
        memcpy(string, acceptor->data, acceptor->len);
        string[acceptor->len] = '\0';
index 172395465e8a63963d096ec29f3ee04f7bfe5948..8fea1b86df25ebe5e66ea56bfb9babdae031a117 100644 (file)
@@ -4520,6 +4520,8 @@ static const struct hda_fixup alc269_fixups[] = {
        [ALC269_FIXUP_HEADSET_MODE] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_headset_mode,
+               .chained = true,
+               .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
        },
        [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
                .type = HDA_FIXUP_FUNC,
@@ -4709,6 +4711,8 @@ static const struct hda_fixup alc269_fixups[] = {
        [ALC255_FIXUP_HEADSET_MODE] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_headset_mode_alc255,
+               .chained = true,
+               .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
        },
        [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
                .type = HDA_FIXUP_FUNC,
@@ -4744,8 +4748,6 @@ static const struct hda_fixup alc269_fixups[] = {
        [ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_dell_wmi,
-               .chained_before = true,
-               .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
        },
        [ALC282_FIXUP_ASPIRE_V5_PINS] = {
                .type = HDA_FIXUP_PINS,
@@ -4783,10 +4785,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
-       SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED),
        SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
        SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
-       SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED),
        SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
        SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
index cee51ae177c1e219325231eb517b91784ac258fe..c40428f25ba5c9b9b3d2e5e657a71020702dc12b 100644 (file)
@@ -46,6 +46,7 @@ static struct i2c_driver cs42l51_i2c_driver = {
        .driver = {
                .name = "cs42l51",
                .owner = THIS_MODULE,
+               .of_match_table = cs42l51_of_match,
        },
        .probe = cs42l51_i2c_probe,
        .remove = cs42l51_i2c_remove,
index 09488d97de60d040bbdb37edfa3a94a999930633..669c38fc303468d51dd6bbd3dfa16e935c030e8c 100644 (file)
@@ -558,11 +558,13 @@ error:
 }
 EXPORT_SYMBOL_GPL(cs42l51_probe);
 
-static const struct of_device_id cs42l51_of_match[] = {
+const struct of_device_id cs42l51_of_match[] = {
        { .compatible = "cirrus,cs42l51", },
        { }
 };
 MODULE_DEVICE_TABLE(of, cs42l51_of_match);
+EXPORT_SYMBOL_GPL(cs42l51_of_match);
+
 MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
 MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
 MODULE_LICENSE("GPL");
index 8c55bf384bc65189545807d9ce9278d6c66670f2..0ca805492ac4b77d110dc24b378845fb5b3768a6 100644 (file)
@@ -22,6 +22,7 @@ struct device;
 
 extern const struct regmap_config cs42l51_regmap;
 int cs42l51_probe(struct device *dev, struct regmap *regmap);
+extern const struct of_device_id cs42l51_of_match[];
 
 #define CS42L51_CHIP_ID                        0x1B
 #define CS42L51_CHIP_REV_A             0x00
index aae410d122ee1f8f7cb99fbd416fd02c0f17fdfd..2d05b5d3a6ce7fdc3531f5c322853dbb1a0ca63e 100644 (file)
@@ -19,7 +19,7 @@
 #include "es8328.h"
 
 static const struct i2c_device_id es8328_id[] = {
-       { "everest,es8328", 0 },
+       { "es8328", 0 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, es8328_id);
index d519294f57c79c289784f9a71bb43d7bf51dc7e9..1229554f1464d1e1c37a1d82d227a5a6347e377d 100644 (file)
@@ -1941,13 +1941,13 @@ static int max98090_dai_set_sysclk(struct snd_soc_dai *dai,
         *               0x02 (when master clk is 20MHz to 40MHz)..
         *               0x03 (when master clk is 40MHz to 60MHz)..
         */
-       if ((freq >= 10000000) && (freq < 20000000)) {
+       if ((freq >= 10000000) && (freq <= 20000000)) {
                snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
                        M98090_PSCLK_DIV1);
-       } else if ((freq >= 20000000) && (freq < 40000000)) {
+       } else if ((freq > 20000000) && (freq <= 40000000)) {
                snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
                        M98090_PSCLK_DIV2);
-       } else if ((freq >= 40000000) && (freq < 60000000)) {
+       } else if ((freq > 40000000) && (freq <= 60000000)) {
                snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
                        M98090_PSCLK_DIV4);
        } else {
index 3fb83bf09768347f1bcd469d2be9be4b56ea62e2..d16331e0b64d4532647b5f4eb4d4abe58a4d66ec 100644 (file)
@@ -139,6 +139,7 @@ static const struct reg_default rt5645_reg[] = {
        { 0x76, 0x000a },
        { 0x77, 0x0c00 },
        { 0x78, 0x0000 },
+       { 0x79, 0x0123 },
        { 0x80, 0x0000 },
        { 0x81, 0x0000 },
        { 0x82, 0x0000 },
@@ -334,6 +335,7 @@ static bool rt5645_readable_register(struct device *dev, unsigned int reg)
        case RT5645_DMIC_CTRL2:
        case RT5645_TDM_CTRL_1:
        case RT5645_TDM_CTRL_2:
+       case RT5645_TDM_CTRL_3:
        case RT5645_GLB_CLK:
        case RT5645_PLL_CTRL1:
        case RT5645_PLL_CTRL2:
index ba9d9b4d485783c80efa30e13e3218f1fec7742e..9bd8b4f633032c713a432ca3af1bc38aa3c81f16 100644 (file)
@@ -100,18 +100,18 @@ static const struct reg_default rt5670_reg[] = {
        { 0x4c, 0x5380 },
        { 0x4f, 0x0073 },
        { 0x52, 0x00d3 },
-       { 0x53, 0xf0f0 },
+       { 0x53, 0xf000 },
        { 0x61, 0x0000 },
        { 0x62, 0x0001 },
        { 0x63, 0x00c3 },
        { 0x64, 0x0000 },
-       { 0x65, 0x0000 },
+       { 0x65, 0x0001 },
        { 0x66, 0x0000 },
        { 0x6f, 0x8000 },
        { 0x70, 0x8000 },
        { 0x71, 0x8000 },
        { 0x72, 0x8000 },
-       { 0x73, 0x1110 },
+       { 0x73, 0x7770 },
        { 0x74, 0x0e00 },
        { 0x75, 0x1505 },
        { 0x76, 0x0015 },
@@ -125,21 +125,21 @@ static const struct reg_default rt5670_reg[] = {
        { 0x83, 0x0000 },
        { 0x84, 0x0000 },
        { 0x85, 0x0000 },
-       { 0x86, 0x0008 },
+       { 0x86, 0x0004 },
        { 0x87, 0x0000 },
        { 0x88, 0x0000 },
        { 0x89, 0x0000 },
        { 0x8a, 0x0000 },
        { 0x8b, 0x0000 },
-       { 0x8c, 0x0007 },
+       { 0x8c, 0x0003 },
        { 0x8d, 0x0000 },
        { 0x8e, 0x0004 },
        { 0x8f, 0x1100 },
        { 0x90, 0x0646 },
        { 0x91, 0x0c06 },
        { 0x93, 0x0000 },
-       { 0x94, 0x0000 },
-       { 0x95, 0x0000 },
+       { 0x94, 0x1270 },
+       { 0x95, 0x1000 },
        { 0x97, 0x0000 },
        { 0x98, 0x0000 },
        { 0x99, 0x0000 },
@@ -150,11 +150,11 @@ static const struct reg_default rt5670_reg[] = {
        { 0x9e, 0x0400 },
        { 0xae, 0x7000 },
        { 0xaf, 0x0000 },
-       { 0xb0, 0x6000 },
+       { 0xb0, 0x7000 },
        { 0xb1, 0x0000 },
        { 0xb2, 0x0000 },
        { 0xb3, 0x001f },
-       { 0xb4, 0x2206 },
+       { 0xb4, 0x220c },
        { 0xb5, 0x1f00 },
        { 0xb6, 0x0000 },
        { 0xb7, 0x0000 },
@@ -171,25 +171,25 @@ static const struct reg_default rt5670_reg[] = {
        { 0xcf, 0x1813 },
        { 0xd0, 0x0690 },
        { 0xd1, 0x1c17 },
-       { 0xd3, 0xb320 },
+       { 0xd3, 0xa220 },
        { 0xd4, 0x0000 },
        { 0xd6, 0x0400 },
        { 0xd9, 0x0809 },
        { 0xda, 0x0000 },
        { 0xdb, 0x0001 },
        { 0xdc, 0x0049 },
-       { 0xdd, 0x0009 },
+       { 0xdd, 0x0024 },
        { 0xe6, 0x8000 },
        { 0xe7, 0x0000 },
-       { 0xec, 0xb300 },
+       { 0xec, 0xa200 },
        { 0xed, 0x0000 },
-       { 0xee, 0xb300 },
+       { 0xee, 0xa200 },
        { 0xef, 0x0000 },
        { 0xf8, 0x0000 },
        { 0xf9, 0x0000 },
        { 0xfa, 0x8010 },
        { 0xfb, 0x0033 },
-       { 0xfc, 0x0080 },
+       { 0xfc, 0x0100 },
 };
 
 static bool rt5670_volatile_register(struct device *dev, unsigned int reg)
@@ -1877,6 +1877,10 @@ static const struct snd_soc_dapm_route rt5670_dapm_routes[] = {
        { "DAC1 MIXR", "DAC1 Switch", "DAC1 R Mux" },
        { "DAC1 MIXR", NULL, "DAC Stereo1 Filter" },
 
+       { "DAC Stereo1 Filter", NULL, "PLL1", is_sys_clk_from_pll },
+       { "DAC Mono Left Filter", NULL, "PLL1", is_sys_clk_from_pll },
+       { "DAC Mono Right Filter", NULL, "PLL1", is_sys_clk_from_pll },
+
        { "DAC MIX", NULL, "DAC1 MIXL" },
        { "DAC MIX", NULL, "DAC1 MIXR" },
 
@@ -1926,14 +1930,10 @@ static const struct snd_soc_dapm_route rt5670_dapm_routes[] = {
 
        { "DAC L1", NULL, "DAC L1 Power" },
        { "DAC L1", NULL, "Stereo DAC MIXL" },
-       { "DAC L1", NULL, "PLL1", is_sys_clk_from_pll },
        { "DAC R1", NULL, "DAC R1 Power" },
        { "DAC R1", NULL, "Stereo DAC MIXR" },
-       { "DAC R1", NULL, "PLL1", is_sys_clk_from_pll },
        { "DAC L2", NULL, "Mono DAC MIXL" },
-       { "DAC L2", NULL, "PLL1", is_sys_clk_from_pll },
        { "DAC R2", NULL, "Mono DAC MIXR" },
-       { "DAC R2", NULL, "PLL1", is_sys_clk_from_pll },
 
        { "OUT MIXL", "BST1 Switch", "BST1" },
        { "OUT MIXL", "INL Switch", "INL VOL" },
index 6bb77d76561b8964303275955d1e1beb579ba859..dab9b15304af829a510742ec4a4827bdca90a453 100644 (file)
@@ -1299,8 +1299,7 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
 
        /* enable small pop, introduce 400ms delay in turning off */
        snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
-                               SGTL5000_SMALL_POP,
-                               SGTL5000_SMALL_POP);
+                               SGTL5000_SMALL_POP, 1);
 
        /* disable short cut detector */
        snd_soc_write(codec, SGTL5000_CHIP_SHORT_CTRL, 0);
index 2f8c88931f690579f86d497d03ef7327a156a94c..bd7a344bf8c517edf69af2fda9e06e08488e47e0 100644 (file)
 #define SGTL5000_BIAS_CTRL_MASK                        0x000e
 #define SGTL5000_BIAS_CTRL_SHIFT               1
 #define SGTL5000_BIAS_CTRL_WIDTH               3
-#define SGTL5000_SMALL_POP                     0x0001
+#define SGTL5000_SMALL_POP                     0
 
 /*
  * SGTL5000_CHIP_MIC_CTRL
index f412a9911a75d2fe531930f6a0108fb977c41e77..67124783558a5374b547f26d30d1ccc2bdc16ae4 100644 (file)
@@ -1355,6 +1355,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
                          file, blocks, pos - firmware->size);
 
 out_fw:
+       regmap_async_complete(regmap);
        release_firmware(firmware);
        wm_adsp_buf_free(&buf_list);
 out:
index ed866e9a2928c4ca5415571fc757f6ba588b636f..9deabdd2b1a29adf3d27335557cd1cc23fee11f4 100644 (file)
@@ -684,12 +684,38 @@ static bool fsl_asrc_writeable_reg(struct device *dev, unsigned int reg)
        }
 }
 
+static struct reg_default fsl_asrc_reg[] = {
+       { REG_ASRCTR, 0x0000 }, { REG_ASRIER, 0x0000 },
+       { REG_ASRCNCR, 0x0000 }, { REG_ASRCFG, 0x0000 },
+       { REG_ASRCSR, 0x0000 }, { REG_ASRCDR1, 0x0000 },
+       { REG_ASRCDR2, 0x0000 }, { REG_ASRSTR, 0x0000 },
+       { REG_ASRRA, 0x0000 }, { REG_ASRRB, 0x0000 },
+       { REG_ASRRC, 0x0000 }, { REG_ASRPM1, 0x0000 },
+       { REG_ASRPM2, 0x0000 }, { REG_ASRPM3, 0x0000 },
+       { REG_ASRPM4, 0x0000 }, { REG_ASRPM5, 0x0000 },
+       { REG_ASRTFR1, 0x0000 }, { REG_ASRCCR, 0x0000 },
+       { REG_ASRDIA, 0x0000 }, { REG_ASRDOA, 0x0000 },
+       { REG_ASRDIB, 0x0000 }, { REG_ASRDOB, 0x0000 },
+       { REG_ASRDIC, 0x0000 }, { REG_ASRDOC, 0x0000 },
+       { REG_ASRIDRHA, 0x0000 }, { REG_ASRIDRLA, 0x0000 },
+       { REG_ASRIDRHB, 0x0000 }, { REG_ASRIDRLB, 0x0000 },
+       { REG_ASRIDRHC, 0x0000 }, { REG_ASRIDRLC, 0x0000 },
+       { REG_ASR76K, 0x0A47 }, { REG_ASR56K, 0x0DF3 },
+       { REG_ASRMCRA, 0x0000 }, { REG_ASRFSTA, 0x0000 },
+       { REG_ASRMCRB, 0x0000 }, { REG_ASRFSTB, 0x0000 },
+       { REG_ASRMCRC, 0x0000 }, { REG_ASRFSTC, 0x0000 },
+       { REG_ASRMCR1A, 0x0000 }, { REG_ASRMCR1B, 0x0000 },
+       { REG_ASRMCR1C, 0x0000 },
+};
+
 static const struct regmap_config fsl_asrc_regmap_config = {
        .reg_bits = 32,
        .reg_stride = 4,
        .val_bits = 32,
 
        .max_register = REG_ASRMCR1C,
+       .reg_defaults = fsl_asrc_reg,
+       .num_reg_defaults = ARRAY_SIZE(fsl_asrc_reg),
        .readable_reg = fsl_asrc_readable_reg,
        .volatile_reg = fsl_asrc_volatile_reg,
        .writeable_reg = fsl_asrc_writeable_reg,
index f373e37f83050a246c2d35fbed008db7cdd0b5a5..c74ba37f862c121b1114edd84bded49ec7d72907 100644 (file)
@@ -154,8 +154,10 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
                        while (val) {
                                regmap_read(i2s->regmap, I2S_CLR, &val);
                                retry--;
-                               if (!retry)
+                               if (!retry) {
                                        dev_warn(i2s->dev, "fail to clear\n");
+                                       break;
+                               }
                        }
                }
        }
index 0acf5d0eed53a30979f66d466252b51f660f3d2e..72118a77dd5b70aa2a08fb51c32b5204063829f5 100644 (file)
@@ -110,6 +110,7 @@ static const struct of_device_id snow_of_match[] = {
        { .compatible = "google,snow-audio-max98095", },
        {},
 };
+MODULE_DEVICE_TABLE(of, snow_of_match);
 
 static struct platform_driver snow_driver = {
        .driver = {
index 66fddec9543d0ecc1bb414871d035bc244abc521..88e5df474ccf0ed089e23d9fe00f1268189886c9 100644 (file)
@@ -1711,8 +1711,7 @@ static const struct snd_soc_dai_ops fsi_dai_ops = {
 static struct snd_pcm_hardware fsi_pcm_hardware = {
        .info =         SNDRV_PCM_INFO_INTERLEAVED      |
                        SNDRV_PCM_INFO_MMAP             |
-                       SNDRV_PCM_INFO_MMAP_VALID       |
-                       SNDRV_PCM_INFO_PAUSE,
+                       SNDRV_PCM_INFO_MMAP_VALID,
        .buffer_bytes_max       = 64 * 1024,
        .period_bytes_min       = 32,
        .period_bytes_max       = 8192,
index 1922ec57d10a1fd29c174295adb6de5446e8d7a2..70042197f9e26eaf6f95f5f429435388b12976b4 100644 (file)
@@ -886,8 +886,7 @@ static int rsnd_dai_probe(struct platform_device *pdev,
 static struct snd_pcm_hardware rsnd_pcm_hardware = {
        .info =         SNDRV_PCM_INFO_INTERLEAVED      |
                        SNDRV_PCM_INFO_MMAP             |
-                       SNDRV_PCM_INFO_MMAP_VALID       |
-                       SNDRV_PCM_INFO_PAUSE,
+                       SNDRV_PCM_INFO_MMAP_VALID,
        .buffer_bytes_max       = 64 * 1024,
        .period_bytes_min       = 32,
        .period_bytes_max       = 8192,
index 4c8f8a23a0e9de132827fc041438fc1e07a4892c..b60ff56ebc0f56c2199a3473521fa657d9436713 100644 (file)
@@ -884,7 +884,7 @@ static struct snd_soc_dai *snd_soc_find_dai(
        list_for_each_entry(component, &component_list, list) {
                if (dlc->of_node && component->dev->of_node != dlc->of_node)
                        continue;
-               if (dlc->name && strcmp(dev_name(component->dev), dlc->name))
+               if (dlc->name && strcmp(component->name, dlc->name))
                        continue;
                list_for_each_entry(dai, &component->dai_list, list) {
                        if (dlc->dai_name && strcmp(dai->name, dlc->dai_name))
index 002311afdeaa8bd6ceb40d120b0c6afaa13c6119..57277dd79e112c2b59bf2ee3925bae6228bc30ac 100644 (file)
@@ -1522,13 +1522,36 @@ static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream)
                dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture);
 }
 
+static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd);
+
+/* Set FE's runtime_update state; the state is protected via PCM stream lock
+ * for avoiding the race with trigger callback.
+ * If the state is unset and a trigger is pending while the previous operation,
+ * process the pending trigger action here.
+ */
+static void dpcm_set_fe_update_state(struct snd_soc_pcm_runtime *fe,
+                                    int stream, enum snd_soc_dpcm_update state)
+{
+       struct snd_pcm_substream *substream =
+               snd_soc_dpcm_get_substream(fe, stream);
+
+       snd_pcm_stream_lock_irq(substream);
+       if (state == SND_SOC_DPCM_UPDATE_NO && fe->dpcm[stream].trigger_pending) {
+               dpcm_fe_dai_do_trigger(substream,
+                                      fe->dpcm[stream].trigger_pending - 1);
+               fe->dpcm[stream].trigger_pending = 0;
+       }
+       fe->dpcm[stream].runtime_update = state;
+       snd_pcm_stream_unlock_irq(substream);
+}
+
 static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
 {
        struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
        struct snd_pcm_runtime *runtime = fe_substream->runtime;
        int stream = fe_substream->stream, ret = 0;
 
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
 
        ret = dpcm_be_dai_startup(fe, fe_substream->stream);
        if (ret < 0) {
@@ -1550,13 +1573,13 @@ static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
        dpcm_set_fe_runtime(fe_substream);
        snd_pcm_limit_hw_rates(runtime);
 
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
        return 0;
 
 unwind:
        dpcm_be_dai_startup_unwind(fe, fe_substream->stream);
 be_err:
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
        return ret;
 }
 
@@ -1603,7 +1626,7 @@ static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream)
        struct snd_soc_pcm_runtime *fe = substream->private_data;
        int stream = substream->stream;
 
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
 
        /* shutdown the BEs */
        dpcm_be_dai_shutdown(fe, substream->stream);
@@ -1617,7 +1640,7 @@ static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream)
        dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
 
        fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
        return 0;
 }
 
@@ -1665,7 +1688,7 @@ static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream)
        int err, stream = substream->stream;
 
        mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
 
        dev_dbg(fe->dev, "ASoC: hw_free FE %s\n", fe->dai_link->name);
 
@@ -1680,7 +1703,7 @@ static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream)
        err = dpcm_be_dai_hw_free(fe, stream);
 
        fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
 
        mutex_unlock(&fe->card->mutex);
        return 0;
@@ -1773,7 +1796,7 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream,
        int ret, stream = substream->stream;
 
        mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
 
        memcpy(&fe->dpcm[substream->stream].hw_params, params,
                        sizeof(struct snd_pcm_hw_params));
@@ -1796,7 +1819,7 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream,
                fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS;
 
 out:
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
        mutex_unlock(&fe->card->mutex);
        return ret;
 }
@@ -1910,7 +1933,7 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream,
 }
 EXPORT_SYMBOL_GPL(dpcm_be_dai_trigger);
 
-static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd)
+static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd)
 {
        struct snd_soc_pcm_runtime *fe = substream->private_data;
        int stream = substream->stream, ret;
@@ -1984,6 +2007,23 @@ out:
        return ret;
 }
 
+static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       struct snd_soc_pcm_runtime *fe = substream->private_data;
+       int stream = substream->stream;
+
+       /* if FE's runtime_update is already set, we're in race;
+        * process this trigger later at exit
+        */
+       if (fe->dpcm[stream].runtime_update != SND_SOC_DPCM_UPDATE_NO) {
+               fe->dpcm[stream].trigger_pending = cmd + 1;
+               return 0; /* delayed, assuming it's successful */
+       }
+
+       /* we're alone, let's trigger */
+       return dpcm_fe_dai_do_trigger(substream, cmd);
+}
+
 int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream)
 {
        struct snd_soc_dpcm *dpcm;
@@ -2027,7 +2067,7 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream)
 
        dev_dbg(fe->dev, "ASoC: prepare FE %s\n", fe->dai_link->name);
 
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
 
        /* there is no point preparing this FE if there are no BEs */
        if (list_empty(&fe->dpcm[stream].be_clients)) {
@@ -2054,7 +2094,7 @@ static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream)
        fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
 
 out:
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
        mutex_unlock(&fe->card->mutex);
 
        return ret;
@@ -2201,11 +2241,11 @@ static int dpcm_run_new_update(struct snd_soc_pcm_runtime *fe, int stream)
 {
        int ret;
 
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE);
        ret = dpcm_run_update_startup(fe, stream);
        if (ret < 0)
                dev_err(fe->dev, "ASoC: failed to startup some BEs\n");
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
 
        return ret;
 }
@@ -2214,11 +2254,11 @@ static int dpcm_run_old_update(struct snd_soc_pcm_runtime *fe, int stream)
 {
        int ret;
 
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE);
        ret = dpcm_run_update_shutdown(fe, stream);
        if (ret < 0)
                dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n");
-       fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
+       dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
 
        return ret;
 }
index 2e4a9dbc51faeca29529da8d231d779a10b92aed..6e354d3268585bfa38e2e35e4b1c6382ceb10067 100644 (file)
@@ -2033,10 +2033,11 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
        cval->res = 1;
        cval->initialized = 1;
 
-       if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
-               cval->control = UAC2_CX_CLOCK_SELECTOR;
-       else
+       if (state->mixer->protocol == UAC_VERSION_1)
                cval->control = 0;
+       else /* UAC_VERSION_2 */
+               cval->control = (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR) ?
+                       UAC2_CX_CLOCK_SELECTOR : UAC2_SU_SELECTOR;
 
        namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL);
        if (!namelist) {
index d2aa45a8d89546b378fa05fc94750a35f6fe5c18..a5941f80fc5bc6321d26ce523953312acae2e09f 100644 (file)
@@ -1146,6 +1146,20 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
        if ((le16_to_cpu(dev->descriptor.idVendor) == 0x23ba) &&
            (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
                mdelay(20);
+
+       /* Marantz/Denon devices with USB DAC functionality need a delay
+        * after each class compliant request
+        */
+       if ((le16_to_cpu(dev->descriptor.idVendor) == 0x154e) &&
+           (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) {
+
+               switch (le16_to_cpu(dev->descriptor.idProduct)) {
+               case 0x3005: /* Marantz HD-DAC1 */
+               case 0x3006: /* Marantz SA-14S1 */
+                       mdelay(20);
+                       break;
+               }
+       }
 }
 
 /*