]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branches 'pm-core', 'pm-qos' and 'pm-avs'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 12 Dec 2016 19:43:44 +0000 (20:43 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 12 Dec 2016 19:43:44 +0000 (20:43 +0100)
* pm-core:
  PM / core: Fix bug in the error handling of async suspend
  PM / wakeirq: Fix dedicated wakeirq for drivers not using autosuspend
  PM / Runtime: Defer resuming of the device in pm_runtime_force_resume()
  PM / Runtime: Don't allow to suspend a device with an active child
  net: smsc911x: Synchronize the runtime PM status during system suspend
  PM / Runtime: Convert pm_runtime_set_suspended() to return an int
  PM / Runtime: Clarify comment in rpm_resume() when resuming the parent
  PM / Runtime: Remove the exported function pm_children_suspended()

* pm-qos:
  PM / QoS: Export dev_pm_qos_update_user_latency_tolerance
  PM / QoS: Fix writing 'auto' to pm_qos_latency_tolerance_us
  PM / QoS: Improve sysfs pm_qos_latency_tolerance validation

* pm-avs:
  PM / AVS: rockchip-io: make the log more consistent

325 files changed:
CREDITS
Documentation/devicetree/bindings/net/ethernet.txt
Documentation/devicetree/bindings/power/domain-idle-state.txt [new file with mode: 0644]
Documentation/devicetree/bindings/power/power_domain.txt
Documentation/networking/nf_conntrack-sysctl.txt
Documentation/power/devices.txt
MAINTAINERS
Makefile
arch/arc/include/asm/delay.h
arch/arc/include/asm/pgtable.h
arch/arc/mm/cache.c
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/imx7s.dtsi
arch/arm/boot/dts/ntc-gr8-evb.dts [deleted file]
arch/arm/boot/dts/ntc-gr8.dtsi [deleted file]
arch/arm/boot/dts/orion5x-linkstation-lsgl.dts
arch/arm/boot/dts/stih407-family.dtsi
arch/arm/boot/dts/sun5i-gr8-evb.dts [new file with mode: 0644]
arch/arm/boot/dts/sun5i-gr8.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sun8i-h3.dtsi
arch/arm/mach-imx/gpc.c
arch/arm64/boot/dts/arm/juno-base.dtsi
arch/arm64/boot/dts/arm/juno-r1.dts
arch/arm64/boot/dts/arm/juno-r2.dts
arch/arm64/boot/dts/arm/juno.dts
arch/m68k/configs/amiga_defconfig
arch/m68k/configs/apollo_defconfig
arch/m68k/configs/atari_defconfig
arch/m68k/configs/bvme6000_defconfig
arch/m68k/configs/hp300_defconfig
arch/m68k/configs/mac_defconfig
arch/m68k/configs/multi_defconfig
arch/m68k/configs/mvme147_defconfig
arch/m68k/configs/mvme16x_defconfig
arch/m68k/configs/q40_defconfig
arch/m68k/configs/sun3_defconfig
arch/m68k/configs/sun3x_defconfig
arch/m68k/include/asm/delay.h
arch/mips/kernel/time.c
arch/mips/lantiq/falcon/sysctrl.c
arch/parisc/include/asm/pgtable.h
arch/parisc/kernel/cache.c
arch/parisc/kernel/pacache.S
arch/powerpc/boot/Makefile
arch/powerpc/boot/opal.c
arch/powerpc/kernel/eeh_driver.c
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/mm/hash64_4k.c
arch/powerpc/mm/hash64_64k.c
arch/x86/events/core.c
arch/x86/events/intel/core.c
arch/x86/events/intel/cstate.c
arch/x86/include/asm/compat.h
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/unwind_guess.c
arch/x86/platform/olpc/olpc-xo15-sci.c
arch/x86/tools/relocs.h
block/blk-map.c
crypto/Makefile
crypto/algif_aead.c
crypto/drbg.c
crypto/mcryptd.c
drivers/acpi/nfit/core.c
drivers/acpi/nfit/nfit.h
drivers/ata/ahci.c
drivers/ata/libata-scsi.c
drivers/ata/sata_mv.c
drivers/atm/eni.c
drivers/atm/lanai.c
drivers/base/power/domain.c
drivers/base/power/main.c
drivers/base/power/power.h
drivers/base/power/runtime.c
drivers/base/power/wakeirq.c
drivers/block/zram/zram_drv.c
drivers/clk/bcm/Kconfig
drivers/clk/sunxi-ng/ccu-sun6i-a31.c
drivers/clk/sunxi-ng/ccu-sun8i-a33.c
drivers/crypto/caam/ctrl.c
drivers/crypto/chelsio/chcr_algo.h
drivers/crypto/marvell/hash.c
drivers/dax/dax.c
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c
drivers/gpu/drm/arm/hdlcd_drv.c
drivers/gpu/drm/drm_ioctl.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/radeon/radeon_atpx_handler.c
drivers/i2c/busses/i2c-octeon-core.c
drivers/i2c/busses/i2c-octeon-core.h
drivers/input/mouse/psmouse-base.c
drivers/isdn/gigaset/ser-gigaset.c
drivers/isdn/hisax/hfc4s8s_l1.c
drivers/net/can/usb/peak_usb/pcan_ucan.h
drivers/net/can/usb/peak_usb/pcan_usb_core.c
drivers/net/can/usb/peak_usb/pcan_usb_core.h
drivers/net/can/usb/peak_usb/pcan_usb_fd.c
drivers/net/ethernet/altera/altera_tse_main.c
drivers/net/ethernet/amd/xgbe/xgbe-main.c
drivers/net/ethernet/aurora/nb8800.c
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/broadcom/genet/bcmmii.c
drivers/net/ethernet/cadence/macb.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h
drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
drivers/net/ethernet/cirrus/ep93xx_eth.c
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/freescale/fman/fman_memac.c
drivers/net/ethernet/freescale/fman/mac.c
drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/freescale/ucc_geth.c
drivers/net/ethernet/ibm/ibmveth.c
drivers/net/ethernet/ibm/ibmveth.h
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/igbvf/netdev.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/lantiq_etop.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/mediatek/mtk_eth_soc.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx4/mcg.c
drivers/net/ethernet/mellanox/mlx5/core/Kconfig
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c
drivers/net/ethernet/mellanox/mlx5/core/main.c
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
drivers/net/ethernet/qlogic/qed/qed_ll2.c
drivers/net/ethernet/qualcomm/emac/emac-phy.c
drivers/net/ethernet/qualcomm/emac/emac.c
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/smsc/smsc911x.c
drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
drivers/net/ethernet/synopsys/dwc_eth_qos.c
drivers/net/ethernet/ti/cpmac.c
drivers/net/ethernet/ti/cpsw-phy-sel.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/ethernet/ti/davinci_emac.c
drivers/net/geneve.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/ipvlan/ipvlan_main.c
drivers/net/irda/irda-usb.c
drivers/net/irda/w83977af_ir.c
drivers/net/macvtap.c
drivers/net/phy/phy_device.c
drivers/net/phy/realtek.c
drivers/net/tun.c
drivers/net/usb/asix_devices.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/cdc_mbim.c
drivers/net/usb/cdc_ncm.c
drivers/net/usb/lan78xx.c
drivers/net/usb/qmi_wwan.c
drivers/net/virtio_net.c
drivers/net/vxlan.c
drivers/net/wireless/marvell/mwifiex/cfg80211.c
drivers/nvdimm/bus.c
drivers/of/of_mdio.c
drivers/pci/host/pcie-designware-plat.c
drivers/pci/pcie/aer/aer_inject.c
drivers/pci/probe.c
drivers/power/avs/rockchip-io-domain.c
drivers/pwm/pwm-meson.c
drivers/pwm/sysfs.c
drivers/scsi/be2iscsi/be_mgmt.c
drivers/scsi/hpsa.c
drivers/scsi/hpsa.h
drivers/scsi/libfc/fc_lport.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/mpt3sas/mpt3sas_scsih.c
drivers/scsi/mvsas/mv_sas.c
drivers/scsi/qlogicpti.h
drivers/vhost/vsock.c
fs/ceph/dir.c
fs/cifs/cifsencrypt.c
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/fuse/dir.c
fs/isofs/rock.c
fs/overlayfs/super.c
include/crypto/drbg.h
include/linux/compiler-gcc.h
include/linux/libnvdimm.h
include/linux/mlx4/device.h
include/linux/of_mdio.h
include/linux/pagemap.h
include/linux/pci.h
include/linux/pm_domain.h
include/linux/pm_runtime.h
include/linux/usb/cdc_ncm.h
include/net/ipv6.h
include/net/netfilter/nf_conntrack.h
include/net/netfilter/nf_tables.h
include/uapi/linux/can.h
include/uapi/linux/if.h
include/uapi/linux/input-event-codes.h
include/uapi/linux/netfilter/Kbuild
include/uapi/linux/tc_act/Kbuild
init/Kconfig
kernel/bpf/verifier.c
kernel/events/core.c
kernel/kcov.c
kernel/locking/lockdep.c
kernel/locking/rtmutex.c
kernel/locking/rtmutex_common.h
kernel/module.c
kernel/sched/auto_group.c
lib/debugobjects.c
lib/locking-selftest.c
lib/test_kasan.c
mm/huge_memory.c
mm/kasan/kasan.c
mm/kasan/kasan.h
mm/kasan/report.c
mm/khugepaged.c
mm/mlock.c
mm/mremap.c
mm/shmem.c
mm/truncate.c
mm/vmscan.c
mm/workingset.c
net/batman-adv/translation-table.c
net/bridge/br_sysfs_br.c
net/caif/caif_socket.c
net/can/raw.c
net/core/flow.c
net/core/rtnetlink.c
net/core/sock.c
net/dcb/dcbnl.c
net/dccp/ipv4.c
net/dsa/dsa.c
net/dsa/dsa2.c
net/dsa/slave.c
net/ipv4/Kconfig
net/ipv4/af_inet.c
net/ipv4/esp4.c
net/ipv4/fib_trie.c
net/ipv4/ip_output.c
net/ipv4/netfilter.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/ping.c
net/ipv4/tcp_input.c
net/ipv6/datagram.c
net/ipv6/esp6.c
net/ipv6/icmp.c
net/ipv6/ip6_offload.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6_vti.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
net/ipv6/netfilter/nf_reject_ipv6.c
net/ipv6/output_core.c
net/l2tp/l2tp_ip.c
net/l2tp/l2tp_ip6.c
net/mpls/af_mpls.c
net/netfilter/nf_nat_core.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_hash.c
net/netfilter/nft_range.c
net/netlink/af_netlink.c
net/netlink/af_netlink.h
net/openvswitch/conntrack.c
net/packet/af_packet.c
net/rds/tcp.c
net/sched/act_pedit.c
net/sched/cls_basic.c
net/sched/cls_bpf.c
net/sched/cls_cgroup.c
net/sched/cls_flow.c
net/sched/cls_flower.c
net/sched/cls_matchall.c
net/sched/cls_rsvp.h
net/sched/cls_tcindex.c
net/tipc/bearer.c
net/tipc/bearer.h
net/tipc/link.c
net/tipc/udp_media.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_user.c
samples/bpf/bpf_helpers.h
samples/bpf/sampleip_kern.c
samples/bpf/trace_event_kern.c
scripts/kconfig/Makefile
sound/sparc/dbri.c
tools/objtool/arch/x86/decode.c
tools/testing/nvdimm/Kbuild
tools/testing/nvdimm/test/iomap.c
tools/testing/nvdimm/test/nfit.c
tools/testing/nvdimm/test/nfit_test.h
virt/kvm/arm/vgic/vgic-v2.c
virt/kvm/arm/vgic/vgic-v3.c
virt/kvm/kvm_main.c

diff --git a/CREDITS b/CREDITS
index 837367624e4598e1b936c25b9c2095f5d43e33eb..d7ebdfbc4d4fae70cb1bc11d82503c2c92a6d27c 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -9,7 +9,7 @@
                        Linus
 ----------
 
-M: Matt Mackal
+N: Matt Mackal
 E: mpm@selenic.com
 D: SLOB slab allocator
 
@@ -1910,7 +1910,7 @@ S: Ra'annana, Israel
 
 N: Andi Kleen
 E: andi@firstfloor.org
-U: http://www.halobates.de
+W: http://www.halobates.de
 D: network, x86, NUMA, various hacks
 S: Schwalbenstr. 96
 S: 85551 Ottobrunn
@@ -2089,8 +2089,8 @@ D: ST Microelectronics SPEAr13xx PCI host bridge driver
 D: Synopsys Designware PCI host bridge driver
 
 N: Gabor Kuti
-M: seasons@falcon.sch.bme.hu
-M: seasons@makosteszta.sote.hu
+E: seasons@falcon.sch.bme.hu
+E: seasons@makosteszta.sote.hu
 D: Original author of software suspend
 
 N: Jaroslav Kysela
index e1d76812419cad0dcba664263ac09d12b90f069c..05150957ecfda1bdee82f716fc7a00c70f9aa713 100644 (file)
@@ -9,10 +9,26 @@ The following properties are common to the Ethernet controllers:
 - max-speed: number, specifies maximum speed in Mbit/s supported by the device;
 - max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than
   the maximum frame size (there's contradiction in ePAPR).
-- phy-mode: string, operation mode of the PHY interface; supported values are
-  "mii", "gmii", "sgmii", "qsgmii", "tbi", "rev-mii", "rmii", "rgmii", "rgmii-id",
-  "rgmii-rxid", "rgmii-txid", "rtbi", "smii", "xgmii", "trgmii"; this is now a
-  de-facto standard property;
+- phy-mode: string, operation mode of the PHY interface. This is now a de-facto
+  standard property; supported values are:
+  * "mii"
+  * "gmii"
+  * "sgmii"
+  * "qsgmii"
+  * "tbi"
+  * "rev-mii"
+  * "rmii"
+  * "rgmii" (RX and TX delays are added by the MAC when required)
+  * "rgmii-id" (RGMII with internal RX and TX delays provided by the PHY, the
+     MAC should not add the RX or TX delays in this case)
+  * "rgmii-rxid" (RGMII with internal RX delay provided by the PHY, the MAC
+     should not add an RX delay in this case)
+  * "rgmii-txid" (RGMII with internal TX delay provided by the PHY, the MAC
+     should not add an TX delay in this case)
+  * "rtbi"
+  * "smii"
+  * "xgmii"
+  * "trgmii"
 - phy-connection-type: the same as "phy-mode" property but described in ePAPR;
 - phy-handle: phandle, specifies a reference to a node representing a PHY
   device; this property is described in ePAPR and so preferred;
diff --git a/Documentation/devicetree/bindings/power/domain-idle-state.txt b/Documentation/devicetree/bindings/power/domain-idle-state.txt
new file mode 100644 (file)
index 0000000..eefc7ed
--- /dev/null
@@ -0,0 +1,33 @@
+PM Domain Idle State Node:
+
+A domain idle state node represents the state parameters that will be used to
+select the state when there are no active components in the domain.
+
+The state node has the following parameters -
+
+- compatible:
+       Usage: Required
+       Value type: <string>
+       Definition: Must be "domain-idle-state".
+
+- entry-latency-us
+       Usage: Required
+       Value type: <prop-encoded-array>
+       Definition: u32 value representing worst case latency in
+                   microseconds required to enter the idle state.
+                   The exit-latency-us duration may be guaranteed
+                   only after entry-latency-us has passed.
+
+- exit-latency-us
+       Usage: Required
+       Value type: <prop-encoded-array>
+       Definition: u32 value representing worst case latency
+                   in microseconds required to exit the idle state.
+
+- min-residency-us
+       Usage: Required
+       Value type: <prop-encoded-array>
+       Definition: u32 value representing minimum residency duration
+                   in microseconds after which the idle state will yield
+                   power benefits after overcoming the overhead in entering
+i                  the idle state.
index 025b5e7df61c630c3048d6b6befa8735296e7884..723e1ad937da24edefa5c48b03ccb1f345c9919f 100644 (file)
@@ -29,6 +29,15 @@ Optional properties:
    specified by this binding. More details about power domain specifier are
    available in the next section.
 
+- domain-idle-states : A phandle of an idle-state that shall be soaked into a
+                generic domain power state. The idle state definitions are
+                compatible with domain-idle-state specified in [1].
+  The domain-idle-state property reflects the idle state of this PM domain and
+  not the idle states of the devices or sub-domains in the PM domain. Devices
+  and sub-domains have their own idle-states independent of the parent
+  domain's idle states. In the absence of this property, the domain would be
+  considered as capable of being powered-on or powered-off.
+
 Example:
 
        power: power-controller@12340000 {
@@ -59,6 +68,38 @@ The nodes above define two power controllers: 'parent' and 'child'.
 Domains created by the 'child' power controller are subdomains of '0' power
 domain provided by the 'parent' power controller.
 
+Example 3:
+       parent: power-controller@12340000 {
+               compatible = "foo,power-controller";
+               reg = <0x12340000 0x1000>;
+               #power-domain-cells = <0>;
+               domain-idle-states = <&DOMAIN_RET>, <&DOMAIN_PWR_DN>;
+       };
+
+       child: power-controller@12341000 {
+               compatible = "foo,power-controller";
+               reg = <0x12341000 0x1000>;
+               power-domains = <&parent 0>;
+               #power-domain-cells = <0>;
+               domain-idle-states = <&DOMAIN_PWR_DN>;
+       };
+
+       DOMAIN_RET: state@0 {
+               compatible = "domain-idle-state";
+               reg = <0x0>;
+               entry-latency-us = <1000>;
+               exit-latency-us = <2000>;
+               min-residency-us = <10000>;
+       };
+
+       DOMAIN_PWR_DN: state@1 {
+               compatible = "domain-idle-state";
+               reg = <0x1>;
+               entry-latency-us = <5000>;
+               exit-latency-us = <8000>;
+               min-residency-us = <7000>;
+       };
+
 ==PM domain consumers==
 
 Required properties:
@@ -76,3 +117,5 @@ Example:
 The node above defines a typical PM domain consumer device, which is located
 inside a PM domain with index 0 of a power controller represented by a node
 with the label "power".
+
+[1]. Documentation/devicetree/bindings/power/domain-idle-state.txt
index 399e4e866a9c4df6104d8a048b5d2546db0da0f4..433b6724797ad7e9476f041c7f0e2dcd77ca8579 100644 (file)
@@ -62,10 +62,13 @@ nf_conntrack_generic_timeout - INTEGER (seconds)
        protocols.
 
 nf_conntrack_helper - BOOLEAN
-       0 - disabled
-       not 0 - enabled (default)
+       0 - disabled (default)
+       not 0 - enabled
 
        Enable automatic conntrack helper assignment.
+       If disabled it is required to set up iptables rules to assign
+       helpers to connections.  See the CT target description in the
+       iptables-extensions(8) man page for further information.
 
 nf_conntrack_icmp_timeout - INTEGER (seconds)
        default 30
index 8ba6625fdd63da42eae53cbbb1ca6539c199aa2e..73ddea39a9cefc40964f06c2d8e1611d67879eca 100644 (file)
@@ -607,7 +607,9 @@ individually.  Instead, a set of devices sharing a power resource can be put
 into a low-power state together at the same time by turning off the shared
 power resource.  Of course, they also need to be put into the full-power state
 together, by turning the shared power resource on.  A set of devices with this
-property is often referred to as a power domain.
+property is often referred to as a power domain. A power domain may also be
+nested inside another power domain. The nested domain is referred to as the
+sub-domain of the parent domain.
 
 Support for power domains is provided through the pm_domain field of struct
 device.  This field is a pointer to an object of type struct dev_pm_domain,
@@ -629,6 +631,16 @@ support for power domains into subsystem-level callbacks, for example by
 modifying the platform bus type.  Other platforms need not implement it or take
 it into account in any way.
 
+Devices may be defined as IRQ-safe which indicates to the PM core that their
+runtime PM callbacks may be invoked with disabled interrupts (see
+Documentation/power/runtime_pm.txt for more information).  If an IRQ-safe
+device belongs to a PM domain, the runtime PM of the domain will be
+disallowed, unless the domain itself is defined as IRQ-safe. However, it
+makes sense to define a PM domain as IRQ-safe only if all the devices in it
+are IRQ-safe. Moreover, if an IRQ-safe domain has a parent domain, the runtime
+PM of the parent is only allowed if the parent itself is IRQ-safe too with the
+additional restriction that all child domains of an IRQ-safe parent must also
+be IRQ-safe.
 
 Device Low Power (suspend) States
 ---------------------------------
index 8d4148406923f6cd77a277bd95c43b7d46e2288b..63cefa62324cd1e0cc788efbeffcff9b4ab875f3 100644 (file)
@@ -9257,11 +9257,12 @@ S:      Maintained
 F:     drivers/pci/host/*layerscape*
 
 PCI DRIVER FOR IMX6
-M:     Richard Zhu <Richard.Zhu@freescale.com>
+M:     Richard Zhu <hongxing.zhu@nxp.com>
 M:     Lucas Stach <l.stach@pengutronix.de>
 L:     linux-pci@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
+F:     Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 F:     drivers/pci/host/*imx6*
 
 PCI DRIVER FOR TI KEYSTONE
@@ -9320,17 +9321,11 @@ F:      drivers/pci/host/pci-exynos.c
 
 PCI DRIVER FOR SYNOPSIS DESIGNWARE
 M:     Jingoo Han <jingoohan1@gmail.com>
-M:     Pratyush Anand <pratyush.anand@gmail.com>
-L:     linux-pci@vger.kernel.org
-S:     Maintained
-F:     drivers/pci/host/*designware*
-
-PCI DRIVER FOR SYNOPSYS PROTOTYPING DEVICE
-M:     Jose Abreu <Jose.Abreu@synopsys.com>
+M:     Joao Pinto <Joao.Pinto@synopsys.com>
 L:     linux-pci@vger.kernel.org
 S:     Maintained
 F:     Documentation/devicetree/bindings/pci/designware-pcie.txt
-F:     drivers/pci/host/pcie-designware-plat.c
+F:     drivers/pci/host/*designware*
 
 PCI DRIVER FOR GENERIC OF HOSTS
 M:     Will Deacon <will.deacon@arm.com>
index 694111b43cf8a5a8df969010f3d32a50bae2854a..b1037774e8e83c86fc93afbd705acf8591c6b4ec 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 4
 PATCHLEVEL = 9
 SUBLEVEL = 0
-EXTRAVERSION = -rc7
-NAME = Psychotic Stoned Sheep
+EXTRAVERSION =
+NAME = Roaring Lionus
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
@@ -607,6 +607,13 @@ else
 include/config/auto.conf: ;
 endif # $(dot-config)
 
+# For the kernel to actually contain only the needed exported symbols,
+# we have to build modules as well to determine what those symbols are.
+# (this can be evaluated only once include/config/auto.conf has been included)
+ifdef CONFIG_TRIM_UNUSED_KSYMS
+  KBUILD_MODULES := 1
+endif
+
 # The all: target is the default when no target is given on the
 # command line.
 # This allow a user to issue only 'make' to build a kernel including modules
@@ -944,7 +951,7 @@ ifdef CONFIG_GDB_SCRIPTS
 endif
 ifdef CONFIG_TRIM_UNUSED_KSYMS
        $(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \
-         "$(MAKE) KBUILD_MODULES=1 -f $(srctree)/Makefile vmlinux_prereq"
+         "$(MAKE) -f $(srctree)/Makefile vmlinux"
 endif
 
 # standalone target for easier testing
@@ -1019,8 +1026,6 @@ prepare2: prepare3 prepare-compiler-check outputmakefile asm-generic
 prepare1: prepare2 $(version_h) include/generated/utsrelease.h \
                    include/config/auto.conf
        $(cmd_crmodverdir)
-       $(Q)test -e include/generated/autoksyms.h || \
-           touch   include/generated/autoksyms.h
 
 archprepare: archheaders archscripts prepare1 scripts_basic
 
index 08e7e2a16ac176a597ceb21c3b0f399b6ad98ea6..a36e8601114d2ca2970f257f9f8d7e5c03ec08a2 100644 (file)
 static inline void __delay(unsigned long loops)
 {
        __asm__ __volatile__(
-       "       lp  1f  \n"
-       "       nop     \n"
-       "1:             \n"
-       : "+l"(loops));
+       "       mov lp_count, %0        \n"
+       "       lp  1f                  \n"
+       "       nop                     \n"
+       "1:                             \n"
+       : : "r"(loops));
 }
 
 extern void __bad_udelay(void);
index 89eeb372005180802181d860be8f215768701659..e94ca72b974e7c7b31c2d631cb773ab3ad707b8d 100644 (file)
@@ -280,7 +280,7 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
 
 #define pte_page(pte)          pfn_to_page(pte_pfn(pte))
 #define mk_pte(page, prot)     pfn_pte(page_to_pfn(page), prot)
-#define pfn_pte(pfn, prot)     __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define pfn_pte(pfn, prot)     __pte(__pfn_to_phys(pfn) | pgprot_val(prot))
 
 /* Don't use virt_to_pfn for macros below: could cause truncations for PAE40*/
 #define pte_pfn(pte)           (pte_val(pte) >> PAGE_SHIFT)
index 2b96cfc3be751a6d56fd13a9531c40e4f8debd8b..50d71695cd4ecbeefd64f28e9f44265195b01d15 100644 (file)
@@ -23,7 +23,7 @@
 
 static int l2_line_sz;
 static int ioc_exists;
-int slc_enable = 1, ioc_enable = 1;
+int slc_enable = 1, ioc_enable = 0;
 unsigned long perip_base = ARC_UNCACHED_ADDR_SPACE; /* legacy value for boot */
 unsigned long perip_end = 0xFFFFFFFF; /* legacy value */
 
index befcd26199021e4bf61f5e90a508ebdda16e347b..c558ba75cbccf909063e0f4f131f7efdfd28867b 100644 (file)
@@ -745,7 +745,6 @@ dtb-$(CONFIG_MACH_SUN4I) += \
        sun4i-a10-pcduino2.dtb \
        sun4i-a10-pov-protab2-ips9.dtb
 dtb-$(CONFIG_MACH_SUN5I) += \
-       ntc-gr8-evb.dtb \
        sun5i-a10s-auxtek-t003.dtb \
        sun5i-a10s-auxtek-t004.dtb \
        sun5i-a10s-mk802.dtb \
@@ -761,6 +760,7 @@ dtb-$(CONFIG_MACH_SUN5I) += \
        sun5i-a13-olinuxino-micro.dtb \
        sun5i-a13-q8-tablet.dtb \
        sun5i-a13-utoo-p66.dtb \
+       sun5i-gr8-evb.dtb \
        sun5i-r8-chip.dtb
 dtb-$(CONFIG_MACH_SUN6I) += \
        sun6i-a31-app4-evb1.dtb \
index 0d7d5ac6257b5080f84b855d62f9edc93af74fea..2b6cb05bc01a85f937823d8c1c97fd5aec13bb5c 100644 (file)
                                reg = <0x30730000 0x10000>;
                                interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>,
-                                       <&clks IMX7D_CLK_DUMMY>,
-                                       <&clks IMX7D_CLK_DUMMY>;
-                               clock-names = "pix", "axi", "disp_axi";
+                                       <&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>;
+                               clock-names = "pix", "axi";
                                status = "disabled";
                        };
                };
diff --git a/arch/arm/boot/dts/ntc-gr8-evb.dts b/arch/arm/boot/dts/ntc-gr8-evb.dts
deleted file mode 100644 (file)
index 4b622f3..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Copyright 2016 Free Electrons
- * Copyright 2016 NextThing Co
- *
- * Mylène Josserand <mylene.josserand@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/dts-v1/;
-#include "ntc-gr8.dtsi"
-#include "sunxi-common-regulators.dtsi"
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-
-/ {
-       model = "NextThing GR8-EVB";
-       compatible = "nextthing,gr8-evb", "nextthing,gr8";
-
-       aliases {
-               i2c0 = &i2c0;
-               i2c1 = &i2c1;
-               i2c2 = &i2c2;
-               serial0 = &uart1;
-               serial1 = &uart2;
-       };
-
-       chosen {
-               stdout-path = "serial0:115200n8";
-       };
-
-       backlight: backlight {
-               compatible = "pwm-backlight";
-               pwms = <&pwm 0 10000 0>;
-               enable-gpios = <&axp_gpio 1 GPIO_ACTIVE_HIGH>;
-
-               brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
-               default-brightness-level = <8>;
-       };
-};
-
-&be0 {
-       status = "okay";
-};
-
-&codec {
-       status = "okay";
-};
-
-&ehci0 {
-       status = "okay";
-};
-
-&i2c0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&i2c0_pins_a>;
-       status = "okay";
-
-       axp209: pmic@34 {
-               reg = <0x34>;
-
-               /*
-               * The interrupt is routed through the "External Fast
-               * Interrupt Request" pin (ball G13 of the module)
-               * directly to the main interrupt controller, without
-               * any other controller interfering.
-               */
-               interrupts = <0>;
-       };
-};
-
-#include "axp209.dtsi"
-
-&i2c1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&i2c1_pins_a>;
-       status = "okay";
-
-       wm8978: codec@1a {
-               #sound-dai-cells = <0>;
-               compatible = "wlf,wm8978";
-               reg = <0x1a>;
-       };
-
-       pcf8563: rtc@51 {
-               compatible = "phg,pcf8563";
-               reg = <0x51>;
-       };
-};
-
-&i2c2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&i2c2_pins_a>;
-       status = "okay";
-};
-
-&i2s0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&i2s0_mclk_pins_a>, <&i2s0_data_pins_a>;
-       status = "okay";
-};
-
-&ir0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&ir0_rx_pins_a>;
-       status = "okay";
-};
-
-&lradc {
-       vref-supply = <&reg_ldo2>;
-       status = "okay";
-
-       button@190 {
-               label = "Volume Up";
-               linux,code = <KEY_VOLUMEUP>;
-               channel = <0>;
-               voltage = <190000>;
-       };
-
-       button@390 {
-               label = "Volume Down";
-               linux,code = <KEY_VOLUMEDOWN>;
-               channel = <0>;
-               voltage = <390000>;
-       };
-
-       button@600 {
-               label = "Menu";
-               linux,code = <KEY_MENU>;
-               channel = <0>;
-               voltage = <600000>;
-       };
-
-       button@800 {
-               label = "Search";
-               linux,code = <KEY_SEARCH>;
-               channel = <0>;
-               voltage = <800000>;
-       };
-
-       button@980 {
-               label = "Home";
-               linux,code = <KEY_HOMEPAGE>;
-               channel = <0>;
-               voltage = <980000>;
-       };
-
-       button@1180 {
-               label = "Esc";
-               linux,code = <KEY_ESC>;
-               channel = <0>;
-               voltage = <1180000>;
-       };
-
-       button@1400 {
-               label = "Enter";
-               linux,code = <KEY_ENTER>;
-               channel = <0>;
-               voltage = <1400000>;
-       };
-};
-
-&mmc0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_gr8_evb>;
-       vmmc-supply = <&reg_vcc3v3>;
-       bus-width = <4>;
-       cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
-       cd-inverted;
-       status = "okay";
-};
-
-&nfc {
-       pinctrl-names = "default";
-       pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
-
-       /* MLC Support sucks for now */
-       status = "disabled";
-};
-
-&ohci0 {
-       status = "okay";
-};
-
-&otg_sram {
-       status = "okay";
-};
-
-&pio {
-       mmc0_cd_pin_gr8_evb: mmc0-cd-pin@0 {
-               allwinner,pins = "PG0";
-               allwinner,function = "gpio_in";
-               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-       };
-
-       usb0_id_pin_gr8_evb: usb0-id-pin@0 {
-               allwinner,pins = "PG2";
-               allwinner,function = "gpio_in";
-               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-       };
-
-       usb0_vbus_det_pin_gr8_evb: usb0-vbus-det-pin@0 {
-               allwinner,pins = "PG1";
-               allwinner,function = "gpio_in";
-               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-       };
-
-       usb1_vbus_pin_gr8_evb: usb1-vbus-pin@0 {
-               allwinner,pins = "PG13";
-               allwinner,function = "gpio_out";
-               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-       };
-};
-
-&pwm {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pwm0_pins_a>;
-       status = "okay";
-};
-
-&reg_dcdc2 {
-       regulator-min-microvolt = <1000000>;
-       regulator-max-microvolt = <1400000>;
-       regulator-name = "vdd-cpu";
-       regulator-always-on;
-};
-
-&reg_dcdc3 {
-       regulator-min-microvolt = <1000000>;
-       regulator-max-microvolt = <1300000>;
-       regulator-name = "vdd-sys";
-       regulator-always-on;
-};
-
-&reg_ldo1 {
-       regulator-name = "vdd-rtc";
-};
-
-&reg_ldo2 {
-       regulator-min-microvolt = <2700000>;
-       regulator-max-microvolt = <3300000>;
-       regulator-name = "avcc";
-       regulator-always-on;
-};
-
-&reg_usb1_vbus {
-       pinctrl-0 = <&usb1_vbus_pin_gr8_evb>;
-       gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>;
-       status = "okay";
-};
-
-&rtp {
-       allwinner,ts-attached;
-};
-
-&spdif {
-       pinctrl-names = "default";
-       pinctrl-0 = <&spdif_tx_pins_a>;
-       status = "okay";
-};
-
-&tve0 {
-       status = "okay";
-};
-
-&uart1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart1_pins_a>, <&uart1_cts_rts_pins_a>;
-       status = "okay";
-};
-
-&usb_otg {
-       /*
-        * The GR8-EVB has a somewhat interesting design. There's a
-        * pin supposed to control VBUS, an ID pin, a VBUS detect pin,
-        * so everything should work just fine.
-        *
-        * Except that the pin supposed to control VBUS is not
-        * connected to any controllable output, neither to the SoC
-        * through a GPIO or to the PMIC, and it is pulled down,
-        * meaning that we will never be able to enable VBUS on this
-        * board.
-        */
-       dr_mode = "otg";
-       status = "okay";
-};
-
-&usb_power_supply {
-       status = "okay";
-};
-
-&usbphy {
-       pinctrl-names = "default";
-       pinctrl-0 = <&usb0_id_pin_gr8_evb>, <&usb0_vbus_det_pin_gr8_evb>;
-       usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
-       usb0_vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
-       usb0_vbus_power-supply = <&usb_power_supply>;
-       usb1_vbus-supply = <&reg_usb1_vbus>;
-       status = "okay";
-};
diff --git a/arch/arm/boot/dts/ntc-gr8.dtsi b/arch/arm/boot/dts/ntc-gr8.dtsi
deleted file mode 100644 (file)
index ca54e03..0000000
+++ /dev/null
@@ -1,1087 +0,0 @@
-/*
- * Copyright 2016 Mylène Josserand
- *
- * Mylène Josserand <mylene.josserand@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <dt-bindings/clock/sun4i-a10-pll2.h>
-#include <dt-bindings/dma/sun4i-a10.h>
-#include <dt-bindings/pinctrl/sun4i-a10.h>
-
-/ {
-       interrupt-parent = <&intc>;
-       #address-cells = <1>;
-       #size-cells = <1>;
-
-       cpus {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               cpu0: cpu@0 {
-                       device_type = "cpu";
-                       compatible = "arm,cortex-a8";
-                       reg = <0x0>;
-                       clocks = <&cpu>;
-               };
-       };
-
-       clocks {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               /*
-                * This is a dummy clock, to be used as placeholder on
-                * other mux clocks when a specific parent clock is not
-                * yet implemented. It should be dropped when the driver
-                * is complete.
-                */
-               dummy: dummy {
-                       #clock-cells = <0>;
-                       compatible = "fixed-clock";
-                       clock-frequency = <0>;
-               };
-
-               osc24M: clk@01c20050 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-osc-clk";
-                       reg = <0x01c20050 0x4>;
-                       clock-frequency = <24000000>;
-                       clock-output-names = "osc24M";
-               };
-
-               osc3M: osc3M-clk {
-                       compatible = "fixed-factor-clock";
-                       #clock-cells = <0>;
-                       clock-div = <8>;
-                       clock-mult = <1>;
-                       clocks = <&osc24M>;
-                       clock-output-names = "osc3M";
-               };
-
-               osc32k: clk@0 {
-                       #clock-cells = <0>;
-                       compatible = "fixed-clock";
-                       clock-frequency = <32768>;
-                       clock-output-names = "osc32k";
-               };
-
-               pll1: clk@01c20000 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-pll1-clk";
-                       reg = <0x01c20000 0x4>;
-                       clocks = <&osc24M>;
-                       clock-output-names = "pll1";
-               };
-
-               pll2: clk@01c20008 {
-                       #clock-cells = <1>;
-                       compatible = "allwinner,sun5i-a13-pll2-clk";
-                       reg = <0x01c20008 0x8>;
-                       clocks = <&osc24M>;
-                       clock-output-names = "pll2-1x", "pll2-2x",
-                                            "pll2-4x", "pll2-8x";
-               };
-
-               pll3: clk@01c20010 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-pll3-clk";
-                       reg = <0x01c20010 0x4>;
-                       clocks = <&osc3M>;
-                       clock-output-names = "pll3";
-               };
-
-               pll3x2: pll3x2-clk {
-                       compatible = "allwinner,sun4i-a10-pll3-2x-clk";
-                       #clock-cells = <0>;
-                       clock-div = <1>;
-                       clock-mult = <2>;
-                       clocks = <&pll3>;
-                       clock-output-names = "pll3-2x";
-               };
-
-               pll4: clk@01c20018 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-pll1-clk";
-                       reg = <0x01c20018 0x4>;
-                       clocks = <&osc24M>;
-                       clock-output-names = "pll4";
-               };
-
-               pll5: clk@01c20020 {
-                       #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-a10-pll5-clk";
-                       reg = <0x01c20020 0x4>;
-                       clocks = <&osc24M>;
-                       clock-output-names = "pll5_ddr", "pll5_other";
-               };
-
-               pll6: clk@01c20028 {
-                       #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-a10-pll6-clk";
-                       reg = <0x01c20028 0x4>;
-                       clocks = <&osc24M>;
-                       clock-output-names = "pll6_sata", "pll6_other", "pll6";
-               };
-
-               pll7: clk@01c20030 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-pll3-clk";
-                       reg = <0x01c20030 0x4>;
-                       clocks = <&osc3M>;
-                       clock-output-names = "pll7";
-               };
-
-               pll7x2: pll7x2-clk {
-                       compatible = "allwinner,sun4i-a10-pll3-2x-clk";
-                       #clock-cells = <0>;
-                       clock-div = <1>;
-                       clock-mult = <2>;
-                       clocks = <&pll7>;
-                       clock-output-names = "pll7-2x";
-               };
-
-               /* dummy is 200M */
-               cpu: cpu@01c20054 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-cpu-clk";
-                       reg = <0x01c20054 0x4>;
-                       clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
-                       clock-output-names = "cpu";
-               };
-
-               axi: axi@01c20054 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-axi-clk";
-                       reg = <0x01c20054 0x4>;
-                       clocks = <&cpu>;
-                       clock-output-names = "axi";
-               };
-
-               ahb: ahb@01c20054 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun5i-a13-ahb-clk";
-                       reg = <0x01c20054 0x4>;
-                       clocks = <&axi>, <&cpu>, <&pll6 1>;
-                       clock-output-names = "ahb";
-                       /*
-                        * Use PLL6 as parent, instead of CPU/AXI
-                        * which has rate changes due to cpufreq
-                        */
-                       assigned-clocks = <&ahb>;
-                       assigned-clock-parents = <&pll6 1>;
-               };
-
-               apb0: apb0@01c20054 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-apb0-clk";
-                       reg = <0x01c20054 0x4>;
-                       clocks = <&ahb>;
-                       clock-output-names = "apb0";
-               };
-
-               apb1: clk@01c20058 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-apb1-clk";
-                       reg = <0x01c20058 0x4>;
-                       clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
-                       clock-output-names = "apb1";
-               };
-
-               axi_gates: clk@01c2005c {
-                       #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-a10-gates-clk";
-                       reg = <0x01c2005c 0x4>;
-                       clocks = <&axi>;
-                       clock-indices = <0>;
-                       clock-output-names = "axi_dram";
-               };
-
-               ahb_gates: clk@01c20060 {
-                       #clock-cells = <1>;
-                       compatible = "allwinner,sun5i-a13-ahb-gates-clk";
-                       reg = <0x01c20060 0x8>;
-                       clocks = <&ahb>;
-                       clock-indices = <0>, <1>,
-                                       <2>, <5>, <6>,
-                                       <7>, <8>, <9>,
-                                       <10>, <13>,
-                                       <14>, <17>, <20>,
-                                       <21>, <22>,
-                                       <28>, <32>, <34>,
-                                       <36>, <40>, <44>,
-                                       <46>, <51>,
-                                       <52>;
-                       clock-output-names = "ahb_usbotg", "ahb_ehci",
-                                            "ahb_ohci", "ahb_ss", "ahb_dma",
-                                            "ahb_bist", "ahb_mmc0", "ahb_mmc1",
-                                            "ahb_mmc2", "ahb_nand",
-                                            "ahb_sdram", "ahb_emac", "ahb_spi0",
-                                            "ahb_spi1", "ahb_spi2",
-                                            "ahb_hstimer", "ahb_ve", "ahb_tve",
-                                            "ahb_lcd", "ahb_csi", "ahb_de_be",
-                                            "ahb_de_fe", "ahb_iep",
-                                            "ahb_mali400";
-               };
-
-               apb0_gates: clk@01c20068 {
-                       #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-a10-gates-clk";
-                       reg = <0x01c20068 0x4>;
-                       clocks = <&apb0>;
-                       clock-indices = <0>, <3>,
-                                       <5>, <6>;
-                       clock-output-names = "apb0_codec", "apb0_i2s0",
-                                            "apb0_pio", "apb0_ir";
-               };
-
-               apb1_gates: clk@01c2006c {
-                       #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-a10-gates-clk";
-                       reg = <0x01c2006c 0x4>;
-                       clocks = <&apb1>;
-                       clock-indices = <0>, <1>,
-                                       <2>, <17>,
-                                       <18>, <19>;
-                       clock-output-names = "apb1_i2c0", "apb1_i2c1",
-                                            "apb1_i2c2", "apb1_uart1",
-                                            "apb1_uart2", "apb1_uart3";
-               };
-
-               nand_clk: clk@01c20080 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
-                       reg = <0x01c20080 0x4>;
-                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "nand";
-               };
-
-               ms_clk: clk@01c20084 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
-                       reg = <0x01c20084 0x4>;
-                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "ms";
-               };
-
-               mmc0_clk: clk@01c20088 {
-                       #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-a10-mmc-clk";
-                       reg = <0x01c20088 0x4>;
-                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc0",
-                                            "mmc0_output",
-                                            "mmc0_sample";
-               };
-
-               mmc1_clk: clk@01c2008c {
-                       #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-a10-mmc-clk";
-                       reg = <0x01c2008c 0x4>;
-                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc1",
-                                            "mmc1_output",
-                                            "mmc1_sample";
-               };
-
-               mmc2_clk: clk@01c20090 {
-                       #clock-cells = <1>;
-                       compatible = "allwinner,sun4i-a10-mmc-clk";
-                       reg = <0x01c20090 0x4>;
-                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mmc2",
-                                            "mmc2_output",
-                                            "mmc2_sample";
-               };
-
-               ts_clk: clk@01c20098 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
-                       reg = <0x01c20098 0x4>;
-                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "ts";
-               };
-
-               ss_clk: clk@01c2009c {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
-                       reg = <0x01c2009c 0x4>;
-                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "ss";
-               };
-
-               spi0_clk: clk@01c200a0 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
-                       reg = <0x01c200a0 0x4>;
-                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "spi0";
-               };
-
-               spi1_clk: clk@01c200a4 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
-                       reg = <0x01c200a4 0x4>;
-                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "spi1";
-               };
-
-               spi2_clk: clk@01c200a8 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
-                       reg = <0x01c200a8 0x4>;
-                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "spi2";
-               };
-
-               ir0_clk: clk@01c200b0 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod0-clk";
-                       reg = <0x01c200b0 0x4>;
-                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "ir0";
-               };
-
-               i2s0_clk: clk@01c200b8 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod1-clk";
-                       reg = <0x01c200b8 0x4>;
-                       clocks = <&pll2 SUN4I_A10_PLL2_8X>,
-                                <&pll2 SUN4I_A10_PLL2_4X>,
-                                <&pll2 SUN4I_A10_PLL2_2X>,
-                                <&pll2 SUN4I_A10_PLL2_1X>;
-                       clock-output-names = "i2s0";
-               };
-
-               spdif_clk: clk@01c200c0 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-mod1-clk";
-                       reg = <0x01c200c0 0x4>;
-                       clocks = <&pll2 SUN4I_A10_PLL2_8X>,
-                                <&pll2 SUN4I_A10_PLL2_4X>,
-                                <&pll2 SUN4I_A10_PLL2_2X>,
-                                <&pll2 SUN4I_A10_PLL2_1X>;
-                       clock-output-names = "spdif";
-               };
-
-               usb_clk: clk@01c200cc {
-                       #clock-cells = <1>;
-                       #reset-cells = <1>;
-                       compatible = "allwinner,sun5i-a13-usb-clk";
-                       reg = <0x01c200cc 0x4>;
-                       clocks = <&pll6 1>;
-                       clock-output-names = "usb_ohci0", "usb_phy";
-               };
-
-               dram_gates: clk@01c20100 {
-                       #clock-cells = <1>;
-                       compatible = "nextthing,gr8-dram-gates-clk",
-                                    "allwinner,sun4i-a10-gates-clk";
-                       reg = <0x01c20100 0x4>;
-                       clocks = <&pll5 0>;
-                       clock-indices = <0>,
-                                       <1>,
-                                       <25>,
-                                       <26>,
-                                       <29>,
-                                       <31>;
-                       clock-output-names = "dram_ve",
-                                            "dram_csi",
-                                            "dram_de_fe",
-                                            "dram_de_be",
-                                            "dram_ace",
-                                            "dram_iep";
-               };
-
-               de_be_clk: clk@01c20104 {
-                       #clock-cells = <0>;
-                       #reset-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-display-clk";
-                       reg = <0x01c20104 0x4>;
-                       clocks = <&pll3>, <&pll7>, <&pll5 1>;
-                       clock-output-names = "de-be";
-               };
-
-               de_fe_clk: clk@01c2010c {
-                       #clock-cells = <0>;
-                       #reset-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-display-clk";
-                       reg = <0x01c2010c 0x4>;
-                       clocks = <&pll3>, <&pll7>, <&pll5 1>;
-                       clock-output-names = "de-fe";
-               };
-
-               tcon_ch0_clk: clk@01c20118 {
-                       #clock-cells = <0>;
-                       #reset-cells = <1>;
-                       compatible = "allwinner,sun4i-a10-tcon-ch0-clk";
-                       reg = <0x01c20118 0x4>;
-                       clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
-                       clock-output-names = "tcon-ch0-sclk";
-               };
-
-               tcon_ch1_clk: clk@01c2012c {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-tcon-ch1-clk";
-                       reg = <0x01c2012c 0x4>;
-                       clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
-                       clock-output-names = "tcon-ch1-sclk";
-               };
-
-               codec_clk: clk@01c20140 {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-codec-clk";
-                       reg = <0x01c20140 0x4>;
-                       clocks = <&pll2 SUN4I_A10_PLL2_1X>;
-                       clock-output-names = "codec";
-               };
-
-               mbus_clk: clk@01c2015c {
-                       #clock-cells = <0>;
-                       compatible = "allwinner,sun5i-a13-mbus-clk";
-                       reg = <0x01c2015c 0x4>;
-                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-                       clock-output-names = "mbus";
-               };
-       };
-
-       display-engine {
-               compatible = "allwinner,sun5i-a13-display-engine";
-               allwinner,pipelines = <&fe0>;
-       };
-
-       soc@01c00000 {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               sram-controller@01c00000 {
-                       compatible = "allwinner,sun4i-a10-sram-controller";
-                       reg = <0x01c00000 0x30>;
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges;
-
-                       sram_a: sram@00000000 {
-                               compatible = "mmio-sram";
-                               reg = <0x00000000 0xc000>;
-                               #address-cells = <1>;
-                               #size-cells = <1>;
-                               ranges = <0 0x00000000 0xc000>;
-                       };
-
-                       sram_d: sram@00010000 {
-                               compatible = "mmio-sram";
-                               reg = <0x00010000 0x1000>;
-                               #address-cells = <1>;
-                               #size-cells = <1>;
-                               ranges = <0 0x00010000 0x1000>;
-
-                               otg_sram: sram-section@0000 {
-                                       compatible = "allwinner,sun4i-a10-sram-d";
-                                       reg = <0x0000 0x1000>;
-                                       status = "disabled";
-                               };
-                       };
-               };
-
-               dma: dma-controller@01c02000 {
-                       compatible = "allwinner,sun4i-a10-dma";
-                       reg = <0x01c02000 0x1000>;
-                       interrupts = <27>;
-                       clocks = <&ahb_gates 6>;
-                       #dma-cells = <2>;
-               };
-
-               nfc: nand@01c03000 {
-                       compatible = "allwinner,sun4i-a10-nand";
-                       reg = <0x01c03000 0x1000>;
-                       interrupts = <37>;
-                       clocks = <&ahb_gates 13>, <&nand_clk>;
-                       clock-names = "ahb", "mod";
-                       dmas = <&dma SUN4I_DMA_DEDICATED 3>;
-                       dma-names = "rxtx";
-                       status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-               };
-
-               spi0: spi@01c05000 {
-                       compatible = "allwinner,sun4i-a10-spi";
-                       reg = <0x01c05000 0x1000>;
-                       interrupts = <10>;
-                       clocks = <&ahb_gates 20>, <&spi0_clk>;
-                       clock-names = "ahb", "mod";
-                       dmas = <&dma SUN4I_DMA_DEDICATED 27>,
-                              <&dma SUN4I_DMA_DEDICATED 26>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-               };
-
-               spi1: spi@01c06000 {
-                       compatible = "allwinner,sun4i-a10-spi";
-                       reg = <0x01c06000 0x1000>;
-                       interrupts = <11>;
-                       clocks = <&ahb_gates 21>, <&spi1_clk>;
-                       clock-names = "ahb", "mod";
-                       dmas = <&dma SUN4I_DMA_DEDICATED 9>,
-                              <&dma SUN4I_DMA_DEDICATED 8>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-               };
-
-               tve0: tv-encoder@01c0a000 {
-                       compatible = "allwinner,sun4i-a10-tv-encoder";
-                       reg = <0x01c0a000 0x1000>;
-                       clocks = <&ahb_gates 34>;
-                       resets = <&tcon_ch0_clk 0>;
-                       status = "disabled";
-
-                       port {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               tve0_in_tcon0: endpoint@0 {
-                                       reg = <0>;
-                                       remote-endpoint = <&tcon0_out_tve0>;
-                               };
-                       };
-               };
-
-               tcon0: lcd-controller@01c0c000 {
-                       compatible = "allwinner,sun5i-a13-tcon";
-                       reg = <0x01c0c000 0x1000>;
-                       interrupts = <44>;
-                       resets = <&tcon_ch0_clk 1>;
-                       reset-names = "lcd";
-                       clocks = <&ahb_gates 36>,
-                                <&tcon_ch0_clk>,
-                                <&tcon_ch1_clk>;
-                       clock-names = "ahb",
-                                     "tcon-ch0",
-                                     "tcon-ch1";
-                       clock-output-names = "tcon-pixel-clock";
-                       status = "disabled";
-
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               tcon0_in: port@0 {
-                                       #address-cells = <1>;
-                                       #size-cells = <0>;
-                                       reg = <0>;
-
-                                       tcon0_in_be0: endpoint@0 {
-                                               reg = <0>;
-                                               remote-endpoint = <&be0_out_tcon0>;
-                                       };
-                               };
-
-                               tcon0_out: port@1 {
-                                       #address-cells = <1>;
-                                       #size-cells = <0>;
-                                       reg = <1>;
-
-                                       tcon0_out_tve0: endpoint@1 {
-                                               reg = <1>;
-                                               remote-endpoint = <&tve0_in_tcon0>;
-                                       };
-                               };
-                       };
-               };
-
-               mmc0: mmc@01c0f000 {
-                       compatible = "allwinner,sun5i-a13-mmc";
-                       reg = <0x01c0f000 0x1000>;
-                       clocks = <&ahb_gates 8>,
-                                <&mmc0_clk 0>,
-                                <&mmc0_clk 1>,
-                                <&mmc0_clk 2>;
-                       clock-names = "ahb",
-                                     "mmc",
-                                     "output",
-                                     "sample";
-                       interrupts = <32>;
-                       status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-               };
-
-               mmc1: mmc@01c10000 {
-                       compatible = "allwinner,sun5i-a13-mmc";
-                       reg = <0x01c10000 0x1000>;
-                       clocks = <&ahb_gates 9>,
-                                <&mmc1_clk 0>,
-                                <&mmc1_clk 1>,
-                                <&mmc1_clk 2>;
-                       clock-names = "ahb",
-                                     "mmc",
-                                     "output",
-                                     "sample";
-                       interrupts = <33>;
-                       status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-               };
-
-               mmc2: mmc@01c11000 {
-                       compatible = "allwinner,sun5i-a13-mmc";
-                       reg = <0x01c11000 0x1000>;
-                       clocks = <&ahb_gates 10>,
-                                <&mmc2_clk 0>,
-                                <&mmc2_clk 1>,
-                                <&mmc2_clk 2>;
-                       clock-names = "ahb",
-                                     "mmc",
-                                     "output",
-                                     "sample";
-                       interrupts = <34>;
-                       status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-               };
-
-               usb_otg: usb@01c13000 {
-                       compatible = "allwinner,sun4i-a10-musb";
-                       reg = <0x01c13000 0x0400>;
-                       clocks = <&ahb_gates 0>;
-                       interrupts = <38>;
-                       interrupt-names = "mc";
-                       phys = <&usbphy 0>;
-                       phy-names = "usb";
-                       extcon = <&usbphy 0>;
-                       allwinner,sram = <&otg_sram 1>;
-                       status = "disabled";
-
-                       dr_mode = "otg";
-               };
-
-               usbphy: phy@01c13400 {
-                       #phy-cells = <1>;
-                       compatible = "allwinner,sun5i-a13-usb-phy";
-                       reg = <0x01c13400 0x10 0x01c14800 0x4>;
-                       reg-names = "phy_ctrl", "pmu1";
-                       clocks = <&usb_clk 8>;
-                       clock-names = "usb_phy";
-                       resets = <&usb_clk 0>, <&usb_clk 1>;
-                       reset-names = "usb0_reset", "usb1_reset";
-                       status = "disabled";
-               };
-
-               ehci0: usb@01c14000 {
-                       compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
-                       reg = <0x01c14000 0x100>;
-                       interrupts = <39>;
-                       clocks = <&ahb_gates 1>;
-                       phys = <&usbphy 1>;
-                       phy-names = "usb";
-                       status = "disabled";
-               };
-
-               ohci0: usb@01c14400 {
-                       compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
-                       reg = <0x01c14400 0x100>;
-                       interrupts = <40>;
-                       clocks = <&usb_clk 6>, <&ahb_gates 2>;
-                       phys = <&usbphy 1>;
-                       phy-names = "usb";
-                       status = "disabled";
-               };
-
-               spi2: spi@01c17000 {
-                       compatible = "allwinner,sun4i-a10-spi";
-                       reg = <0x01c17000 0x1000>;
-                       interrupts = <12>;
-                       clocks = <&ahb_gates 22>, <&spi2_clk>;
-                       clock-names = "ahb", "mod";
-                       dmas = <&dma SUN4I_DMA_DEDICATED 29>,
-                              <&dma SUN4I_DMA_DEDICATED 28>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-               };
-
-               intc: interrupt-controller@01c20400 {
-                       compatible = "allwinner,sun4i-a10-ic";
-                       reg = <0x01c20400 0x400>;
-                       interrupt-controller;
-                       #interrupt-cells = <1>;
-               };
-
-               pio: pinctrl@01c20800 {
-                       compatible = "nextthing,gr8-pinctrl";
-                       reg = <0x01c20800 0x400>;
-                       interrupts = <28>;
-                       clocks = <&apb0_gates 5>;
-                       gpio-controller;
-                       interrupt-controller;
-                       #interrupt-cells = <3>;
-                       #gpio-cells = <3>;
-
-                       i2c0_pins_a: i2c0@0 {
-                               allwinner,pins = "PB0", "PB1";
-                               allwinner,function = "i2c0";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-
-                       i2c1_pins_a: i2c1@0 {
-                               allwinner,pins = "PB15", "PB16";
-                               allwinner,function = "i2c1";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-
-                       i2c2_pins_a: i2c2@0 {
-                               allwinner,pins = "PB17", "PB18";
-                               allwinner,function = "i2c2";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-
-                       i2s0_data_pins_a: i2s0-data@0 {
-                               allwinner,pins = "PB6", "PB7", "PB8", "PB9";
-                               allwinner,function = "i2s0";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-
-                       i2s0_mclk_pins_a: i2s0-mclk@0 {
-                               allwinner,pins = "PB6", "PB7", "PB8", "PB9";
-                               allwinner,function = "i2s0";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-
-                       ir0_rx_pins_a: ir0@0 {
-                               allwinner,pins = "PB4";
-                               allwinner,function = "ir0";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-
-                       lcd_rgb666_pins: lcd-rgb666@0 {
-                               allwinner,pins = "PD2", "PD3", "PD4", "PD5", "PD6", "PD7",
-                                                "PD10", "PD11", "PD12", "PD13", "PD14", "PD15",
-                                                "PD18", "PD19", "PD20", "PD21", "PD22", "PD23",
-                                                "PD24", "PD25", "PD26", "PD27";
-                               allwinner,function = "lcd0";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-
-                       mmc0_pins_a: mmc0@0 {
-                               allwinner,pins = "PF0", "PF1", "PF2", "PF3",
-                                                "PF4", "PF5";
-                               allwinner,function = "mmc0";
-                               allwinner,drive = <SUN4I_PINCTRL_30_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-
-                       nand_pins_a: nand-base0@0 {
-                               allwinner,pins = "PC0", "PC1", "PC2",
-                                               "PC5", "PC8", "PC9", "PC10",
-                                               "PC11", "PC12", "PC13", "PC14",
-                                               "PC15";
-                               allwinner,function = "nand0";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-
-                       nand_cs0_pins_a: nand-cs@0 {
-                               allwinner,pins = "PC4";
-                               allwinner,function = "nand0";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-
-                       nand_rb0_pins_a: nand-rb@0 {
-                               allwinner,pins = "PC6";
-                               allwinner,function = "nand0";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-
-                       pwm0_pins_a: pwm0@0 {
-                               allwinner,pins = "PB2";
-                               allwinner,function = "pwm0";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-
-                       spdif_tx_pins_a: spdif@0 {
-                               allwinner,pins = "PB10";
-                               allwinner,function = "spdif";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
-                       };
-
-                       uart1_pins_a: uart1@1 {
-                               allwinner,pins = "PG3", "PG4";
-                               allwinner,function = "uart1";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-
-                       uart1_cts_rts_pins_a: uart1-cts-rts@0 {
-                               allwinner,pins = "PG5", "PG6";
-                               allwinner,function = "uart1";
-                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-                       };
-               };
-
-               pwm: pwm@01c20e00 {
-                       compatible = "allwinner,sun5i-a10s-pwm";
-                       reg = <0x01c20e00 0xc>;
-                       clocks = <&osc24M>;
-                       #pwm-cells = <3>;
-                       status = "disabled";
-               };
-
-               timer@01c20c00 {
-                       compatible = "allwinner,sun4i-a10-timer";
-                       reg = <0x01c20c00 0x90>;
-                       interrupts = <22>;
-                       clocks = <&osc24M>;
-               };
-
-               wdt: watchdog@01c20c90 {
-                       compatible = "allwinner,sun4i-a10-wdt";
-                       reg = <0x01c20c90 0x10>;
-               };
-
-               spdif: spdif@01c21000 {
-                       #sound-dai-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-spdif";
-                       reg = <0x01c21000 0x400>;
-                       interrupts = <13>;
-                       clocks = <&apb0_gates 1>, <&spdif_clk>;
-                       clock-names = "apb", "spdif";
-                       dmas = <&dma SUN4I_DMA_NORMAL 2>,
-                              <&dma SUN4I_DMA_NORMAL 2>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
-
-               ir0: ir@01c21800 {
-                       compatible = "allwinner,sun4i-a10-ir";
-                       clocks = <&apb0_gates 6>, <&ir0_clk>;
-                       clock-names = "apb", "ir";
-                       interrupts = <5>;
-                       reg = <0x01c21800 0x40>;
-                       status = "disabled";
-               };
-
-               i2s0: i2s@01c22400 {
-                       #sound-dai-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-i2s";
-                       reg = <0x01c22400 0x400>;
-                       interrupts = <16>;
-                       clocks = <&apb0_gates 3>, <&i2s0_clk>;
-                       clock-names = "apb", "mod";
-                       dmas = <&dma SUN4I_DMA_NORMAL 3>,
-                              <&dma SUN4I_DMA_NORMAL 3>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
-
-               lradc: lradc@01c22800 {
-                       compatible = "allwinner,sun4i-a10-lradc-keys";
-                       reg = <0x01c22800 0x100>;
-                       interrupts = <31>;
-                       status = "disabled";
-               };
-
-               codec: codec@01c22c00 {
-                       #sound-dai-cells = <0>;
-                       compatible = "allwinner,sun4i-a10-codec";
-                       reg = <0x01c22c00 0x40>;
-                       interrupts = <30>;
-                       clocks = <&apb0_gates 0>, <&codec_clk>;
-                       clock-names = "apb", "codec";
-                       dmas = <&dma SUN4I_DMA_NORMAL 19>,
-                              <&dma SUN4I_DMA_NORMAL 19>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
-
-               rtp: rtp@01c25000 {
-                       compatible = "allwinner,sun5i-a13-ts";
-                       reg = <0x01c25000 0x100>;
-                       interrupts = <29>;
-                       #thermal-sensor-cells = <0>;
-               };
-
-               uart1: serial@01c28400 {
-                       compatible = "snps,dw-apb-uart";
-                       reg = <0x01c28400 0x400>;
-                       interrupts = <2>;
-                       reg-shift = <2>;
-                       reg-io-width = <4>;
-                       clocks = <&apb1_gates 17>;
-                       status = "disabled";
-               };
-
-               uart2: serial@01c28800 {
-                       compatible = "snps,dw-apb-uart";
-                       reg = <0x01c28800 0x400>;
-                       interrupts = <3>;
-                       reg-shift = <2>;
-                       reg-io-width = <4>;
-                       clocks = <&apb1_gates 18>;
-                       status = "disabled";
-               };
-
-               i2c0: i2c@01c2ac00 {
-                       compatible = "allwinner,sun4i-a10-i2c";
-                       reg = <0x01c2ac00 0x400>;
-                       interrupts = <7>;
-                       clocks = <&apb1_gates 0>;
-                       status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-               };
-
-               i2c1: i2c@01c2b000 {
-                       compatible = "allwinner,sun4i-a10-i2c";
-                       reg = <0x01c2b000 0x400>;
-                       interrupts = <8>;
-                       clocks = <&apb1_gates 1>;
-                       status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-               };
-
-               i2c2: i2c@01c2b400 {
-                       compatible = "allwinner,sun4i-a10-i2c";
-                       reg = <0x01c2b400 0x400>;
-                       interrupts = <9>;
-                       clocks = <&apb1_gates 2>;
-                       status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-               };
-
-               timer@01c60000 {
-                       compatible = "allwinner,sun5i-a13-hstimer";
-                       reg = <0x01c60000 0x1000>;
-                       interrupts = <82>, <83>;
-                       clocks = <&ahb_gates 28>;
-               };
-
-               fe0: display-frontend@01e00000 {
-                       compatible = "allwinner,sun5i-a13-display-frontend";
-                       reg = <0x01e00000 0x20000>;
-                       interrupts = <47>;
-                       clocks = <&ahb_gates 46>, <&de_fe_clk>,
-                                <&dram_gates 25>;
-                       clock-names = "ahb", "mod",
-                                     "ram";
-                       resets = <&de_fe_clk>;
-                       status = "disabled";
-
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               fe0_out: port@1 {
-                                       #address-cells = <1>;
-                                       #size-cells = <0>;
-                                       reg = <1>;
-
-                                       fe0_out_be0: endpoint@0 {
-                                               reg = <0>;
-                                               remote-endpoint = <&be0_in_fe0>;
-                                       };
-                               };
-                       };
-               };
-
-               be0: display-backend@01e60000 {
-                       compatible = "allwinner,sun5i-a13-display-backend";
-                       reg = <0x01e60000 0x10000>;
-                       clocks = <&ahb_gates 44>, <&de_be_clk>,
-                                <&dram_gates 26>;
-                       clock-names = "ahb", "mod",
-                                     "ram";
-                       resets = <&de_be_clk>;
-                       status = "disabled";
-
-                       assigned-clocks = <&de_be_clk>;
-                       assigned-clock-rates = <300000000>;
-
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               be0_in: port@0 {
-                                       #address-cells = <1>;
-                                       #size-cells = <0>;
-                                       reg = <0>;
-
-                                       be0_in_fe0: endpoint@0 {
-                                               reg = <0>;
-                                               remote-endpoint = <&fe0_out_be0>;
-                                       };
-                               };
-
-                               be0_out: port@1 {
-                                       #address-cells = <1>;
-                                       #size-cells = <0>;
-                                       reg = <1>;
-
-                                       be0_out_tcon0: endpoint@0 {
-                                               reg = <0>;
-                                               remote-endpoint = <&tcon0_in_be0>;
-                                       };
-                               };
-                       };
-               };
-       };
-};
index 1cf644bfd7ea13afd59f404b4825fefc9b67b2f5..51dc734cd5b902663df96e15dfeba4820966ce05 100644 (file)
        gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
 };
 
+&sata {
+       nr-ports = <2>;
+};
+
 &ehci1 {
        status = "okay";
 };
index 91096a49efa95af9e63082765d97eac2f81f1210..8f79b4147bba1b5f57155d1a738b7af851a1e901 100644 (file)
                        clock-frequency = <400000>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_i2c0_default>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
 
                        status = "disabled";
                };
                        clock-frequency = <400000>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_i2c1_default>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
 
                        status = "disabled";
                };
                        clock-frequency = <400000>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_i2c2_default>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
 
                        status = "disabled";
                };
                        clock-frequency = <400000>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_i2c3_default>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
 
                        status = "disabled";
                };
                        clock-frequency = <400000>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_i2c4_default>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
 
                        status = "disabled";
                };
                        clock-frequency = <400000>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_i2c5_default>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
 
                        status = "disabled";
                };
                        clock-frequency = <400000>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_i2c10_default>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
 
                        status = "disabled";
                };
                        clock-frequency = <400000>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_i2c11_default>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
 
                        status = "disabled";
                };
diff --git a/arch/arm/boot/dts/sun5i-gr8-evb.dts b/arch/arm/boot/dts/sun5i-gr8-evb.dts
new file mode 100644 (file)
index 0000000..714381f
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2016 Free Electrons
+ * Copyright 2016 NextThing Co
+ *
+ * Mylène Josserand <mylene.josserand@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun5i-gr8.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       model = "NextThing GR8-EVB";
+       compatible = "nextthing,gr8-evb", "nextthing,gr8";
+
+       aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               serial0 = &uart1;
+               serial1 = &uart2;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm 0 10000 0>;
+               enable-gpios = <&axp_gpio 1 GPIO_ACTIVE_HIGH>;
+
+               brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+               default-brightness-level = <8>;
+       };
+};
+
+&be0 {
+       status = "okay";
+};
+
+&codec {
+       status = "okay";
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins_a>;
+       status = "okay";
+
+       axp209: pmic@34 {
+               reg = <0x34>;
+
+               /*
+               * The interrupt is routed through the "External Fast
+               * Interrupt Request" pin (ball G13 of the module)
+               * directly to the main interrupt controller, without
+               * any other controller interfering.
+               */
+               interrupts = <0>;
+       };
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins_a>;
+       status = "okay";
+
+       wm8978: codec@1a {
+               #sound-dai-cells = <0>;
+               compatible = "wlf,wm8978";
+               reg = <0x1a>;
+       };
+
+       pcf8563: rtc@51 {
+               compatible = "phg,pcf8563";
+               reg = <0x51>;
+       };
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins_a>;
+       status = "okay";
+};
+
+&i2s0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2s0_mclk_pins_a>, <&i2s0_data_pins_a>;
+       status = "okay";
+};
+
+&ir0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&ir0_rx_pins_a>;
+       status = "okay";
+};
+
+&lradc {
+       vref-supply = <&reg_ldo2>;
+       status = "okay";
+
+       button@190 {
+               label = "Volume Up";
+               linux,code = <KEY_VOLUMEUP>;
+               channel = <0>;
+               voltage = <190000>;
+       };
+
+       button@390 {
+               label = "Volume Down";
+               linux,code = <KEY_VOLUMEDOWN>;
+               channel = <0>;
+               voltage = <390000>;
+       };
+
+       button@600 {
+               label = "Menu";
+               linux,code = <KEY_MENU>;
+               channel = <0>;
+               voltage = <600000>;
+       };
+
+       button@800 {
+               label = "Search";
+               linux,code = <KEY_SEARCH>;
+               channel = <0>;
+               voltage = <800000>;
+       };
+
+       button@980 {
+               label = "Home";
+               linux,code = <KEY_HOMEPAGE>;
+               channel = <0>;
+               voltage = <980000>;
+       };
+
+       button@1180 {
+               label = "Esc";
+               linux,code = <KEY_ESC>;
+               channel = <0>;
+               voltage = <1180000>;
+       };
+
+       button@1400 {
+               label = "Enter";
+               linux,code = <KEY_ENTER>;
+               channel = <0>;
+               voltage = <1400000>;
+       };
+};
+
+&mmc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_gr8_evb>;
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <4>;
+       cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
+       cd-inverted;
+       status = "okay";
+};
+
+&nfc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+
+       /* MLC Support sucks for now */
+       status = "disabled";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&otg_sram {
+       status = "okay";
+};
+
+&pio {
+       mmc0_cd_pin_gr8_evb: mmc0-cd-pin@0 {
+               allwinner,pins = "PG0";
+               allwinner,function = "gpio_in";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
+       usb0_id_pin_gr8_evb: usb0-id-pin@0 {
+               allwinner,pins = "PG2";
+               allwinner,function = "gpio_in";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
+       usb0_vbus_det_pin_gr8_evb: usb0-vbus-det-pin@0 {
+               allwinner,pins = "PG1";
+               allwinner,function = "gpio_in";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+
+       usb1_vbus_pin_gr8_evb: usb1-vbus-pin@0 {
+               allwinner,pins = "PG13";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+       };
+};
+
+&pwm {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm0_pins_a>;
+       status = "okay";
+};
+
+&reg_dcdc2 {
+       regulator-min-microvolt = <1000000>;
+       regulator-max-microvolt = <1400000>;
+       regulator-name = "vdd-cpu";
+       regulator-always-on;
+};
+
+&reg_dcdc3 {
+       regulator-min-microvolt = <1000000>;
+       regulator-max-microvolt = <1300000>;
+       regulator-name = "vdd-sys";
+       regulator-always-on;
+};
+
+&reg_ldo1 {
+       regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+       regulator-min-microvolt = <2700000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "avcc";
+       regulator-always-on;
+};
+
+&reg_usb1_vbus {
+       pinctrl-0 = <&usb1_vbus_pin_gr8_evb>;
+       gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&rtp {
+       allwinner,ts-attached;
+};
+
+&spdif {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spdif_tx_pins_a>;
+       status = "okay";
+};
+
+&tve0 {
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins_a>, <&uart1_cts_rts_pins_a>;
+       status = "okay";
+};
+
+&usb_otg {
+       /*
+        * The GR8-EVB has a somewhat interesting design. There's a
+        * pin supposed to control VBUS, an ID pin, a VBUS detect pin,
+        * so everything should work just fine.
+        *
+        * Except that the pin supposed to control VBUS is not
+        * connected to any controllable output, neither to the SoC
+        * through a GPIO or to the PMIC, and it is pulled down,
+        * meaning that we will never be able to enable VBUS on this
+        * board.
+        */
+       dr_mode = "otg";
+       status = "okay";
+};
+
+&usb_power_supply {
+       status = "okay";
+};
+
+&usbphy {
+       pinctrl-names = "default";
+       pinctrl-0 = <&usb0_id_pin_gr8_evb>, <&usb0_vbus_det_pin_gr8_evb>;
+       usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+       usb0_vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+       usb0_vbus_power-supply = <&usb_power_supply>;
+       usb1_vbus-supply = <&reg_usb1_vbus>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun5i-gr8.dtsi b/arch/arm/boot/dts/sun5i-gr8.dtsi
new file mode 100644 (file)
index 0000000..ca54e03
--- /dev/null
@@ -0,0 +1,1087 @@
+/*
+ * Copyright 2016 Mylène Josserand
+ *
+ * Mylène Josserand <mylene.josserand@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/clock/sun4i-a10-pll2.h>
+#include <dt-bindings/dma/sun4i-a10.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+       interrupt-parent = <&intc>;
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a8";
+                       reg = <0x0>;
+                       clocks = <&cpu>;
+               };
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               /*
+                * This is a dummy clock, to be used as placeholder on
+                * other mux clocks when a specific parent clock is not
+                * yet implemented. It should be dropped when the driver
+                * is complete.
+                */
+               dummy: dummy {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <0>;
+               };
+
+               osc24M: clk@01c20050 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-osc-clk";
+                       reg = <0x01c20050 0x4>;
+                       clock-frequency = <24000000>;
+                       clock-output-names = "osc24M";
+               };
+
+               osc3M: osc3M-clk {
+                       compatible = "fixed-factor-clock";
+                       #clock-cells = <0>;
+                       clock-div = <8>;
+                       clock-mult = <1>;
+                       clocks = <&osc24M>;
+                       clock-output-names = "osc3M";
+               };
+
+               osc32k: clk@0 {
+                       #clock-cells = <0>;
+                       compatible = "fixed-clock";
+                       clock-frequency = <32768>;
+                       clock-output-names = "osc32k";
+               };
+
+               pll1: clk@01c20000 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-pll1-clk";
+                       reg = <0x01c20000 0x4>;
+                       clocks = <&osc24M>;
+                       clock-output-names = "pll1";
+               };
+
+               pll2: clk@01c20008 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun5i-a13-pll2-clk";
+                       reg = <0x01c20008 0x8>;
+                       clocks = <&osc24M>;
+                       clock-output-names = "pll2-1x", "pll2-2x",
+                                            "pll2-4x", "pll2-8x";
+               };
+
+               pll3: clk@01c20010 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-pll3-clk";
+                       reg = <0x01c20010 0x4>;
+                       clocks = <&osc3M>;
+                       clock-output-names = "pll3";
+               };
+
+               pll3x2: pll3x2-clk {
+                       compatible = "allwinner,sun4i-a10-pll3-2x-clk";
+                       #clock-cells = <0>;
+                       clock-div = <1>;
+                       clock-mult = <2>;
+                       clocks = <&pll3>;
+                       clock-output-names = "pll3-2x";
+               };
+
+               pll4: clk@01c20018 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-pll1-clk";
+                       reg = <0x01c20018 0x4>;
+                       clocks = <&osc24M>;
+                       clock-output-names = "pll4";
+               };
+
+               pll5: clk@01c20020 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-pll5-clk";
+                       reg = <0x01c20020 0x4>;
+                       clocks = <&osc24M>;
+                       clock-output-names = "pll5_ddr", "pll5_other";
+               };
+
+               pll6: clk@01c20028 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-pll6-clk";
+                       reg = <0x01c20028 0x4>;
+                       clocks = <&osc24M>;
+                       clock-output-names = "pll6_sata", "pll6_other", "pll6";
+               };
+
+               pll7: clk@01c20030 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-pll3-clk";
+                       reg = <0x01c20030 0x4>;
+                       clocks = <&osc3M>;
+                       clock-output-names = "pll7";
+               };
+
+               pll7x2: pll7x2-clk {
+                       compatible = "allwinner,sun4i-a10-pll3-2x-clk";
+                       #clock-cells = <0>;
+                       clock-div = <1>;
+                       clock-mult = <2>;
+                       clocks = <&pll7>;
+                       clock-output-names = "pll7-2x";
+               };
+
+               /* dummy is 200M */
+               cpu: cpu@01c20054 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-cpu-clk";
+                       reg = <0x01c20054 0x4>;
+                       clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
+                       clock-output-names = "cpu";
+               };
+
+               axi: axi@01c20054 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-axi-clk";
+                       reg = <0x01c20054 0x4>;
+                       clocks = <&cpu>;
+                       clock-output-names = "axi";
+               };
+
+               ahb: ahb@01c20054 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun5i-a13-ahb-clk";
+                       reg = <0x01c20054 0x4>;
+                       clocks = <&axi>, <&cpu>, <&pll6 1>;
+                       clock-output-names = "ahb";
+                       /*
+                        * Use PLL6 as parent, instead of CPU/AXI
+                        * which has rate changes due to cpufreq
+                        */
+                       assigned-clocks = <&ahb>;
+                       assigned-clock-parents = <&pll6 1>;
+               };
+
+               apb0: apb0@01c20054 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-apb0-clk";
+                       reg = <0x01c20054 0x4>;
+                       clocks = <&ahb>;
+                       clock-output-names = "apb0";
+               };
+
+               apb1: clk@01c20058 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-apb1-clk";
+                       reg = <0x01c20058 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+                       clock-output-names = "apb1";
+               };
+
+               axi_gates: clk@01c2005c {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-gates-clk";
+                       reg = <0x01c2005c 0x4>;
+                       clocks = <&axi>;
+                       clock-indices = <0>;
+                       clock-output-names = "axi_dram";
+               };
+
+               ahb_gates: clk@01c20060 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun5i-a13-ahb-gates-clk";
+                       reg = <0x01c20060 0x8>;
+                       clocks = <&ahb>;
+                       clock-indices = <0>, <1>,
+                                       <2>, <5>, <6>,
+                                       <7>, <8>, <9>,
+                                       <10>, <13>,
+                                       <14>, <17>, <20>,
+                                       <21>, <22>,
+                                       <28>, <32>, <34>,
+                                       <36>, <40>, <44>,
+                                       <46>, <51>,
+                                       <52>;
+                       clock-output-names = "ahb_usbotg", "ahb_ehci",
+                                            "ahb_ohci", "ahb_ss", "ahb_dma",
+                                            "ahb_bist", "ahb_mmc0", "ahb_mmc1",
+                                            "ahb_mmc2", "ahb_nand",
+                                            "ahb_sdram", "ahb_emac", "ahb_spi0",
+                                            "ahb_spi1", "ahb_spi2",
+                                            "ahb_hstimer", "ahb_ve", "ahb_tve",
+                                            "ahb_lcd", "ahb_csi", "ahb_de_be",
+                                            "ahb_de_fe", "ahb_iep",
+                                            "ahb_mali400";
+               };
+
+               apb0_gates: clk@01c20068 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-gates-clk";
+                       reg = <0x01c20068 0x4>;
+                       clocks = <&apb0>;
+                       clock-indices = <0>, <3>,
+                                       <5>, <6>;
+                       clock-output-names = "apb0_codec", "apb0_i2s0",
+                                            "apb0_pio", "apb0_ir";
+               };
+
+               apb1_gates: clk@01c2006c {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-gates-clk";
+                       reg = <0x01c2006c 0x4>;
+                       clocks = <&apb1>;
+                       clock-indices = <0>, <1>,
+                                       <2>, <17>,
+                                       <18>, <19>;
+                       clock-output-names = "apb1_i2c0", "apb1_i2c1",
+                                            "apb1_i2c2", "apb1_uart1",
+                                            "apb1_uart2", "apb1_uart3";
+               };
+
+               nand_clk: clk@01c20080 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       reg = <0x01c20080 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "nand";
+               };
+
+               ms_clk: clk@01c20084 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       reg = <0x01c20084 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "ms";
+               };
+
+               mmc0_clk: clk@01c20088 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
+                       reg = <0x01c20088 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "mmc0",
+                                            "mmc0_output",
+                                            "mmc0_sample";
+               };
+
+               mmc1_clk: clk@01c2008c {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
+                       reg = <0x01c2008c 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "mmc1",
+                                            "mmc1_output",
+                                            "mmc1_sample";
+               };
+
+               mmc2_clk: clk@01c20090 {
+                       #clock-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-mmc-clk";
+                       reg = <0x01c20090 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "mmc2",
+                                            "mmc2_output",
+                                            "mmc2_sample";
+               };
+
+               ts_clk: clk@01c20098 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       reg = <0x01c20098 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "ts";
+               };
+
+               ss_clk: clk@01c2009c {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       reg = <0x01c2009c 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "ss";
+               };
+
+               spi0_clk: clk@01c200a0 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       reg = <0x01c200a0 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "spi0";
+               };
+
+               spi1_clk: clk@01c200a4 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       reg = <0x01c200a4 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "spi1";
+               };
+
+               spi2_clk: clk@01c200a8 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       reg = <0x01c200a8 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "spi2";
+               };
+
+               ir0_clk: clk@01c200b0 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod0-clk";
+                       reg = <0x01c200b0 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "ir0";
+               };
+
+               i2s0_clk: clk@01c200b8 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod1-clk";
+                       reg = <0x01c200b8 0x4>;
+                       clocks = <&pll2 SUN4I_A10_PLL2_8X>,
+                                <&pll2 SUN4I_A10_PLL2_4X>,
+                                <&pll2 SUN4I_A10_PLL2_2X>,
+                                <&pll2 SUN4I_A10_PLL2_1X>;
+                       clock-output-names = "i2s0";
+               };
+
+               spdif_clk: clk@01c200c0 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-mod1-clk";
+                       reg = <0x01c200c0 0x4>;
+                       clocks = <&pll2 SUN4I_A10_PLL2_8X>,
+                                <&pll2 SUN4I_A10_PLL2_4X>,
+                                <&pll2 SUN4I_A10_PLL2_2X>,
+                                <&pll2 SUN4I_A10_PLL2_1X>;
+                       clock-output-names = "spdif";
+               };
+
+               usb_clk: clk@01c200cc {
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       compatible = "allwinner,sun5i-a13-usb-clk";
+                       reg = <0x01c200cc 0x4>;
+                       clocks = <&pll6 1>;
+                       clock-output-names = "usb_ohci0", "usb_phy";
+               };
+
+               dram_gates: clk@01c20100 {
+                       #clock-cells = <1>;
+                       compatible = "nextthing,gr8-dram-gates-clk",
+                                    "allwinner,sun4i-a10-gates-clk";
+                       reg = <0x01c20100 0x4>;
+                       clocks = <&pll5 0>;
+                       clock-indices = <0>,
+                                       <1>,
+                                       <25>,
+                                       <26>,
+                                       <29>,
+                                       <31>;
+                       clock-output-names = "dram_ve",
+                                            "dram_csi",
+                                            "dram_de_fe",
+                                            "dram_de_be",
+                                            "dram_ace",
+                                            "dram_iep";
+               };
+
+               de_be_clk: clk@01c20104 {
+                       #clock-cells = <0>;
+                       #reset-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-display-clk";
+                       reg = <0x01c20104 0x4>;
+                       clocks = <&pll3>, <&pll7>, <&pll5 1>;
+                       clock-output-names = "de-be";
+               };
+
+               de_fe_clk: clk@01c2010c {
+                       #clock-cells = <0>;
+                       #reset-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-display-clk";
+                       reg = <0x01c2010c 0x4>;
+                       clocks = <&pll3>, <&pll7>, <&pll5 1>;
+                       clock-output-names = "de-fe";
+               };
+
+               tcon_ch0_clk: clk@01c20118 {
+                       #clock-cells = <0>;
+                       #reset-cells = <1>;
+                       compatible = "allwinner,sun4i-a10-tcon-ch0-clk";
+                       reg = <0x01c20118 0x4>;
+                       clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
+                       clock-output-names = "tcon-ch0-sclk";
+               };
+
+               tcon_ch1_clk: clk@01c2012c {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-tcon-ch1-clk";
+                       reg = <0x01c2012c 0x4>;
+                       clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
+                       clock-output-names = "tcon-ch1-sclk";
+               };
+
+               codec_clk: clk@01c20140 {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-codec-clk";
+                       reg = <0x01c20140 0x4>;
+                       clocks = <&pll2 SUN4I_A10_PLL2_1X>;
+                       clock-output-names = "codec";
+               };
+
+               mbus_clk: clk@01c2015c {
+                       #clock-cells = <0>;
+                       compatible = "allwinner,sun5i-a13-mbus-clk";
+                       reg = <0x01c2015c 0x4>;
+                       clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+                       clock-output-names = "mbus";
+               };
+       };
+
+       display-engine {
+               compatible = "allwinner,sun5i-a13-display-engine";
+               allwinner,pipelines = <&fe0>;
+       };
+
+       soc@01c00000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               sram-controller@01c00000 {
+                       compatible = "allwinner,sun4i-a10-sram-controller";
+                       reg = <0x01c00000 0x30>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       sram_a: sram@00000000 {
+                               compatible = "mmio-sram";
+                               reg = <0x00000000 0xc000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x00000000 0xc000>;
+                       };
+
+                       sram_d: sram@00010000 {
+                               compatible = "mmio-sram";
+                               reg = <0x00010000 0x1000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x00010000 0x1000>;
+
+                               otg_sram: sram-section@0000 {
+                                       compatible = "allwinner,sun4i-a10-sram-d";
+                                       reg = <0x0000 0x1000>;
+                                       status = "disabled";
+                               };
+                       };
+               };
+
+               dma: dma-controller@01c02000 {
+                       compatible = "allwinner,sun4i-a10-dma";
+                       reg = <0x01c02000 0x1000>;
+                       interrupts = <27>;
+                       clocks = <&ahb_gates 6>;
+                       #dma-cells = <2>;
+               };
+
+               nfc: nand@01c03000 {
+                       compatible = "allwinner,sun4i-a10-nand";
+                       reg = <0x01c03000 0x1000>;
+                       interrupts = <37>;
+                       clocks = <&ahb_gates 13>, <&nand_clk>;
+                       clock-names = "ahb", "mod";
+                       dmas = <&dma SUN4I_DMA_DEDICATED 3>;
+                       dma-names = "rxtx";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               spi0: spi@01c05000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c05000 0x1000>;
+                       interrupts = <10>;
+                       clocks = <&ahb_gates 20>, <&spi0_clk>;
+                       clock-names = "ahb", "mod";
+                       dmas = <&dma SUN4I_DMA_DEDICATED 27>,
+                              <&dma SUN4I_DMA_DEDICATED 26>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               spi1: spi@01c06000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c06000 0x1000>;
+                       interrupts = <11>;
+                       clocks = <&ahb_gates 21>, <&spi1_clk>;
+                       clock-names = "ahb", "mod";
+                       dmas = <&dma SUN4I_DMA_DEDICATED 9>,
+                              <&dma SUN4I_DMA_DEDICATED 8>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               tve0: tv-encoder@01c0a000 {
+                       compatible = "allwinner,sun4i-a10-tv-encoder";
+                       reg = <0x01c0a000 0x1000>;
+                       clocks = <&ahb_gates 34>;
+                       resets = <&tcon_ch0_clk 0>;
+                       status = "disabled";
+
+                       port {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               tve0_in_tcon0: endpoint@0 {
+                                       reg = <0>;
+                                       remote-endpoint = <&tcon0_out_tve0>;
+                               };
+                       };
+               };
+
+               tcon0: lcd-controller@01c0c000 {
+                       compatible = "allwinner,sun5i-a13-tcon";
+                       reg = <0x01c0c000 0x1000>;
+                       interrupts = <44>;
+                       resets = <&tcon_ch0_clk 1>;
+                       reset-names = "lcd";
+                       clocks = <&ahb_gates 36>,
+                                <&tcon_ch0_clk>,
+                                <&tcon_ch1_clk>;
+                       clock-names = "ahb",
+                                     "tcon-ch0",
+                                     "tcon-ch1";
+                       clock-output-names = "tcon-pixel-clock";
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               tcon0_in: port@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0>;
+
+                                       tcon0_in_be0: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&be0_out_tcon0>;
+                                       };
+                               };
+
+                               tcon0_out: port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <1>;
+
+                                       tcon0_out_tve0: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&tve0_in_tcon0>;
+                                       };
+                               };
+                       };
+               };
+
+               mmc0: mmc@01c0f000 {
+                       compatible = "allwinner,sun5i-a13-mmc";
+                       reg = <0x01c0f000 0x1000>;
+                       clocks = <&ahb_gates 8>,
+                                <&mmc0_clk 0>,
+                                <&mmc0_clk 1>,
+                                <&mmc0_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
+                       interrupts = <32>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               mmc1: mmc@01c10000 {
+                       compatible = "allwinner,sun5i-a13-mmc";
+                       reg = <0x01c10000 0x1000>;
+                       clocks = <&ahb_gates 9>,
+                                <&mmc1_clk 0>,
+                                <&mmc1_clk 1>,
+                                <&mmc1_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
+                       interrupts = <33>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               mmc2: mmc@01c11000 {
+                       compatible = "allwinner,sun5i-a13-mmc";
+                       reg = <0x01c11000 0x1000>;
+                       clocks = <&ahb_gates 10>,
+                                <&mmc2_clk 0>,
+                                <&mmc2_clk 1>,
+                                <&mmc2_clk 2>;
+                       clock-names = "ahb",
+                                     "mmc",
+                                     "output",
+                                     "sample";
+                       interrupts = <34>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               usb_otg: usb@01c13000 {
+                       compatible = "allwinner,sun4i-a10-musb";
+                       reg = <0x01c13000 0x0400>;
+                       clocks = <&ahb_gates 0>;
+                       interrupts = <38>;
+                       interrupt-names = "mc";
+                       phys = <&usbphy 0>;
+                       phy-names = "usb";
+                       extcon = <&usbphy 0>;
+                       allwinner,sram = <&otg_sram 1>;
+                       status = "disabled";
+
+                       dr_mode = "otg";
+               };
+
+               usbphy: phy@01c13400 {
+                       #phy-cells = <1>;
+                       compatible = "allwinner,sun5i-a13-usb-phy";
+                       reg = <0x01c13400 0x10 0x01c14800 0x4>;
+                       reg-names = "phy_ctrl", "pmu1";
+                       clocks = <&usb_clk 8>;
+                       clock-names = "usb_phy";
+                       resets = <&usb_clk 0>, <&usb_clk 1>;
+                       reset-names = "usb0_reset", "usb1_reset";
+                       status = "disabled";
+               };
+
+               ehci0: usb@01c14000 {
+                       compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
+                       reg = <0x01c14000 0x100>;
+                       interrupts = <39>;
+                       clocks = <&ahb_gates 1>;
+                       phys = <&usbphy 1>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               ohci0: usb@01c14400 {
+                       compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
+                       reg = <0x01c14400 0x100>;
+                       interrupts = <40>;
+                       clocks = <&usb_clk 6>, <&ahb_gates 2>;
+                       phys = <&usbphy 1>;
+                       phy-names = "usb";
+                       status = "disabled";
+               };
+
+               spi2: spi@01c17000 {
+                       compatible = "allwinner,sun4i-a10-spi";
+                       reg = <0x01c17000 0x1000>;
+                       interrupts = <12>;
+                       clocks = <&ahb_gates 22>, <&spi2_clk>;
+                       clock-names = "ahb", "mod";
+                       dmas = <&dma SUN4I_DMA_DEDICATED 29>,
+                              <&dma SUN4I_DMA_DEDICATED 28>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               intc: interrupt-controller@01c20400 {
+                       compatible = "allwinner,sun4i-a10-ic";
+                       reg = <0x01c20400 0x400>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
+
+               pio: pinctrl@01c20800 {
+                       compatible = "nextthing,gr8-pinctrl";
+                       reg = <0x01c20800 0x400>;
+                       interrupts = <28>;
+                       clocks = <&apb0_gates 5>;
+                       gpio-controller;
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       #gpio-cells = <3>;
+
+                       i2c0_pins_a: i2c0@0 {
+                               allwinner,pins = "PB0", "PB1";
+                               allwinner,function = "i2c0";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       i2c1_pins_a: i2c1@0 {
+                               allwinner,pins = "PB15", "PB16";
+                               allwinner,function = "i2c1";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       i2c2_pins_a: i2c2@0 {
+                               allwinner,pins = "PB17", "PB18";
+                               allwinner,function = "i2c2";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       i2s0_data_pins_a: i2s0-data@0 {
+                               allwinner,pins = "PB6", "PB7", "PB8", "PB9";
+                               allwinner,function = "i2s0";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       i2s0_mclk_pins_a: i2s0-mclk@0 {
+                               allwinner,pins = "PB6", "PB7", "PB8", "PB9";
+                               allwinner,function = "i2s0";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       ir0_rx_pins_a: ir0@0 {
+                               allwinner,pins = "PB4";
+                               allwinner,function = "ir0";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       lcd_rgb666_pins: lcd-rgb666@0 {
+                               allwinner,pins = "PD2", "PD3", "PD4", "PD5", "PD6", "PD7",
+                                                "PD10", "PD11", "PD12", "PD13", "PD14", "PD15",
+                                                "PD18", "PD19", "PD20", "PD21", "PD22", "PD23",
+                                                "PD24", "PD25", "PD26", "PD27";
+                               allwinner,function = "lcd0";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       mmc0_pins_a: mmc0@0 {
+                               allwinner,pins = "PF0", "PF1", "PF2", "PF3",
+                                                "PF4", "PF5";
+                               allwinner,function = "mmc0";
+                               allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       nand_pins_a: nand-base0@0 {
+                               allwinner,pins = "PC0", "PC1", "PC2",
+                                               "PC5", "PC8", "PC9", "PC10",
+                                               "PC11", "PC12", "PC13", "PC14",
+                                               "PC15";
+                               allwinner,function = "nand0";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       nand_cs0_pins_a: nand-cs@0 {
+                               allwinner,pins = "PC4";
+                               allwinner,function = "nand0";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       nand_rb0_pins_a: nand-rb@0 {
+                               allwinner,pins = "PC6";
+                               allwinner,function = "nand0";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       pwm0_pins_a: pwm0@0 {
+                               allwinner,pins = "PB2";
+                               allwinner,function = "pwm0";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       spdif_tx_pins_a: spdif@0 {
+                               allwinner,pins = "PB10";
+                               allwinner,function = "spdif";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+                       };
+
+                       uart1_pins_a: uart1@1 {
+                               allwinner,pins = "PG3", "PG4";
+                               allwinner,function = "uart1";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+
+                       uart1_cts_rts_pins_a: uart1-cts-rts@0 {
+                               allwinner,pins = "PG5", "PG6";
+                               allwinner,function = "uart1";
+                               allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+                               allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                       };
+               };
+
+               pwm: pwm@01c20e00 {
+                       compatible = "allwinner,sun5i-a10s-pwm";
+                       reg = <0x01c20e00 0xc>;
+                       clocks = <&osc24M>;
+                       #pwm-cells = <3>;
+                       status = "disabled";
+               };
+
+               timer@01c20c00 {
+                       compatible = "allwinner,sun4i-a10-timer";
+                       reg = <0x01c20c00 0x90>;
+                       interrupts = <22>;
+                       clocks = <&osc24M>;
+               };
+
+               wdt: watchdog@01c20c90 {
+                       compatible = "allwinner,sun4i-a10-wdt";
+                       reg = <0x01c20c90 0x10>;
+               };
+
+               spdif: spdif@01c21000 {
+                       #sound-dai-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-spdif";
+                       reg = <0x01c21000 0x400>;
+                       interrupts = <13>;
+                       clocks = <&apb0_gates 1>, <&spdif_clk>;
+                       clock-names = "apb", "spdif";
+                       dmas = <&dma SUN4I_DMA_NORMAL 2>,
+                              <&dma SUN4I_DMA_NORMAL 2>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+
+               ir0: ir@01c21800 {
+                       compatible = "allwinner,sun4i-a10-ir";
+                       clocks = <&apb0_gates 6>, <&ir0_clk>;
+                       clock-names = "apb", "ir";
+                       interrupts = <5>;
+                       reg = <0x01c21800 0x40>;
+                       status = "disabled";
+               };
+
+               i2s0: i2s@01c22400 {
+                       #sound-dai-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-i2s";
+                       reg = <0x01c22400 0x400>;
+                       interrupts = <16>;
+                       clocks = <&apb0_gates 3>, <&i2s0_clk>;
+                       clock-names = "apb", "mod";
+                       dmas = <&dma SUN4I_DMA_NORMAL 3>,
+                              <&dma SUN4I_DMA_NORMAL 3>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+
+               lradc: lradc@01c22800 {
+                       compatible = "allwinner,sun4i-a10-lradc-keys";
+                       reg = <0x01c22800 0x100>;
+                       interrupts = <31>;
+                       status = "disabled";
+               };
+
+               codec: codec@01c22c00 {
+                       #sound-dai-cells = <0>;
+                       compatible = "allwinner,sun4i-a10-codec";
+                       reg = <0x01c22c00 0x40>;
+                       interrupts = <30>;
+                       clocks = <&apb0_gates 0>, <&codec_clk>;
+                       clock-names = "apb", "codec";
+                       dmas = <&dma SUN4I_DMA_NORMAL 19>,
+                              <&dma SUN4I_DMA_NORMAL 19>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+
+               rtp: rtp@01c25000 {
+                       compatible = "allwinner,sun5i-a13-ts";
+                       reg = <0x01c25000 0x100>;
+                       interrupts = <29>;
+                       #thermal-sensor-cells = <0>;
+               };
+
+               uart1: serial@01c28400 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x01c28400 0x400>;
+                       interrupts = <2>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&apb1_gates 17>;
+                       status = "disabled";
+               };
+
+               uart2: serial@01c28800 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x01c28800 0x400>;
+                       interrupts = <3>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&apb1_gates 18>;
+                       status = "disabled";
+               };
+
+               i2c0: i2c@01c2ac00 {
+                       compatible = "allwinner,sun4i-a10-i2c";
+                       reg = <0x01c2ac00 0x400>;
+                       interrupts = <7>;
+                       clocks = <&apb1_gates 0>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               i2c1: i2c@01c2b000 {
+                       compatible = "allwinner,sun4i-a10-i2c";
+                       reg = <0x01c2b000 0x400>;
+                       interrupts = <8>;
+                       clocks = <&apb1_gates 1>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               i2c2: i2c@01c2b400 {
+                       compatible = "allwinner,sun4i-a10-i2c";
+                       reg = <0x01c2b400 0x400>;
+                       interrupts = <9>;
+                       clocks = <&apb1_gates 2>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               timer@01c60000 {
+                       compatible = "allwinner,sun5i-a13-hstimer";
+                       reg = <0x01c60000 0x1000>;
+                       interrupts = <82>, <83>;
+                       clocks = <&ahb_gates 28>;
+               };
+
+               fe0: display-frontend@01e00000 {
+                       compatible = "allwinner,sun5i-a13-display-frontend";
+                       reg = <0x01e00000 0x20000>;
+                       interrupts = <47>;
+                       clocks = <&ahb_gates 46>, <&de_fe_clk>,
+                                <&dram_gates 25>;
+                       clock-names = "ahb", "mod",
+                                     "ram";
+                       resets = <&de_fe_clk>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               fe0_out: port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <1>;
+
+                                       fe0_out_be0: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&be0_in_fe0>;
+                                       };
+                               };
+                       };
+               };
+
+               be0: display-backend@01e60000 {
+                       compatible = "allwinner,sun5i-a13-display-backend";
+                       reg = <0x01e60000 0x10000>;
+                       clocks = <&ahb_gates 44>, <&de_be_clk>,
+                                <&dram_gates 26>;
+                       clock-names = "ahb", "mod",
+                                     "ram";
+                       resets = <&de_be_clk>;
+                       status = "disabled";
+
+                       assigned-clocks = <&de_be_clk>;
+                       assigned-clock-rates = <300000000>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               be0_in: port@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0>;
+
+                                       be0_in_fe0: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&fe0_out_be0>;
+                                       };
+                               };
+
+                               be0_out: port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <1>;
+
+                                       be0_out_tcon0: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&tcon0_in_be0>;
+                                       };
+                               };
+                       };
+               };
+       };
+};
index 75a865406d3ef54c1579b4f558560aaf90567d1c..f4ba088b225edee8d26dcfdf5ab4f8469ea9628d 100644 (file)
                        };
 
                        uart3_pins: uart3 {
-                               allwinner,pins = "PG13", "PG14";
+                               allwinner,pins = "PA13", "PA14";
                                allwinner,function = "uart3";
                                allwinner,drive = <SUN4I_PINCTRL_10_MA>;
                                allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
index b54db47f6f322d358f7742ecc7e17b23e0c2b667..1dc2a34b9dbd452531479d0766187c8547cb13fd 100644 (file)
@@ -380,13 +380,6 @@ static struct pu_domain imx6q_pu_domain = {
                .name = "PU",
                .power_off = imx6q_pm_pu_power_off,
                .power_on = imx6q_pm_pu_power_on,
-               .states = {
-                       [0] = {
-                               .power_off_latency_ns = 25000,
-                               .power_on_latency_ns = 2000000,
-                       },
-               },
-               .state_count = 1,
        },
 };
 
@@ -430,6 +423,16 @@ static int imx_gpc_genpd_init(struct device *dev, struct regulator *pu_reg)
        if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS))
                return 0;
 
+       imx6q_pu_domain.base.states = devm_kzalloc(dev,
+                                       sizeof(*imx6q_pu_domain.base.states),
+                                       GFP_KERNEL);
+       if (!imx6q_pu_domain.base.states)
+               return -ENOMEM;
+
+       imx6q_pu_domain.base.states[0].power_off_latency_ns = 25000;
+       imx6q_pu_domain.base.states[0].power_on_latency_ns = 2000000;
+       imx6q_pu_domain.base.state_count = 1;
+
        for (i = 0; i < ARRAY_SIZE(imx_gpc_domains); i++)
                pm_genpd_init(imx_gpc_domains[i], NULL, false);
 
index 334271a25f70b329d5aed75205ff46c02baabf62..7d3a2acc6a553471d66a2bd71ce53e8c36e10aeb 100644 (file)
                #address-cells = <3>;
                #size-cells = <2>;
                dma-coherent;
-               ranges = <0x01000000 0x00 0x5f800000 0x00 0x5f800000 0x0 0x00800000>,
+               ranges = <0x01000000 0x00 0x00000000 0x00 0x5f800000 0x0 0x00800000>,
                         <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>,
                         <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>;
                #interrupt-cells = <1>;
index 123a58b29cbdc13687f196339cc3d60c96512e8f..f0b857d6d73cc9595504b266f9cf197d9b1be5be 100644 (file)
@@ -76,7 +76,7 @@
                                compatible = "arm,idle-state";
                                arm,psci-suspend-param = <0x1010000>;
                                local-timer-stop;
-                               entry-latency-us = <300>;
+                               entry-latency-us = <400>;
                                exit-latency-us = <1200>;
                                min-residency-us = <2500>;
                        };
index 007be826efcea9ef8c49a359c8d5a79ec7c738e9..26aaa6a7670f10b3f8cba5ea91bc214c4ba7241b 100644 (file)
@@ -76,7 +76,7 @@
                                compatible = "arm,idle-state";
                                arm,psci-suspend-param = <0x1010000>;
                                local-timer-stop;
-                               entry-latency-us = <300>;
+                               entry-latency-us = <400>;
                                exit-latency-us = <1200>;
                                min-residency-us = <2500>;
                        };
index a7270eff6939bc677a16cc90646d5ab4d48b4fa4..6e154d948a80b9fa4e79739fff85ed6fb65dc092 100644 (file)
@@ -76,7 +76,7 @@
                                compatible = "arm,idle-state";
                                arm,psci-suspend-param = <0x1010000>;
                                local-timer-stop;
-                               entry-latency-us = <300>;
+                               entry-latency-us = <400>;
                                exit-latency-us = <1200>;
                                min-residency-us = <2500>;
                        };
index 55be7e3ff109056e7837d9014b74e673e9012b57..b98acd15ca22d59fce754a93ee44c4d5619804f8 100644 (file)
@@ -95,9 +95,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -105,8 +106,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -366,6 +369,7 @@ CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_A2065=y
 CONFIG_ARIADNE=y
 # CONFIG_NET_VENDOR_ARC is not set
index 365dda66b0e669a4fa59e85bb4ec4e1f924b3f04..f80dc57e6374d3cf5e001eb29ca1ed8adb3b71d0 100644 (file)
@@ -93,9 +93,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -103,8 +104,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -347,6 +350,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
index ce3cbfd16fcd91b171abc8c13ededc8cc0e8ffb9..4e16b1821fbbf0d89c91b3d0fd16b419aef29307 100644 (file)
@@ -93,9 +93,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -103,8 +104,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -356,6 +359,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_ATARILANCE=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
index 8db496a9797d2dd17eee9c6dcbd0afc810afb1be..2767bbf5ad61c18afc264590155baa789f3b427e 100644 (file)
@@ -91,9 +91,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -101,8 +102,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -346,6 +349,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
index 8314156f71490d2b554ee0909d94fdd848769a87..d13ba309265e5d979d607ba02bbbdcf7bf0d7d71 100644 (file)
@@ -93,9 +93,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -103,8 +104,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -347,6 +350,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_HPLANCE=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
index 6600270b9622a2bad488f363ff66127750a42fa0..78b5101c1aa63476ffe8294927385328f411af01 100644 (file)
@@ -92,9 +92,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -102,8 +103,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -363,6 +366,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_MACMACE=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
index 90abfe9eabba159f49e863b3e594b1088a845a09..38e5bcbd0d62eaf42c7f0d6055446efbe45fa13f 100644 (file)
@@ -102,9 +102,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -112,8 +113,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -397,6 +400,7 @@ CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_A2065=y
 CONFIG_ARIADNE=y
 CONFIG_ATARILANCE=y
index 0d502c2f73d5c6be52476eb2106144798c32c148..28687192b68e4a74ba1d9b53f1732f7130b6be92 100644 (file)
@@ -90,9 +90,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -100,8 +101,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -345,6 +348,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_MVME147_NET=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
index 5930e91fc710cfa1a07111aedb5a93225e78362b..5a5f109ab3cdeb8ad992b2234f7e26a896039510 100644 (file)
@@ -91,9 +91,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -101,8 +102,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -346,6 +349,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
index 74e3ad82eca9e509daf9268d694c57fa6a568bb6..e557c9de3fbce9c8b9b2b809610f59769d00a540 100644 (file)
@@ -91,9 +91,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -101,8 +102,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -353,6 +356,7 @@ CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
 # CONFIG_NET_VENDOR_AMD is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
index 4ba8606a4e697c16e08174dff44f6485c8f46128..c6a748a36daf53798fcf8f3f9a61cbdca133fb46 100644 (file)
@@ -88,9 +88,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -98,8 +99,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -343,6 +346,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_SUN3LANCE=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
index c6f49726a6c911d82d5ead9dd8a07cd902753f50..10d60857b9a691703f3e4297963abeb05dcc40fa 100644 (file)
@@ -88,9 +88,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -98,8 +99,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -343,6 +346,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_SUN3LANCE=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
index d28fa8fe26fece499884fe1c7530ca0ad5dd9af4..c598d847d56b214a653dfa09924471206e44f123 100644 (file)
@@ -114,6 +114,6 @@ static inline void __udelay(unsigned long usecs)
  */
 #define        HZSCALE         (268435456 / (1000000 / HZ))
 
-#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000));
+#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000))
 
 #endif /* defined(_M68K_DELAY_H) */
index 8d0170969e22274efec90f328b626aec51ddb00a..a7f81261c781f0d935fbf70feffdeca3d898703a 100644 (file)
@@ -36,7 +36,7 @@ EXPORT_SYMBOL(rtc_lock);
 
 int __weak rtc_mips_set_time(unsigned long sec)
 {
-       return 0;
+       return -ENODEV;
 }
 
 int __weak rtc_mips_set_mmss(unsigned long nowtime)
index 2a1b3021589cf111aa26f57f0e8250534fd13f9a..82bbd0e2e298fa504f3f1995cf83aee8b7746569 100644 (file)
@@ -24,7 +24,7 @@
 
 /* GPE frequency selection */
 #define GPPC_OFFSET            24
-#define GPEFREQ_MASK           0x00000C0
+#define GPEFREQ_MASK           0x0000C00
 #define GPEFREQ_OFFSET         10
 /* Clock status register */
 #define SYSCTL_CLKS            0x0000
index c2c43f71468498828f924ebc54b9aa3f189ba95e..3a4ed9f91d5727a5293780967411328ae8cc6310 100644 (file)
@@ -65,9 +65,9 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
                unsigned long flags;                            \
                spin_lock_irqsave(&pa_tlb_lock, flags);         \
                old_pte = *ptep;                                \
-               set_pte(ptep, pteval);                          \
                if (pte_inserted(old_pte))                      \
                        purge_tlb_entries(mm, addr);            \
+               set_pte(ptep, pteval);                          \
                spin_unlock_irqrestore(&pa_tlb_lock, flags);    \
        } while (0)
 
@@ -478,8 +478,8 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned
                spin_unlock_irqrestore(&pa_tlb_lock, flags);
                return 0;
        }
-       set_pte(ptep, pte_mkold(pte));
        purge_tlb_entries(vma->vm_mm, addr);
+       set_pte(ptep, pte_mkold(pte));
        spin_unlock_irqrestore(&pa_tlb_lock, flags);
        return 1;
 }
@@ -492,9 +492,9 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
 
        spin_lock_irqsave(&pa_tlb_lock, flags);
        old_pte = *ptep;
-       set_pte(ptep, __pte(0));
        if (pte_inserted(old_pte))
                purge_tlb_entries(mm, addr);
+       set_pte(ptep, __pte(0));
        spin_unlock_irqrestore(&pa_tlb_lock, flags);
 
        return old_pte;
@@ -504,8 +504,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 {
        unsigned long flags;
        spin_lock_irqsave(&pa_tlb_lock, flags);
-       set_pte(ptep, pte_wrprotect(*ptep));
        purge_tlb_entries(mm, addr);
+       set_pte(ptep, pte_wrprotect(*ptep));
        spin_unlock_irqrestore(&pa_tlb_lock, flags);
 }
 
index c263301648f34a049abea878974324022b70b086..977f0a4f5ecf2cffec9f147d8999456ed839c01c 100644 (file)
@@ -393,6 +393,15 @@ void __init parisc_setup_cache_timing(void)
 
        /* calculate TLB flush threshold */
 
+       /* On SMP machines, skip the TLB measure of kernel text which
+        * has been mapped as huge pages. */
+       if (num_online_cpus() > 1 && !parisc_requires_coherency()) {
+               threshold = max(cache_info.it_size, cache_info.dt_size);
+               threshold *= PAGE_SIZE;
+               threshold /= num_online_cpus();
+               goto set_tlb_threshold;
+       }
+
        alltime = mfctl(16);
        flush_tlb_all();
        alltime = mfctl(16) - alltime;
@@ -411,6 +420,8 @@ void __init parisc_setup_cache_timing(void)
                alltime, size, rangetime);
 
        threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime);
+
+set_tlb_threshold:
        if (threshold)
                parisc_tlb_flush_threshold = threshold;
        printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
index 1b39a2acaadf43f16df3a54f3a797b029a3e06ff..adf7187f89515ec69b19461f60ce379e552397dc 100644 (file)
@@ -892,19 +892,10 @@ ENTRY_CFI(flush_dcache_page_asm)
        fdc,m           r31(%r28)
        fdc,m           r31(%r28)
        fdc,m           r31(%r28)
-       cmpb,COND(<<)           %r28, %r25,1b
+       cmpb,COND(<<)   %r28, %r25,1b
        fdc,m           r31(%r28)
 
        sync
-
-#ifdef CONFIG_PA20
-       pdtlb,l         %r0(%r25)
-#else
-       tlb_lock        %r20,%r21,%r22
-       pdtlb           %r0(%r25)
-       tlb_unlock      %r20,%r21,%r22
-#endif
-
        bv              %r0(%r2)
        nop
        .exit
@@ -979,17 +970,6 @@ ENTRY_CFI(flush_icache_page_asm)
        fic,m           %r31(%sr4,%r28)
 
        sync
-
-#ifdef CONFIG_PA20
-       pdtlb,l         %r0(%r28)
-       pitlb,l         %r0(%sr4,%r25)
-#else
-       tlb_lock        %r20,%r21,%r22
-       pdtlb           %r0(%r28)
-       pitlb           %r0(%sr4,%r25)
-       tlb_unlock      %r20,%r21,%r22
-#endif
-
        bv              %r0(%r2)
        nop
        .exit
index eae2dc8bc218165242f4406df9a6273755b60770..9d47f2efa830c220c68ffa11d29d6efaa3fa84cc 100644 (file)
@@ -100,7 +100,8 @@ src-wlib-y := string.S crt0.S crtsavres.S stdio.c decompress.c main.c \
                ns16550.c serial.c simple_alloc.c div64.S util.S \
                elf_util.c $(zlib-y) devtree.c stdlib.c \
                oflib.c ofconsole.c cuboot.c mpsc.c cpm-serial.c \
-               uartlite.c mpc52xx-psc.c opal.c opal-calls.S
+               uartlite.c mpc52xx-psc.c opal.c
+src-wlib-$(CONFIG_PPC64_BOOT_WRAPPER) +=  opal-calls.S
 src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c
 src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c
 src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c fsl-soc.c
index d7b4fd47eb44ff6b9bbef81da9f49f334efa8eef..0272570d02de15ba70363809c987ca7efd97dd99 100644 (file)
@@ -13,7 +13,7 @@
 #include <libfdt.h>
 #include "../include/asm/opal-api.h"
 
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64_BOOT_WRAPPER
 
 /* Global OPAL struct used by opal-call.S */
 struct opal {
index a62be72da274de3993a4b28cfbad7938d5502559..5c31369435f24200ae8c06bc69a8795b12ffd8e3 100644 (file)
@@ -671,8 +671,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus,
 
        /* Clear frozen state */
        rc = eeh_clear_pe_frozen_state(pe, false);
-       if (rc)
+       if (rc) {
+               pci_unlock_rescan_remove();
                return rc;
+       }
 
        /* Give the system 5 seconds to finish running the user-space
         * hotplug shutdown scripts, e.g. ifdown for ethernet.  Yes,
index 8295f51c1a5f9023022273d6e19b9e2a46ae4451..7394b770ae1f6b2402ef2b04fe23e92eae2c7ee2 100644 (file)
@@ -94,8 +94,17 @@ SECTIONS
         * detected, and will result in a crash at boot due to offsets being
         * wrong.
         */
+#ifdef CONFIG_PPC64
+       /*
+        * BLOCK(0) overrides the default output section alignment because
+        * this needs to start right after .head.text in order for fixed
+        * section placement to work.
+        */
+       .text BLOCK(0) : AT(ADDR(.text) - LOAD_OFFSET) {
+#else
        .text : AT(ADDR(.text) - LOAD_OFFSET) {
                ALIGN_FUNCTION();
+#endif
                /* careful! __ftr_alt_* sections need to be close to .text */
                *(.text .fixup __ftr_alt_* .ref.text)
                SCHED_TEXT
index 42c702b3be1ff795d36b2039ba0d0bcef01305c2..6fa450c12d6d1b28c71429ac4aa10fdd4dabf2a0 100644 (file)
@@ -55,7 +55,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
         */
        rflags = htab_convert_pte_flags(new_pte);
 
-       if (!cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+       if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
            !cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
                rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
 
index 3bbbea07378c60b56e545d74ebc6e17301f0644f..1a68cb19b0e33c0031a1568f9e977f1681b80cd8 100644 (file)
@@ -87,7 +87,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
        subpg_pte = new_pte & ~subpg_prot;
        rflags = htab_convert_pte_flags(subpg_pte);
 
-       if (!cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+       if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
            !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) {
 
                /*
@@ -258,7 +258,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access,
 
        rflags = htab_convert_pte_flags(new_pte);
 
-       if (!cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+       if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
            !cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
                rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
 
index 9d4bf3ab049ec19f8e8dd3c3f859dc310f92c466..6e395c9969002839fc0fd1e94f95fe0ba77abe0b 100644 (file)
@@ -69,7 +69,7 @@ u64 x86_perf_event_update(struct perf_event *event)
        int shift = 64 - x86_pmu.cntval_bits;
        u64 prev_raw_count, new_raw_count;
        int idx = hwc->idx;
-       s64 delta;
+       u64 delta;
 
        if (idx == INTEL_PMC_IDX_FIXED_BTS)
                return 0;
index a74a2dbc01801a1ccc3c041a6037214c369957bb..cb8522290e6a3f6dc3b5baacfc618d0ee8db65e3 100644 (file)
@@ -4034,7 +4034,7 @@ __init int intel_pmu_init(void)
 
        /* Support full width counters using alternative MSR range */
        if (x86_pmu.intel_cap.full_width_write) {
-               x86_pmu.max_period = x86_pmu.cntval_mask;
+               x86_pmu.max_period = x86_pmu.cntval_mask >> 1;
                x86_pmu.perfctr = MSR_IA32_PMC0;
                pr_cont("full-width counters, ");
        }
index 4f5ac726335f899a4faefd01a41aac241b9160be..da51e5a3e2ff799d54257aa3db5151b4723c8292 100644 (file)
@@ -540,6 +540,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = {
        X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_DESKTOP, snb_cstates),
 
        X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNL, knl_cstates),
+       X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNM, knl_cstates),
        { },
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match);
index 03d269bed9416925bc35682f1fbd37385ef558b5..24118c0b464090372fbd831a891890ecb8debd9b 100644 (file)
@@ -272,7 +272,6 @@ struct compat_shmid64_ds {
 /*
  * The type of struct elf_prstatus.pr_reg in compatible core dumps.
  */
-#ifdef CONFIG_X86_X32_ABI
 typedef struct user_regs_struct compat_elf_gregset_t;
 
 /* Full regset -- prstatus on x32, otherwise on ia32 */
@@ -281,10 +280,9 @@ typedef struct user_regs_struct compat_elf_gregset_t;
   do { *(int *) (((void *) &((S)->pr_reg)) + R) = (V); } \
   while (0)
 
+#ifdef CONFIG_X86_X32_ABI
 #define COMPAT_USE_64BIT_TIME \
        (!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
-#else
-typedef struct user_regs_struct32 compat_elf_gregset_t;
 #endif
 
 /*
index aeef53ce93e1ca999e77c2f174c6a06f17353362..35690a168cf7491d960b34c978a9125bba78c6a0 100644 (file)
@@ -815,9 +815,9 @@ static __init void map_mmioh_high_uv3(int index, int min_pnode, int max_pnode)
                                l = li;
                        }
                        addr1 = (base << shift) +
-                               f * (unsigned long)(1 << m_io);
+                               f * (1ULL << m_io);
                        addr2 = (base << shift) +
-                               (l + 1) * (unsigned long)(1 << m_io);
+                               (l + 1) * (1ULL << m_io);
                        pr_info("UV: %s[%03d..%03d] NASID 0x%04x ADDR 0x%016lx - 0x%016lx\n",
                                id, fi, li, lnasid, addr1, addr2);
                        if (max_io < l)
index b80e8bf43cc63b4350185ab1125ee85f1c43d05f..22881ddcbb9fc0c0a23ee7faf0578727b09a23f6 100644 (file)
@@ -7,11 +7,13 @@
 
 unsigned long unwind_get_return_address(struct unwind_state *state)
 {
-       unsigned long addr = READ_ONCE_NOCHECK(*state->sp);
+       unsigned long addr;
 
        if (unwind_done(state))
                return 0;
 
+       addr = READ_ONCE_NOCHECK(*state->sp);
+
        return ftrace_graph_ret_addr(state->task, &state->graph_idx,
                                     addr, state->sp);
 }
@@ -25,11 +27,12 @@ bool unwind_next_frame(struct unwind_state *state)
                return false;
 
        do {
-               unsigned long addr = READ_ONCE_NOCHECK(*state->sp);
+               for (state->sp++; state->sp < info->end; state->sp++) {
+                       unsigned long addr = READ_ONCE_NOCHECK(*state->sp);
 
-               for (state->sp++; state->sp < info->end; state->sp++)
                        if (__kernel_text_address(addr))
                                return true;
+               }
 
                state->sp = info->next_sp;
 
index 55130846ac87afe11d50e7bdbcf77b77827838b0..c0533fbc39e3a4e9f56575dffe6d0de3a4082706 100644 (file)
@@ -196,6 +196,7 @@ static int xo15_sci_remove(struct acpi_device *device)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int xo15_sci_resume(struct device *dev)
 {
        /* Enable all EC events */
@@ -207,6 +208,7 @@ static int xo15_sci_resume(struct device *dev)
 
        return 0;
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(xo15_sci_pm, NULL, xo15_sci_resume);
 
index f59590645b68641e4de9da7278b6f1c07f2e3b82..1d23bf953a4a451033f2d25a08eab2eebd751b3f 100644 (file)
@@ -16,7 +16,7 @@
 #include <regex.h>
 #include <tools/le_byteshift.h>
 
-void die(char *fmt, ...);
+void die(char *fmt, ...) __attribute__((noreturn));
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
index b8657fa8dc9af7b2f5fe7958693df063cc4c9019..27fd8d92892d47e3478d9bcf3e1294a8eb28da89 100644 (file)
@@ -118,6 +118,9 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
        struct iov_iter i;
        int ret;
 
+       if (!iter_is_iovec(iter))
+               goto fail;
+
        if (map_data)
                copy = true;
        else if (iov_iter_alignment(iter) & align)
@@ -140,6 +143,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
 
 unmap_rq:
        __blk_rq_unmap_user(bio);
+fail:
        rq->bio = NULL;
        return -EINVAL;
 }
index 99cc64ac70efc2ca50f8832be098acadc3b57f76..bd6a029094e6b69455058eec51da6ce86fb8d036 100644 (file)
@@ -40,6 +40,7 @@ obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
+$(obj)/rsa_helper.o: $(obj)/rsapubkey-asn1.h $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
 clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h
 
index 80a0f1a7855181930afa0a545f5bf79584141e5c..e9c0993b131dc34d435d29358a037f56ca62e2b8 100644 (file)
@@ -81,7 +81,11 @@ static inline bool aead_sufficient_data(struct aead_ctx *ctx)
 {
        unsigned as = crypto_aead_authsize(crypto_aead_reqtfm(&ctx->aead_req));
 
-       return ctx->used >= ctx->aead_assoclen + as;
+       /*
+        * The minimum amount of memory needed for an AEAD cipher is
+        * the AAD and in case of decryption the tag.
+        */
+       return ctx->used >= ctx->aead_assoclen + (ctx->enc ? 0 : as);
 }
 
 static void aead_reset_ctx(struct aead_ctx *ctx)
@@ -416,7 +420,7 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg,
        unsigned int i, reqlen = GET_REQ_SIZE(tfm);
        int err = -ENOMEM;
        unsigned long used;
-       size_t outlen;
+       size_t outlen = 0;
        size_t usedpages = 0;
 
        lock_sock(sk);
@@ -426,12 +430,15 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg,
                        goto unlock;
        }
 
-       used = ctx->used;
-       outlen = used;
-
        if (!aead_sufficient_data(ctx))
                goto unlock;
 
+       used = ctx->used;
+       if (ctx->enc)
+               outlen = used + as;
+       else
+               outlen = used - as;
+
        req = sock_kmalloc(sk, reqlen, GFP_KERNEL);
        if (unlikely(!req))
                goto unlock;
@@ -445,7 +452,7 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg,
        aead_request_set_ad(req, ctx->aead_assoclen);
        aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                                  aead_async_cb, sk);
-       used -= ctx->aead_assoclen + (ctx->enc ? as : 0);
+       used -= ctx->aead_assoclen;
 
        /* take over all tx sgls from ctx */
        areq->tsgl = sock_kmalloc(sk, sizeof(*areq->tsgl) * sgl->cur,
@@ -461,7 +468,7 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg,
        areq->tsgls = sgl->cur;
 
        /* create rx sgls */
-       while (iov_iter_count(&msg->msg_iter)) {
+       while (outlen > usedpages && iov_iter_count(&msg->msg_iter)) {
                size_t seglen = min_t(size_t, iov_iter_count(&msg->msg_iter),
                                      (outlen - usedpages));
 
@@ -491,16 +498,14 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg,
 
                last_rsgl = rsgl;
 
-               /* we do not need more iovecs as we have sufficient memory */
-               if (outlen <= usedpages)
-                       break;
-
                iov_iter_advance(&msg->msg_iter, err);
        }
-       err = -EINVAL;
+
        /* ensure output buffer is sufficiently large */
-       if (usedpages < outlen)
-               goto free;
+       if (usedpages < outlen) {
+               err = -EINVAL;
+               goto unlock;
+       }
 
        aead_request_set_crypt(req, areq->tsgl, areq->first_rsgl.sgl.sg, used,
                               areq->iv);
@@ -571,6 +576,7 @@ static int aead_recvmsg_sync(struct socket *sock, struct msghdr *msg, int flags)
                        goto unlock;
        }
 
+       /* data length provided by caller via sendmsg/sendpage */
        used = ctx->used;
 
        /*
@@ -585,16 +591,27 @@ static int aead_recvmsg_sync(struct socket *sock, struct msghdr *msg, int flags)
        if (!aead_sufficient_data(ctx))
                goto unlock;
 
-       outlen = used;
+       /*
+        * Calculate the minimum output buffer size holding the result of the
+        * cipher operation. When encrypting data, the receiving buffer is
+        * larger by the tag length compared to the input buffer as the
+        * encryption operation generates the tag. For decryption, the input
+        * buffer provides the tag which is consumed resulting in only the
+        * plaintext without a buffer for the tag returned to the caller.
+        */
+       if (ctx->enc)
+               outlen = used + as;
+       else
+               outlen = used - as;
 
        /*
         * The cipher operation input data is reduced by the associated data
         * length as this data is processed separately later on.
         */
-       used -= ctx->aead_assoclen + (ctx->enc ? as : 0);
+       used -= ctx->aead_assoclen;
 
        /* convert iovecs of output buffers into scatterlists */
-       while (iov_iter_count(&msg->msg_iter)) {
+       while (outlen > usedpages && iov_iter_count(&msg->msg_iter)) {
                size_t seglen = min_t(size_t, iov_iter_count(&msg->msg_iter),
                                      (outlen - usedpages));
 
@@ -621,16 +638,14 @@ static int aead_recvmsg_sync(struct socket *sock, struct msghdr *msg, int flags)
 
                last_rsgl = rsgl;
 
-               /* we do not need more iovecs as we have sufficient memory */
-               if (outlen <= usedpages)
-                       break;
                iov_iter_advance(&msg->msg_iter, err);
        }
 
-       err = -EINVAL;
        /* ensure output buffer is sufficiently large */
-       if (usedpages < outlen)
+       if (usedpages < outlen) {
+               err = -EINVAL;
                goto unlock;
+       }
 
        sg_mark_end(sgl->sg + sgl->cur - 1);
        aead_request_set_crypt(&ctx->aead_req, sgl->sg, ctx->first_rsgl.sgl.sg,
index fb33f7d3b052f5bb016342c1da2ef61b9f74ad8e..053035b5c8f85686446df108ccbf3675a19cd056 100644 (file)
@@ -262,6 +262,7 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
                              u8 *inbuf, u32 inbuflen,
                              u8 *outbuf, u32 outlen);
 #define DRBG_CTR_NULL_LEN 128
+#define DRBG_OUTSCRATCHLEN DRBG_CTR_NULL_LEN
 
 /* BCC function for CTR DRBG as defined in 10.4.3 */
 static int drbg_ctr_bcc(struct drbg_state *drbg,
@@ -1644,6 +1645,9 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg)
        kfree(drbg->ctr_null_value_buf);
        drbg->ctr_null_value = NULL;
 
+       kfree(drbg->outscratchpadbuf);
+       drbg->outscratchpadbuf = NULL;
+
        return 0;
 }
 
@@ -1708,6 +1712,15 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
        drbg->ctr_null_value = (u8 *)PTR_ALIGN(drbg->ctr_null_value_buf,
                                               alignmask + 1);
 
+       drbg->outscratchpadbuf = kmalloc(DRBG_OUTSCRATCHLEN + alignmask,
+                                        GFP_KERNEL);
+       if (!drbg->outscratchpadbuf) {
+               drbg_fini_sym_kernel(drbg);
+               return -ENOMEM;
+       }
+       drbg->outscratchpad = (u8 *)PTR_ALIGN(drbg->outscratchpadbuf,
+                                             alignmask + 1);
+
        return alignmask;
 }
 
@@ -1737,15 +1750,16 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
                              u8 *outbuf, u32 outlen)
 {
        struct scatterlist sg_in;
+       int ret;
 
        sg_init_one(&sg_in, inbuf, inlen);
 
        while (outlen) {
-               u32 cryptlen = min_t(u32, inlen, outlen);
+               u32 cryptlen = min3(inlen, outlen, (u32)DRBG_OUTSCRATCHLEN);
                struct scatterlist sg_out;
-               int ret;
 
-               sg_init_one(&sg_out, outbuf, cryptlen);
+               /* Output buffer may not be valid for SGL, use scratchpad */
+               sg_init_one(&sg_out, drbg->outscratchpad, cryptlen);
                skcipher_request_set_crypt(drbg->ctr_req, &sg_in, &sg_out,
                                           cryptlen, drbg->V);
                ret = crypto_skcipher_encrypt(drbg->ctr_req);
@@ -1761,14 +1775,19 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
                                break;
                        }
                default:
-                       return ret;
+                       goto out;
                }
                init_completion(&drbg->ctr_completion);
 
+               memcpy(outbuf, drbg->outscratchpad, cryptlen);
+
                outlen -= cryptlen;
        }
+       ret = 0;
 
-       return 0;
+out:
+       memzero_explicit(drbg->outscratchpad, DRBG_OUTSCRATCHLEN);
+       return ret;
 }
 #endif /* CONFIG_CRYPTO_DRBG_CTR */
 
index 94ee44acd4656811c081549b849c295ef160bd12..c207458d62993350d9a0cfca5e1deca573b09c8c 100644 (file)
@@ -254,18 +254,22 @@ out_free_inst:
        goto out;
 }
 
-static inline void mcryptd_check_internal(struct rtattr **tb, u32 *type,
+static inline bool mcryptd_check_internal(struct rtattr **tb, u32 *type,
                                          u32 *mask)
 {
        struct crypto_attr_type *algt;
 
        algt = crypto_get_attr_type(tb);
        if (IS_ERR(algt))
-               return;
-       if ((algt->type & CRYPTO_ALG_INTERNAL))
-               *type |= CRYPTO_ALG_INTERNAL;
-       if ((algt->mask & CRYPTO_ALG_INTERNAL))
-               *mask |= CRYPTO_ALG_INTERNAL;
+               return false;
+
+       *type |= algt->type & CRYPTO_ALG_INTERNAL;
+       *mask |= algt->mask & CRYPTO_ALG_INTERNAL;
+
+       if (*type & *mask & CRYPTO_ALG_INTERNAL)
+               return true;
+       else
+               return false;
 }
 
 static int mcryptd_hash_init_tfm(struct crypto_tfm *tfm)
@@ -492,7 +496,8 @@ static int mcryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb,
        u32 mask = 0;
        int err;
 
-       mcryptd_check_internal(tb, &type, &mask);
+       if (!mcryptd_check_internal(tb, &type, &mask))
+               return -EINVAL;
 
        halg = ahash_attr_alg(tb[1], type, mask);
        if (IS_ERR(halg))
index 71a7d07c28c9447d8ed41bc18c7f3ec4dcc83607..312c4b4dc363fdbc4847d3db55c0cfbfbb80f5f4 100644 (file)
@@ -94,7 +94,7 @@ static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc *acpi_desc)
        return to_acpi_device(acpi_desc->dev);
 }
 
-static int xlat_status(void *buf, unsigned int cmd, u32 status)
+static int xlat_bus_status(void *buf, unsigned int cmd, u32 status)
 {
        struct nd_cmd_clear_error *clear_err;
        struct nd_cmd_ars_status *ars_status;
@@ -113,7 +113,7 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
                flags = ND_ARS_PERSISTENT | ND_ARS_VOLATILE;
                if ((status >> 16 & flags) == 0)
                        return -ENOTTY;
-               break;
+               return 0;
        case ND_CMD_ARS_START:
                /* ARS is in progress */
                if ((status & 0xffff) == NFIT_ARS_START_BUSY)
@@ -122,7 +122,7 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
                /* Command failed */
                if (status & 0xffff)
                        return -EIO;
-               break;
+               return 0;
        case ND_CMD_ARS_STATUS:
                ars_status = buf;
                /* Command failed */
@@ -146,7 +146,8 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
                 * then just continue with the returned results.
                 */
                if (status == NFIT_ARS_STATUS_INTR) {
-                       if (ars_status->flags & NFIT_ARS_F_OVERFLOW)
+                       if (ars_status->out_length >= 40 && (ars_status->flags
+                                               & NFIT_ARS_F_OVERFLOW))
                                return -ENOSPC;
                        return 0;
                }
@@ -154,7 +155,7 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
                /* Unknown status */
                if (status >> 16)
                        return -EIO;
-               break;
+               return 0;
        case ND_CMD_CLEAR_ERROR:
                clear_err = buf;
                if (status & 0xffff)
@@ -163,7 +164,7 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
                        return -EIO;
                if (clear_err->length > clear_err->cleared)
                        return clear_err->cleared;
-               break;
+               return 0;
        default:
                break;
        }
@@ -174,9 +175,18 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
        return 0;
 }
 
-static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
-               struct nvdimm *nvdimm, unsigned int cmd, void *buf,
-               unsigned int buf_len, int *cmd_rc)
+static int xlat_status(struct nvdimm *nvdimm, void *buf, unsigned int cmd,
+               u32 status)
+{
+       if (!nvdimm)
+               return xlat_bus_status(buf, cmd, status);
+       if (status)
+               return -EIO;
+       return 0;
+}
+
+int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
+               unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc)
 {
        struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc);
        union acpi_object in_obj, in_buf, *out_obj;
@@ -298,7 +308,8 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
 
        for (i = 0, offset = 0; i < desc->out_num; i++) {
                u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, buf,
-                               (u32 *) out_obj->buffer.pointer);
+                               (u32 *) out_obj->buffer.pointer,
+                               out_obj->buffer.length - offset);
 
                if (offset + out_size > out_obj->buffer.length) {
                        dev_dbg(dev, "%s:%s output object underflow cmd: %s field: %d\n",
@@ -333,7 +344,8 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
                         */
                        rc = buf_len - offset - in_buf.buffer.length;
                        if (cmd_rc)
-                               *cmd_rc = xlat_status(buf, cmd, fw_status);
+                               *cmd_rc = xlat_status(nvdimm, buf, cmd,
+                                               fw_status);
                } else {
                        dev_err(dev, "%s:%s underrun cmd: %s buf_len: %d out_len: %d\n",
                                        __func__, dimm_name, cmd_name, buf_len,
@@ -343,7 +355,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
        } else {
                rc = 0;
                if (cmd_rc)
-                       *cmd_rc = xlat_status(buf, cmd, fw_status);
+                       *cmd_rc = xlat_status(nvdimm, buf, cmd, fw_status);
        }
 
  out:
@@ -351,6 +363,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
 
        return rc;
 }
+EXPORT_SYMBOL_GPL(acpi_nfit_ctl);
 
 static const char *spa_type_name(u16 type)
 {
@@ -2001,19 +2014,32 @@ static int ars_get_status(struct acpi_nfit_desc *acpi_desc)
        return cmd_rc;
 }
 
-static int ars_status_process_records(struct nvdimm_bus *nvdimm_bus,
+static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc,
                struct nd_cmd_ars_status *ars_status)
 {
+       struct nvdimm_bus *nvdimm_bus = acpi_desc->nvdimm_bus;
        int rc;
        u32 i;
 
+       /*
+        * First record starts at 44 byte offset from the start of the
+        * payload.
+        */
+       if (ars_status->out_length < 44)
+               return 0;
        for (i = 0; i < ars_status->num_records; i++) {
+               /* only process full records */
+               if (ars_status->out_length
+                               < 44 + sizeof(struct nd_ars_record) * (i + 1))
+                       break;
                rc = nvdimm_bus_add_poison(nvdimm_bus,
                                ars_status->records[i].err_address,
                                ars_status->records[i].length);
                if (rc)
                        return rc;
        }
+       if (i < ars_status->num_records)
+               dev_warn(acpi_desc->dev, "detected truncated ars results\n");
 
        return 0;
 }
@@ -2266,8 +2292,7 @@ static int acpi_nfit_query_poison(struct acpi_nfit_desc *acpi_desc,
        if (rc < 0 && rc != -ENOSPC)
                return rc;
 
-       if (ars_status_process_records(acpi_desc->nvdimm_bus,
-                               acpi_desc->ars_status))
+       if (ars_status_process_records(acpi_desc, acpi_desc->ars_status))
                return -ENOMEM;
 
        return 0;
index 14296f5267c8c45a2826b9b82a40dbe8aedf1918..fc29c2e9832e5b1b355d15e8edb8bc0278e31fdb 100644 (file)
@@ -240,5 +240,7 @@ const u8 *to_nfit_uuid(enum nfit_uuids id);
 int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz);
 void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event);
 void __acpi_nvdimm_notify(struct device *dev, u32 event);
+int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
+               unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc);
 void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev);
 #endif /* __NFIT_H__ */
index 9669fc7c19df7fe05b922daf25e0392677433e26..74f4c662f776ecf546d4c61a7de4190a61870b5c 100644 (file)
@@ -1436,13 +1436,6 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
                                "ahci: MRSM is on, fallback to single MSI\n");
                        pci_free_irq_vectors(pdev);
                }
-
-               /*
-                * -ENOSPC indicated we don't have enough vectors.  Don't bother
-                * trying a single vectors for any other error:
-                */
-               if (nvec < 0 && nvec != -ENOSPC)
-                       return nvec;
        }
 
        /*
index 9cceb4a875a58caa19fdd809ad82181f22676fc2..8e575fbdf31d6b5737046111d55600a8638e595b 100644 (file)
@@ -1088,7 +1088,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
                desc[1] = tf->command; /* status */
                desc[2] = tf->device;
                desc[3] = tf->nsect;
-               desc[0] = 0;
+               desc[7] = 0;
                if (tf->flags & ATA_TFLAG_LBA48)  {
                        desc[8] |= 0x80;
                        if (tf->hob_nsect)
@@ -1159,6 +1159,7 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
 {
        sdev->use_10_for_rw = 1;
        sdev->use_10_for_ms = 1;
+       sdev->no_write_same = 1;
 
        /* Schedule policy is determined by ->qc_defer() callback and
         * it needs to see every deferred qc.  Set dev_blocked to 1 to
index efc48bf89d5182a6b4b4150b522fabc2cc1844ee..823e938c9a7877a1cadefde9127d447832630061 100644 (file)
@@ -4090,7 +4090,20 @@ static int mv_platform_probe(struct platform_device *pdev)
 
        /* allocate host */
        if (pdev->dev.of_node) {
-               of_property_read_u32(pdev->dev.of_node, "nr-ports", &n_ports);
+               rc = of_property_read_u32(pdev->dev.of_node, "nr-ports",
+                                          &n_ports);
+               if (rc) {
+                       dev_err(&pdev->dev,
+                               "error parsing nr-ports property: %d\n", rc);
+                       return rc;
+               }
+
+               if (n_ports <= 0) {
+                       dev_err(&pdev->dev, "nr-ports must be positive: %d\n",
+                               n_ports);
+                       return -EINVAL;
+               }
+
                irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
        } else {
                mv_platform_data = dev_get_platdata(&pdev->dev);
index f2aaf9e32a36aa71ece80e6edc39b01b411c74d3..40c2d561417bdecd6bd386f3c92214a51a6faece 100644 (file)
@@ -1727,7 +1727,7 @@ static int eni_do_init(struct atm_dev *dev)
                printk("\n");
                printk(KERN_ERR DEV_LABEL "(itf %d): can't set up page "
                    "mapping\n",dev->number);
-               return error;
+               return -ENOMEM;
        }
        eni_dev->ioaddr = base;
        eni_dev->base_diff = real_base - (unsigned long) base;
index ce43ae3e87b3513245cf5b322d5a4b4984ec9dfa..445505d9ea07187902ed95c6ae121591b23cef5c 100644 (file)
@@ -2143,6 +2143,7 @@ static int lanai_dev_open(struct atm_dev *atmdev)
        lanai->base = (bus_addr_t) ioremap(raw_base, LANAI_MAPPING_SIZE);
        if (lanai->base == NULL) {
                printk(KERN_ERR DEV_LABEL ": couldn't remap I/O space\n");
+               result = -ENOMEM;
                goto error_pci;
        }
        /* 3.3: Reset lanai and PHY */
index e023066e421547c547ded5e94215205ee477eb63..5711708532db12be9a7052a18d5b5ddc7e95d1a1 100644 (file)
 static LIST_HEAD(gpd_list);
 static DEFINE_MUTEX(gpd_list_lock);
 
+struct genpd_lock_ops {
+       void (*lock)(struct generic_pm_domain *genpd);
+       void (*lock_nested)(struct generic_pm_domain *genpd, int depth);
+       int (*lock_interruptible)(struct generic_pm_domain *genpd);
+       void (*unlock)(struct generic_pm_domain *genpd);
+};
+
+static void genpd_lock_mtx(struct generic_pm_domain *genpd)
+{
+       mutex_lock(&genpd->mlock);
+}
+
+static void genpd_lock_nested_mtx(struct generic_pm_domain *genpd,
+                                       int depth)
+{
+       mutex_lock_nested(&genpd->mlock, depth);
+}
+
+static int genpd_lock_interruptible_mtx(struct generic_pm_domain *genpd)
+{
+       return mutex_lock_interruptible(&genpd->mlock);
+}
+
+static void genpd_unlock_mtx(struct generic_pm_domain *genpd)
+{
+       return mutex_unlock(&genpd->mlock);
+}
+
+static const struct genpd_lock_ops genpd_mtx_ops = {
+       .lock = genpd_lock_mtx,
+       .lock_nested = genpd_lock_nested_mtx,
+       .lock_interruptible = genpd_lock_interruptible_mtx,
+       .unlock = genpd_unlock_mtx,
+};
+
+static void genpd_lock_spin(struct generic_pm_domain *genpd)
+       __acquires(&genpd->slock)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&genpd->slock, flags);
+       genpd->lock_flags = flags;
+}
+
+static void genpd_lock_nested_spin(struct generic_pm_domain *genpd,
+                                       int depth)
+       __acquires(&genpd->slock)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave_nested(&genpd->slock, flags, depth);
+       genpd->lock_flags = flags;
+}
+
+static int genpd_lock_interruptible_spin(struct generic_pm_domain *genpd)
+       __acquires(&genpd->slock)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&genpd->slock, flags);
+       genpd->lock_flags = flags;
+       return 0;
+}
+
+static void genpd_unlock_spin(struct generic_pm_domain *genpd)
+       __releases(&genpd->slock)
+{
+       spin_unlock_irqrestore(&genpd->slock, genpd->lock_flags);
+}
+
+static const struct genpd_lock_ops genpd_spin_ops = {
+       .lock = genpd_lock_spin,
+       .lock_nested = genpd_lock_nested_spin,
+       .lock_interruptible = genpd_lock_interruptible_spin,
+       .unlock = genpd_unlock_spin,
+};
+
+#define genpd_lock(p)                  p->lock_ops->lock(p)
+#define genpd_lock_nested(p, d)                p->lock_ops->lock_nested(p, d)
+#define genpd_lock_interruptible(p)    p->lock_ops->lock_interruptible(p)
+#define genpd_unlock(p)                        p->lock_ops->unlock(p)
+
+#define genpd_is_irq_safe(genpd)       (genpd->flags & GENPD_FLAG_IRQ_SAFE)
+
+static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev,
+               struct generic_pm_domain *genpd)
+{
+       bool ret;
+
+       ret = pm_runtime_is_irq_safe(dev) && !genpd_is_irq_safe(genpd);
+
+       /* Warn once for each IRQ safe dev in no sleep domain */
+       if (ret)
+               dev_warn_once(dev, "PM domain %s will not be powered off\n",
+                               genpd->name);
+
+       return ret;
+}
+
 /*
  * Get the generic PM domain for a particular struct device.
  * This validates the struct device pointer, the PM domain pointer,
@@ -200,9 +299,9 @@ static int genpd_poweron(struct generic_pm_domain *genpd, unsigned int depth)
 
                genpd_sd_counter_inc(master);
 
-               mutex_lock_nested(&master->lock, depth + 1);
+               genpd_lock_nested(master, depth + 1);
                ret = genpd_poweron(master, depth + 1);
-               mutex_unlock(&master->lock);
+               genpd_unlock(master);
 
                if (ret) {
                        genpd_sd_counter_dec(master);
@@ -255,9 +354,9 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
                spin_unlock_irq(&dev->power.lock);
 
                if (!IS_ERR(genpd)) {
-                       mutex_lock(&genpd->lock);
+                       genpd_lock(genpd);
                        genpd->max_off_time_changed = true;
-                       mutex_unlock(&genpd->lock);
+                       genpd_unlock(genpd);
                }
 
                dev = dev->parent;
@@ -303,7 +402,12 @@ static int genpd_poweroff(struct generic_pm_domain *genpd, bool is_async)
                if (stat > PM_QOS_FLAGS_NONE)
                        return -EBUSY;
 
-               if (!pm_runtime_suspended(pdd->dev) || pdd->dev->power.irq_safe)
+               /*
+                * Do not allow PM domain to be powered off, when an IRQ safe
+                * device is part of a non-IRQ safe domain.
+                */
+               if (!pm_runtime_suspended(pdd->dev) ||
+                       irq_safe_dev_in_no_sleep_domain(pdd->dev, genpd))
                        not_suspended++;
        }
 
@@ -354,9 +458,9 @@ static void genpd_power_off_work_fn(struct work_struct *work)
 
        genpd = container_of(work, struct generic_pm_domain, power_off_work);
 
-       mutex_lock(&genpd->lock);
+       genpd_lock(genpd);
        genpd_poweroff(genpd, true);
-       mutex_unlock(&genpd->lock);
+       genpd_unlock(genpd);
 }
 
 /**
@@ -466,15 +570,15 @@ static int genpd_runtime_suspend(struct device *dev)
        }
 
        /*
-        * If power.irq_safe is set, this routine will be run with interrupts
-        * off, so it can't use mutexes.
+        * If power.irq_safe is set, this routine may be run with
+        * IRQs disabled, so suspend only if the PM domain also is irq_safe.
         */
-       if (dev->power.irq_safe)
+       if (irq_safe_dev_in_no_sleep_domain(dev, genpd))
                return 0;
 
-       mutex_lock(&genpd->lock);
+       genpd_lock(genpd);
        genpd_poweroff(genpd, false);
-       mutex_unlock(&genpd->lock);
+       genpd_unlock(genpd);
 
        return 0;
 }
@@ -503,15 +607,18 @@ static int genpd_runtime_resume(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       /* If power.irq_safe, the PM domain is never powered off. */
-       if (dev->power.irq_safe) {
+       /*
+        * As we don't power off a non IRQ safe domain, which holds
+        * an IRQ safe device, we don't need to restore power to it.
+        */
+       if (irq_safe_dev_in_no_sleep_domain(dev, genpd)) {
                timed = false;
                goto out;
        }
 
-       mutex_lock(&genpd->lock);
+       genpd_lock(genpd);
        ret = genpd_poweron(genpd, 0);
-       mutex_unlock(&genpd->lock);
+       genpd_unlock(genpd);
 
        if (ret)
                return ret;
@@ -546,10 +653,11 @@ static int genpd_runtime_resume(struct device *dev)
 err_stop:
        genpd_stop_dev(genpd, dev);
 err_poweroff:
-       if (!dev->power.irq_safe) {
-               mutex_lock(&genpd->lock);
+       if (!pm_runtime_is_irq_safe(dev) ||
+               (pm_runtime_is_irq_safe(dev) && genpd_is_irq_safe(genpd))) {
+               genpd_lock(genpd);
                genpd_poweroff(genpd, 0);
-               mutex_unlock(&genpd->lock);
+               genpd_unlock(genpd);
        }
 
        return ret;
@@ -732,20 +840,20 @@ static int pm_genpd_prepare(struct device *dev)
        if (resume_needed(dev, genpd))
                pm_runtime_resume(dev);
 
-       mutex_lock(&genpd->lock);
+       genpd_lock(genpd);
 
        if (genpd->prepared_count++ == 0)
                genpd->suspended_count = 0;
 
-       mutex_unlock(&genpd->lock);
+       genpd_unlock(genpd);
 
        ret = pm_generic_prepare(dev);
        if (ret) {
-               mutex_lock(&genpd->lock);
+               genpd_lock(genpd);
 
                genpd->prepared_count--;
 
-               mutex_unlock(&genpd->lock);
+               genpd_unlock(genpd);
        }
 
        return ret;
@@ -936,13 +1044,13 @@ static void pm_genpd_complete(struct device *dev)
 
        pm_generic_complete(dev);
 
-       mutex_lock(&genpd->lock);
+       genpd_lock(genpd);
 
        genpd->prepared_count--;
        if (!genpd->prepared_count)
                genpd_queue_power_off_work(genpd);
 
-       mutex_unlock(&genpd->lock);
+       genpd_unlock(genpd);
 }
 
 /**
@@ -1071,7 +1179,7 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
        if (IS_ERR(gpd_data))
                return PTR_ERR(gpd_data);
 
-       mutex_lock(&genpd->lock);
+       genpd_lock(genpd);
 
        if (genpd->prepared_count > 0) {
                ret = -EAGAIN;
@@ -1088,7 +1196,7 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
        list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
 
  out:
-       mutex_unlock(&genpd->lock);
+       genpd_unlock(genpd);
 
        if (ret)
                genpd_free_dev_data(dev, gpd_data);
@@ -1130,7 +1238,7 @@ static int genpd_remove_device(struct generic_pm_domain *genpd,
        gpd_data = to_gpd_data(pdd);
        dev_pm_qos_remove_notifier(dev, &gpd_data->nb);
 
-       mutex_lock(&genpd->lock);
+       genpd_lock(genpd);
 
        if (genpd->prepared_count > 0) {
                ret = -EAGAIN;
@@ -1145,14 +1253,14 @@ static int genpd_remove_device(struct generic_pm_domain *genpd,
 
        list_del_init(&pdd->list_node);
 
-       mutex_unlock(&genpd->lock);
+       genpd_unlock(genpd);
 
        genpd_free_dev_data(dev, gpd_data);
 
        return 0;
 
  out:
-       mutex_unlock(&genpd->lock);
+       genpd_unlock(genpd);
        dev_pm_qos_add_notifier(dev, &gpd_data->nb);
 
        return ret;
@@ -1183,12 +1291,23 @@ static int genpd_add_subdomain(struct generic_pm_domain *genpd,
            || genpd == subdomain)
                return -EINVAL;
 
+       /*
+        * If the domain can be powered on/off in an IRQ safe
+        * context, ensure that the subdomain can also be
+        * powered on/off in that context.
+        */
+       if (!genpd_is_irq_safe(genpd) && genpd_is_irq_safe(subdomain)) {
+               WARN(1, "Parent %s of subdomain %s must be IRQ safe\n",
+                               genpd->name, subdomain->name);
+               return -EINVAL;
+       }
+
        link = kzalloc(sizeof(*link), GFP_KERNEL);
        if (!link)
                return -ENOMEM;
 
-       mutex_lock(&subdomain->lock);
-       mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
+       genpd_lock(subdomain);
+       genpd_lock_nested(genpd, SINGLE_DEPTH_NESTING);
 
        if (genpd->status == GPD_STATE_POWER_OFF
            &&  subdomain->status != GPD_STATE_POWER_OFF) {
@@ -1211,8 +1330,8 @@ static int genpd_add_subdomain(struct generic_pm_domain *genpd,
                genpd_sd_counter_inc(genpd);
 
  out:
-       mutex_unlock(&genpd->lock);
-       mutex_unlock(&subdomain->lock);
+       genpd_unlock(genpd);
+       genpd_unlock(subdomain);
        if (ret)
                kfree(link);
        return ret;
@@ -1250,8 +1369,8 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
        if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
                return -EINVAL;
 
-       mutex_lock(&subdomain->lock);
-       mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
+       genpd_lock(subdomain);
+       genpd_lock_nested(genpd, SINGLE_DEPTH_NESTING);
 
        if (!list_empty(&subdomain->master_links) || subdomain->device_count) {
                pr_warn("%s: unable to remove subdomain %s\n", genpd->name,
@@ -1275,13 +1394,39 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
        }
 
 out:
-       mutex_unlock(&genpd->lock);
-       mutex_unlock(&subdomain->lock);
+       genpd_unlock(genpd);
+       genpd_unlock(subdomain);
 
        return ret;
 }
 EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
 
+static int genpd_set_default_power_state(struct generic_pm_domain *genpd)
+{
+       struct genpd_power_state *state;
+
+       state = kzalloc(sizeof(*state), GFP_KERNEL);
+       if (!state)
+               return -ENOMEM;
+
+       genpd->states = state;
+       genpd->state_count = 1;
+       genpd->free = state;
+
+       return 0;
+}
+
+static void genpd_lock_init(struct generic_pm_domain *genpd)
+{
+       if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
+               spin_lock_init(&genpd->slock);
+               genpd->lock_ops = &genpd_spin_ops;
+       } else {
+               mutex_init(&genpd->mlock);
+               genpd->lock_ops = &genpd_mtx_ops;
+       }
+}
+
 /**
  * pm_genpd_init - Initialize a generic I/O PM domain object.
  * @genpd: PM domain object to initialize.
@@ -1293,13 +1438,15 @@ EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
 int pm_genpd_init(struct generic_pm_domain *genpd,
                  struct dev_power_governor *gov, bool is_off)
 {
+       int ret;
+
        if (IS_ERR_OR_NULL(genpd))
                return -EINVAL;
 
        INIT_LIST_HEAD(&genpd->master_links);
        INIT_LIST_HEAD(&genpd->slave_links);
        INIT_LIST_HEAD(&genpd->dev_list);
-       mutex_init(&genpd->lock);
+       genpd_lock_init(genpd);
        genpd->gov = gov;
        INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
        atomic_set(&genpd->sd_count, 0);
@@ -1325,19 +1472,12 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
                genpd->dev_ops.start = pm_clk_resume;
        }
 
-       if (genpd->state_idx >= GENPD_MAX_NUM_STATES) {
-               pr_warn("Initial state index out of bounds.\n");
-               genpd->state_idx = GENPD_MAX_NUM_STATES - 1;
-       }
-
-       if (genpd->state_count > GENPD_MAX_NUM_STATES) {
-               pr_warn("Limiting states to  %d\n", GENPD_MAX_NUM_STATES);
-               genpd->state_count = GENPD_MAX_NUM_STATES;
-       }
-
        /* Use only one "off" state if there were no states declared */
-       if (genpd->state_count == 0)
-               genpd->state_count = 1;
+       if (genpd->state_count == 0) {
+               ret = genpd_set_default_power_state(genpd);
+               if (ret)
+                       return ret;
+       }
 
        mutex_lock(&gpd_list_lock);
        list_add(&genpd->gpd_list_node, &gpd_list);
@@ -1354,16 +1494,16 @@ static int genpd_remove(struct generic_pm_domain *genpd)
        if (IS_ERR_OR_NULL(genpd))
                return -EINVAL;
 
-       mutex_lock(&genpd->lock);
+       genpd_lock(genpd);
 
        if (genpd->has_provider) {
-               mutex_unlock(&genpd->lock);
+               genpd_unlock(genpd);
                pr_err("Provider present, unable to remove %s\n", genpd->name);
                return -EBUSY;
        }
 
        if (!list_empty(&genpd->master_links) || genpd->device_count) {
-               mutex_unlock(&genpd->lock);
+               genpd_unlock(genpd);
                pr_err("%s: unable to remove %s\n", __func__, genpd->name);
                return -EBUSY;
        }
@@ -1375,8 +1515,9 @@ static int genpd_remove(struct generic_pm_domain *genpd)
        }
 
        list_del(&genpd->gpd_list_node);
-       mutex_unlock(&genpd->lock);
+       genpd_unlock(genpd);
        cancel_work_sync(&genpd->power_off_work);
+       kfree(genpd->free);
        pr_debug("%s: removed %s\n", __func__, genpd->name);
 
        return 0;
@@ -1890,21 +2031,117 @@ int genpd_dev_pm_attach(struct device *dev)
        mutex_unlock(&gpd_list_lock);
 
        if (ret < 0) {
-               dev_err(dev, "failed to add to PM domain %s: %d",
-                       pd->name, ret);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "failed to add to PM domain %s: %d",
+                               pd->name, ret);
                goto out;
        }
 
        dev->pm_domain->detach = genpd_dev_pm_detach;
        dev->pm_domain->sync = genpd_dev_pm_sync;
 
-       mutex_lock(&pd->lock);
+       genpd_lock(pd);
        ret = genpd_poweron(pd, 0);
-       mutex_unlock(&pd->lock);
+       genpd_unlock(pd);
 out:
        return ret ? -EPROBE_DEFER : 0;
 }
 EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
+
+static const struct of_device_id idle_state_match[] = {
+       { .compatible = "domain-idle-state", },
+       { }
+};
+
+static int genpd_parse_state(struct genpd_power_state *genpd_state,
+                                   struct device_node *state_node)
+{
+       int err;
+       u32 residency;
+       u32 entry_latency, exit_latency;
+       const struct of_device_id *match_id;
+
+       match_id = of_match_node(idle_state_match, state_node);
+       if (!match_id)
+               return -EINVAL;
+
+       err = of_property_read_u32(state_node, "entry-latency-us",
+                                               &entry_latency);
+       if (err) {
+               pr_debug(" * %s missing entry-latency-us property\n",
+                                               state_node->full_name);
+               return -EINVAL;
+       }
+
+       err = of_property_read_u32(state_node, "exit-latency-us",
+                                               &exit_latency);
+       if (err) {
+               pr_debug(" * %s missing exit-latency-us property\n",
+                                               state_node->full_name);
+               return -EINVAL;
+       }
+
+       err = of_property_read_u32(state_node, "min-residency-us", &residency);
+       if (!err)
+               genpd_state->residency_ns = 1000 * residency;
+
+       genpd_state->power_on_latency_ns = 1000 * exit_latency;
+       genpd_state->power_off_latency_ns = 1000 * entry_latency;
+       genpd_state->fwnode = &state_node->fwnode;
+
+       return 0;
+}
+
+/**
+ * of_genpd_parse_idle_states: Return array of idle states for the genpd.
+ *
+ * @dn: The genpd device node
+ * @states: The pointer to which the state array will be saved.
+ * @n: The count of elements in the array returned from this function.
+ *
+ * Returns the device states parsed from the OF node. The memory for the states
+ * is allocated by this function and is the responsibility of the caller to
+ * free the memory after use.
+ */
+int of_genpd_parse_idle_states(struct device_node *dn,
+                       struct genpd_power_state **states, int *n)
+{
+       struct genpd_power_state *st;
+       struct device_node *np;
+       int i = 0;
+       int err, ret;
+       int count;
+       struct of_phandle_iterator it;
+
+       count = of_count_phandle_with_args(dn, "domain-idle-states", NULL);
+       if (count <= 0)
+               return -EINVAL;
+
+       st = kcalloc(count, sizeof(*st), GFP_KERNEL);
+       if (!st)
+               return -ENOMEM;
+
+       /* Loop over the phandles until all the requested entry is found */
+       of_for_each_phandle(&it, err, dn, "domain-idle-states", NULL, 0) {
+               np = it.node;
+               ret = genpd_parse_state(&st[i++], np);
+               if (ret) {
+                       pr_err
+                       ("Parsing idle state node %s failed with err %d\n",
+                                                       np->full_name, ret);
+                       of_node_put(np);
+                       kfree(st);
+                       return ret;
+               }
+       }
+
+       *n = count;
+       *states = st;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(of_genpd_parse_idle_states);
+
 #endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
 
 
@@ -1958,7 +2195,7 @@ static int pm_genpd_summary_one(struct seq_file *s,
        char state[16];
        int ret;
 
-       ret = mutex_lock_interruptible(&genpd->lock);
+       ret = genpd_lock_interruptible(genpd);
        if (ret)
                return -ERESTARTSYS;
 
@@ -1984,7 +2221,9 @@ static int pm_genpd_summary_one(struct seq_file *s,
        }
 
        list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
-               kobj_path = kobject_get_path(&pm_data->dev->kobj, GFP_KERNEL);
+               kobj_path = kobject_get_path(&pm_data->dev->kobj,
+                               genpd_is_irq_safe(genpd) ?
+                               GFP_ATOMIC : GFP_KERNEL);
                if (kobj_path == NULL)
                        continue;
 
@@ -1995,7 +2234,7 @@ static int pm_genpd_summary_one(struct seq_file *s,
 
        seq_puts(s, "\n");
 exit:
-       mutex_unlock(&genpd->lock);
+       genpd_unlock(genpd);
 
        return 0;
 }
index 2932a5bd892f7e2b400d5b806c7df36b3cdc30a8..eb474c882ebe058f33d589e0cbf28cca8da818ef 100644 (file)
@@ -1460,10 +1460,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
        dpm_watchdog_clear(&wd);
 
  Complete:
-       complete_all(&dev->power.completion);
        if (error)
                async_error = error;
 
+       complete_all(&dev->power.completion);
        TRACE_SUSPEND(error);
        return error;
 }
index 50e30e7b059d18a034c80b2a71fd846a098189a1..a84332aefc2da73aa3252877cf970efe9e2b9f77 100644 (file)
@@ -21,14 +21,22 @@ extern void pm_runtime_init(struct device *dev);
 extern void pm_runtime_reinit(struct device *dev);
 extern void pm_runtime_remove(struct device *dev);
 
+#define WAKE_IRQ_DEDICATED_ALLOCATED   BIT(0)
+#define WAKE_IRQ_DEDICATED_MANAGED     BIT(1)
+#define WAKE_IRQ_DEDICATED_MASK                (WAKE_IRQ_DEDICATED_ALLOCATED | \
+                                        WAKE_IRQ_DEDICATED_MANAGED)
+
 struct wake_irq {
        struct device *dev;
+       unsigned int status;
        int irq;
-       bool dedicated_irq:1;
 };
 
 extern void dev_pm_arm_wake_irq(struct wake_irq *wirq);
 extern void dev_pm_disarm_wake_irq(struct wake_irq *wirq);
+extern void dev_pm_enable_wake_irq_check(struct device *dev,
+                                        bool can_change_status);
+extern void dev_pm_disable_wake_irq_check(struct device *dev);
 
 #ifdef CONFIG_PM_SLEEP
 
@@ -104,6 +112,15 @@ static inline void dev_pm_disarm_wake_irq(struct wake_irq *wirq)
 {
 }
 
+static inline void dev_pm_enable_wake_irq_check(struct device *dev,
+                                               bool can_change_status)
+{
+}
+
+static inline void dev_pm_disable_wake_irq_check(struct device *dev)
+{
+}
+
 #endif
 
 #ifdef CONFIG_PM_SLEEP
index 82a081ea43176ca8e1d8accd886ad7065287a8aa..26856d05003702b4551e6df44c67db919fd6883f 100644 (file)
@@ -241,7 +241,8 @@ static int rpm_check_suspend_allowed(struct device *dev)
                retval = -EACCES;
        else if (atomic_read(&dev->power.usage_count) > 0)
                retval = -EAGAIN;
-       else if (!pm_children_suspended(dev))
+       else if (!dev->power.ignore_children &&
+                       atomic_read(&dev->power.child_count))
                retval = -EBUSY;
 
        /* Pending resume requests take precedence over suspends. */
@@ -515,7 +516,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
 
        callback = RPM_GET_CALLBACK(dev, runtime_suspend);
 
-       dev_pm_enable_wake_irq(dev);
+       dev_pm_enable_wake_irq_check(dev, true);
        retval = rpm_callback(callback, dev);
        if (retval)
                goto fail;
@@ -554,7 +555,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
        return retval;
 
  fail:
-       dev_pm_disable_wake_irq(dev);
+       dev_pm_disable_wake_irq_check(dev);
        __update_runtime_status(dev, RPM_ACTIVE);
        dev->power.deferred_resume = false;
        wake_up_all(&dev->power.wait_queue);
@@ -712,8 +713,8 @@ static int rpm_resume(struct device *dev, int rpmflags)
 
                spin_lock(&parent->power.lock);
                /*
-                * We can resume if the parent's runtime PM is disabled or it
-                * is set to ignore children.
+                * Resume the parent if it has runtime PM enabled and not been
+                * set to ignore its children.
                 */
                if (!parent->power.disable_depth
                    && !parent->power.ignore_children) {
@@ -737,12 +738,12 @@ static int rpm_resume(struct device *dev, int rpmflags)
 
        callback = RPM_GET_CALLBACK(dev, runtime_resume);
 
-       dev_pm_disable_wake_irq(dev);
+       dev_pm_disable_wake_irq_check(dev);
        retval = rpm_callback(callback, dev);
        if (retval) {
                __update_runtime_status(dev, RPM_SUSPENDED);
                pm_runtime_cancel_pending(dev);
-               dev_pm_enable_wake_irq(dev);
+               dev_pm_enable_wake_irq_check(dev, false);
        } else {
  no_callback:
                __update_runtime_status(dev, RPM_ACTIVE);
@@ -1027,7 +1028,17 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
                goto out_set;
 
        if (status == RPM_SUSPENDED) {
-               /* It always is possible to set the status to 'suspended'. */
+               /*
+                * It is invalid to suspend a device with an active child,
+                * unless it has been set to ignore its children.
+                */
+               if (!dev->power.ignore_children &&
+                       atomic_read(&dev->power.child_count)) {
+                       dev_err(dev, "runtime PM trying to suspend device but active child\n");
+                       error = -EBUSY;
+                       goto out;
+               }
+
                if (parent) {
                        atomic_add_unless(&parent->power.child_count, -1, 0);
                        notify_parent = !parent->power.ignore_children;
@@ -1478,6 +1489,16 @@ int pm_runtime_force_suspend(struct device *dev)
        if (ret)
                goto err;
 
+       /*
+        * Increase the runtime PM usage count for the device's parent, in case
+        * when we find the device being used when system suspend was invoked.
+        * This informs pm_runtime_force_resume() to resume the parent
+        * immediately, which is needed to be able to resume its children,
+        * when not deferring the resume to be managed via runtime PM.
+        */
+       if (dev->parent && atomic_read(&dev->power.usage_count) > 1)
+               pm_runtime_get_noresume(dev->parent);
+
        pm_runtime_set_suspended(dev);
        return 0;
 err:
@@ -1487,16 +1508,20 @@ err:
 EXPORT_SYMBOL_GPL(pm_runtime_force_suspend);
 
 /**
- * pm_runtime_force_resume - Force a device into resume state.
+ * pm_runtime_force_resume - Force a device into resume state if needed.
  * @dev: Device to resume.
  *
  * Prior invoking this function we expect the user to have brought the device
  * into low power state by a call to pm_runtime_force_suspend(). Here we reverse
- * those actions and brings the device into full power. We update the runtime PM
- * status and re-enables runtime PM.
+ * those actions and brings the device into full power, if it is expected to be
+ * used on system resume. To distinguish that, we check whether the runtime PM
+ * usage count is greater than 1 (the PM core increases the usage count in the
+ * system PM prepare phase), as that indicates a real user (such as a subsystem,
+ * driver, userspace, etc.) is using it. If that is the case, the device is
+ * expected to be used on system resume as well, so then we resume it. In the
+ * other case, we defer the resume to be managed via runtime PM.
  *
- * Typically this function may be invoked from a system resume callback to make
- * sure the device is put into full power state.
+ * Typically this function may be invoked from a system resume callback.
  */
 int pm_runtime_force_resume(struct device *dev)
 {
@@ -1513,6 +1538,17 @@ int pm_runtime_force_resume(struct device *dev)
        if (!pm_runtime_status_suspended(dev))
                goto out;
 
+       /*
+        * Decrease the parent's runtime PM usage count, if we increased it
+        * during system suspend in pm_runtime_force_suspend().
+       */
+       if (atomic_read(&dev->power.usage_count) > 1) {
+               if (dev->parent)
+                       pm_runtime_put_noidle(dev->parent);
+       } else {
+               goto out;
+       }
+
        ret = pm_runtime_set_active(dev);
        if (ret)
                goto out;
index 0d77cd6fd8d11653c789fa8834e8eb53b801a6d9..404d94c6c8bc6a4531b0666a77c5b86daab207a6 100644 (file)
@@ -110,8 +110,10 @@ void dev_pm_clear_wake_irq(struct device *dev)
        dev->power.wakeirq = NULL;
        spin_unlock_irqrestore(&dev->power.lock, flags);
 
-       if (wirq->dedicated_irq)
+       if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED) {
                free_irq(wirq->irq, wirq);
+               wirq->status &= ~WAKE_IRQ_DEDICATED_MASK;
+       }
        kfree(wirq);
 }
 EXPORT_SYMBOL_GPL(dev_pm_clear_wake_irq);
@@ -179,7 +181,6 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
 
        wirq->dev = dev;
        wirq->irq = irq;
-       wirq->dedicated_irq = true;
        irq_set_status_flags(irq, IRQ_NOAUTOEN);
 
        /*
@@ -195,6 +196,8 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
        if (err)
                goto err_free_irq;
 
+       wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED;
+
        return err;
 
 err_free_irq:
@@ -210,9 +213,9 @@ EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq);
  * dev_pm_enable_wake_irq - Enable device wake-up interrupt
  * @dev: Device
  *
- * Called from the bus code or the device driver for
- * runtime_suspend() to enable the wake-up interrupt while
- * the device is running.
+ * Optionally called from the bus code or the device driver for
+ * runtime_resume() to override the PM runtime core managed wake-up
+ * interrupt handling to enable the wake-up interrupt.
  *
  * Note that for runtime_suspend()) the wake-up interrupts
  * should be unconditionally enabled unlike for suspend()
@@ -222,7 +225,7 @@ void dev_pm_enable_wake_irq(struct device *dev)
 {
        struct wake_irq *wirq = dev->power.wakeirq;
 
-       if (wirq && wirq->dedicated_irq)
+       if (wirq && (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED))
                enable_irq(wirq->irq);
 }
 EXPORT_SYMBOL_GPL(dev_pm_enable_wake_irq);
@@ -231,19 +234,72 @@ EXPORT_SYMBOL_GPL(dev_pm_enable_wake_irq);
  * dev_pm_disable_wake_irq - Disable device wake-up interrupt
  * @dev: Device
  *
- * Called from the bus code or the device driver for
- * runtime_resume() to disable the wake-up interrupt while
- * the device is running.
+ * Optionally called from the bus code or the device driver for
+ * runtime_suspend() to override the PM runtime core managed wake-up
+ * interrupt handling to disable the wake-up interrupt.
  */
 void dev_pm_disable_wake_irq(struct device *dev)
 {
        struct wake_irq *wirq = dev->power.wakeirq;
 
-       if (wirq && wirq->dedicated_irq)
+       if (wirq && (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED))
                disable_irq_nosync(wirq->irq);
 }
 EXPORT_SYMBOL_GPL(dev_pm_disable_wake_irq);
 
+/**
+ * dev_pm_enable_wake_irq_check - Checks and enables wake-up interrupt
+ * @dev: Device
+ * @can_change_status: Can change wake-up interrupt status
+ *
+ * Enables wakeirq conditionally. We need to enable wake-up interrupt
+ * lazily on the first rpm_suspend(). This is needed as the consumer device
+ * starts in RPM_SUSPENDED state, and the the first pm_runtime_get() would
+ * otherwise try to disable already disabled wakeirq. The wake-up interrupt
+ * starts disabled with IRQ_NOAUTOEN set.
+ *
+ * Should be only called from rpm_suspend() and rpm_resume() path.
+ * Caller must hold &dev->power.lock to change wirq->status
+ */
+void dev_pm_enable_wake_irq_check(struct device *dev,
+                                 bool can_change_status)
+{
+       struct wake_irq *wirq = dev->power.wakeirq;
+
+       if (!wirq || !((wirq->status & WAKE_IRQ_DEDICATED_MASK)))
+               return;
+
+       if (likely(wirq->status & WAKE_IRQ_DEDICATED_MANAGED)) {
+               goto enable;
+       } else if (can_change_status) {
+               wirq->status |= WAKE_IRQ_DEDICATED_MANAGED;
+               goto enable;
+       }
+
+       return;
+
+enable:
+       enable_irq(wirq->irq);
+}
+
+/**
+ * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt
+ * @dev: Device
+ *
+ * Disables wake-up interrupt conditionally based on status.
+ * Should be only called from rpm_suspend() and rpm_resume() path.
+ */
+void dev_pm_disable_wake_irq_check(struct device *dev)
+{
+       struct wake_irq *wirq = dev->power.wakeirq;
+
+       if (!wirq || !((wirq->status & WAKE_IRQ_DEDICATED_MASK)))
+               return;
+
+       if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED)
+               disable_irq_nosync(wirq->irq);
+}
+
 /**
  * dev_pm_arm_wake_irq - Arm device wake-up
  * @wirq: Device wake-up interrupt
index 04365b17ee67fe668f4bfc1f5683846af999009a..5497f7fc44d04c0287a6c51d968a7df0165a37c3 100644 (file)
@@ -1403,7 +1403,8 @@ static ssize_t hot_remove_store(struct class *class,
        zram = idr_find(&zram_index_idr, dev_id);
        if (zram) {
                ret = zram_remove(zram);
-               idr_remove(&zram_index_idr, dev_id);
+               if (!ret)
+                       idr_remove(&zram_index_idr, dev_id);
        } else {
                ret = -ENODEV;
        }
@@ -1412,8 +1413,14 @@ static ssize_t hot_remove_store(struct class *class,
        return ret ? ret : count;
 }
 
+/*
+ * NOTE: hot_add attribute is not the usual read-only sysfs attribute. In a
+ * sense that reading from this file does alter the state of your system -- it
+ * creates a new un-initialized zram device and returns back this device's
+ * device_id (or an error code if it fails to create a new device).
+ */
 static struct class_attribute zram_control_class_attrs[] = {
-       __ATTR_RO(hot_add),
+       __ATTR(hot_add, 0400, hot_add_show, NULL),
        __ATTR_WO(hot_remove),
        __ATTR_NULL,
 };
index f21e9b7afd1ad3ab25f210ea0de59eabb5721015..e3eed5a784044c3db5e1260d82e7a200ff4b62e6 100644 (file)
@@ -20,7 +20,7 @@ config CLK_BCM_KONA
 
 config COMMON_CLK_IPROC
        bool "Broadcom iProc clock support"
-       depends on ARCH_BCM_IPROC || COMPILE_TEST
+       depends on ARCH_BCM_IPROC || ARCH_BCM_63XX || COMPILE_TEST
        depends on COMMON_CLK
        default ARCH_BCM_IPROC
        help
index 4a82a49cff5e604a290b395a84614fc5158dd27d..fc75a335a7ce12480f12f41a95091417466b6a92 100644 (file)
@@ -143,7 +143,7 @@ static SUNXI_CCU_NKM_WITH_MUX_GATE_LOCK(pll_mipi_clk, "pll-mipi",
                                        4, 2,   /* K */
                                        0, 4,   /* M */
                                        21, 0,  /* mux */
-                                       BIT(31),        /* gate */
+                                       BIT(31) | BIT(23) | BIT(22), /* gate */
                                        BIT(28),        /* lock */
                                        CLK_SET_RATE_UNGATE);
 
index 96b40ca57697d0220452349dc83ff406099d11d7..9bd1f78a05471955890e41da51e1b81811c00d64 100644 (file)
@@ -131,7 +131,7 @@ static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_mipi_clk, "pll-mipi",
                                    8, 4,               /* N */
                                    4, 2,               /* K */
                                    0, 4,               /* M */
-                                   BIT(31),            /* gate */
+                                   BIT(31) | BIT(23) | BIT(22), /* gate */
                                    BIT(28),            /* lock */
                                    CLK_SET_RATE_UNGATE);
 
index 72ff196589851d652ff4d369bf0ce497aa0e2165..e483b78c6343fd745f83e52b317edbb3ccb23e92 100644 (file)
@@ -558,8 +558,9 @@ static int caam_probe(struct platform_device *pdev)
         * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
         * long pointers in master configuration register
         */
-       clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK, MCFGR_AWCACHE_CACH |
-                     MCFGR_AWCACHE_BUFF | MCFGR_WDENABLE | MCFGR_LARGE_BURST |
+       clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR,
+                     MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF |
+                     MCFGR_WDENABLE | MCFGR_LARGE_BURST |
                      (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0));
 
        /*
index ec64fbcdeb49230d10fce5cda83dc238dbb45500..199b0bb69b89bcd5c96af1a9355208b367737089 100644 (file)
@@ -422,7 +422,7 @@ static inline void get_aes_decrypt_key(unsigned char *dec_key,
 {
        u32 temp;
        u32 w_ring[MAX_NK];
-       int i, j, k = 0;
+       int i, j, k;
        u8  nr, nk;
 
        switch (keylength) {
@@ -460,6 +460,7 @@ static inline void get_aes_decrypt_key(unsigned char *dec_key,
                temp = w_ring[i % nk];
                i++;
        }
+       i--;
        for (k = 0, j = i % nk; k < nk; k++) {
                *((u32 *)dec_key + k) = htonl(w_ring[j]);
                j--;
index 9f284682c091aa1b675ea5a1fdda806a5345935c..77712b375b8428a88ad127d689a4e3a99e6b0640 100644 (file)
@@ -168,12 +168,11 @@ static void mv_cesa_ahash_std_step(struct ahash_request *req)
        mv_cesa_adjust_op(engine, &creq->op_tmpl);
        memcpy_toio(engine->sram, &creq->op_tmpl, sizeof(creq->op_tmpl));
 
-       digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(req));
-       for (i = 0; i < digsize / 4; i++)
-               writel_relaxed(creq->state[i], engine->regs + CESA_IVDIG(i));
-
-       mv_cesa_adjust_op(engine, &creq->op_tmpl);
-       memcpy_toio(engine->sram, &creq->op_tmpl, sizeof(creq->op_tmpl));
+       if (!sreq->offset) {
+               digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(req));
+               for (i = 0; i < digsize / 4; i++)
+                       writel_relaxed(creq->state[i], engine->regs + CESA_IVDIG(i));
+       }
 
        if (creq->cache_ptr)
                memcpy_toio(engine->sram + CESA_SA_DATA_SRAM_OFFSET,
index 3d94ff20fdca2bd64beeb86674e42abe736117de..286447a83dab809e0522e461c7e6ca416e997462 100644 (file)
@@ -271,7 +271,7 @@ static int check_vma(struct dax_dev *dax_dev, struct vm_area_struct *vma,
                return -ENXIO;
 
        /* prevent private mappings from being established */
-       if ((vma->vm_flags & VM_SHARED) != VM_SHARED) {
+       if ((vma->vm_flags & VM_MAYSHARE) != VM_MAYSHARE) {
                dev_info(dev, "%s: %s: fail, attempted private mapping\n",
                                current->comm, func);
                return -EINVAL;
index 496f72b134eb07777f623f62d10eda6743565fa1..05c2850c04b00f01bfcda21182fdaa15f3c0edb1 100644 (file)
@@ -2472,6 +2472,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
                                 struct drm_file *file_priv);
 void amdgpu_driver_preclose_kms(struct drm_device *dev,
                                struct drm_file *file_priv);
+int amdgpu_suspend(struct amdgpu_device *adev);
 int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon);
 int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon);
 u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe);
index 02ca5dd978f664ad31cbe248674514e707ce143f..6c343a9331825452a572a876649dc3b67eba28c4 100644 (file)
@@ -485,7 +485,6 @@ static int amdgpu_atpx_power_state(enum vga_switcheroo_client_id id,
  */
 static bool amdgpu_atpx_pci_probe_handle(struct pci_dev *pdev)
 {
-       struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
        acpi_handle dhandle, atpx_handle;
        acpi_status status;
 
@@ -500,7 +499,6 @@ static bool amdgpu_atpx_pci_probe_handle(struct pci_dev *pdev)
        }
        amdgpu_atpx_priv.dhandle = dhandle;
        amdgpu_atpx_priv.atpx.handle = atpx_handle;
-       amdgpu_atpx_priv.bridge_pm_usable = parent_pdev && parent_pdev->bridge_d3;
        return true;
 }
 
@@ -562,17 +560,25 @@ static bool amdgpu_atpx_detect(void)
        struct pci_dev *pdev = NULL;
        bool has_atpx = false;
        int vga_count = 0;
+       bool d3_supported = false;
+       struct pci_dev *parent_pdev;
 
        while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
                vga_count++;
 
                has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true);
+
+               parent_pdev = pci_upstream_bridge(pdev);
+               d3_supported |= parent_pdev && parent_pdev->bridge_d3;
        }
 
        while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
                vga_count++;
 
                has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true);
+
+               parent_pdev = pci_upstream_bridge(pdev);
+               d3_supported |= parent_pdev && parent_pdev->bridge_d3;
        }
 
        if (has_atpx && vga_count == 2) {
@@ -580,6 +586,7 @@ static bool amdgpu_atpx_detect(void)
                printk(KERN_INFO "vga_switcheroo: detected switching method %s handle\n",
                       acpi_method_name);
                amdgpu_atpx_priv.atpx_detected = true;
+               amdgpu_atpx_priv.bridge_pm_usable = d3_supported;
                amdgpu_atpx_init();
                return true;
        }
index 3161d77bf29989f5a6edb6d817973630e2b996b4..e41d4baebf86ea39b7e604071d72b0ca29ded612 100644 (file)
@@ -1493,7 +1493,7 @@ static int amdgpu_fini(struct amdgpu_device *adev)
        return 0;
 }
 
-static int amdgpu_suspend(struct amdgpu_device *adev)
+int amdgpu_suspend(struct amdgpu_device *adev)
 {
        int i, r;
 
index 02ff0747197c13e91ee378696a0fc46fe2b193f0..e0890deccb2fe31d4deb78deac640d53d8f34a45 100644 (file)
@@ -479,12 +479,15 @@ amdgpu_pci_remove(struct pci_dev *pdev)
 static void
 amdgpu_pci_shutdown(struct pci_dev *pdev)
 {
+       struct drm_device *dev = pci_get_drvdata(pdev);
+       struct amdgpu_device *adev = dev->dev_private;
+
        /* if we are running in a VM, make sure the device
         * torn down properly on reboot/shutdown.
         * unfortunately we can't detect certain
         * hypervisors so just do this all the time.
         */
-       amdgpu_pci_remove(pdev);
+       amdgpu_suspend(adev);
 }
 
 static int amdgpu_pmops_suspend(struct device *dev)
index 4ccc0b72324de3e6c6e1e530a57f3bb070f92e6d..71bb2f8dc157ba36029c5131237a20a8c0e2b7be 100644 (file)
@@ -2214,6 +2214,7 @@ uint32_t polaris10_get_mac_definition(uint32_t value)
 int polaris10_process_firmware_header(struct pp_hwmgr *hwmgr)
 {
        struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smumgr->backend);
+       struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
        uint32_t tmp;
        int result;
        bool error = false;
@@ -2233,8 +2234,10 @@ int polaris10_process_firmware_header(struct pp_hwmgr *hwmgr)
                        offsetof(SMU74_Firmware_Header, SoftRegisters),
                        &tmp, SMC_RAM_END);
 
-       if (!result)
+       if (!result) {
+               data->soft_regs_start = tmp;
                smu_data->smu7_data.soft_regs_start = tmp;
+       }
 
        error |= (0 != result);
 
index fb6a418ce6be611176e26bf5fa699503178e8364..e138fb51e8ce58e1ac6bad38c96447e68152ec48 100644 (file)
@@ -375,7 +375,6 @@ static int hdlcd_drm_bind(struct device *dev)
 
 err_fbdev:
        drm_kms_helper_poll_fini(drm);
-       drm_mode_config_cleanup(drm);
        drm_vblank_cleanup(drm);
 err_vblank:
        pm_runtime_disable(drm->dev);
@@ -387,6 +386,7 @@ err_unload:
        drm_irq_uninstall(drm);
        of_reserved_mem_device_release(drm->dev);
 err_free:
+       drm_mode_config_cleanup(drm);
        dev_set_drvdata(dev, NULL);
        drm_dev_unref(drm);
 
index 0ad2c47f808fc1d732ef530eba96a6dd265a71c6..71c3473476c7498721a8524c2b8fbde18bf22d7b 100644 (file)
@@ -254,10 +254,12 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_
                req->value = dev->mode_config.async_page_flip;
                break;
        case DRM_CAP_PAGE_FLIP_TARGET:
-               req->value = 1;
-               drm_for_each_crtc(crtc, dev) {
-                       if (!crtc->funcs->page_flip_target)
-                               req->value = 0;
+               if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+                       req->value = 1;
+                       drm_for_each_crtc(crtc, dev) {
+                               if (!crtc->funcs->page_flip_target)
+                                       req->value = 0;
+                       }
                }
                break;
        case DRM_CAP_CURSOR_WIDTH:
index 91ab7e9d6d2ead0827c0b452f119062d8be50a0a..00eb4814b9131655b4ac441d7dbabed02c6ccc8e 100644 (file)
@@ -2268,7 +2268,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
                        page = shmem_read_mapping_page(mapping, i);
                        if (IS_ERR(page)) {
                                ret = PTR_ERR(page);
-                               goto err_pages;
+                               goto err_sg;
                        }
                }
 #ifdef CONFIG_SWIOTLB
@@ -2311,8 +2311,9 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 
        return 0;
 
-err_pages:
+err_sg:
        sg_mark_end(sg);
+err_pages:
        for_each_sgt_page(page, sgt_iter, st)
                put_page(page);
        sg_free_table(st);
index 81c11499bcf059356669cf77778bb53ae17bb0e6..3cb70d73239bf424857c87d3dbc252cfa94c37ab 100644 (file)
@@ -12260,7 +12260,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        intel_crtc->reset_count = i915_reset_count(&dev_priv->gpu_error);
        if (i915_reset_in_progress_or_wedged(&dev_priv->gpu_error)) {
                ret = -EIO;
-               goto cleanup;
+               goto unlock;
        }
 
        atomic_inc(&intel_crtc->unpin_work_count);
@@ -12352,6 +12352,7 @@ cleanup_unpin:
        intel_unpin_fb_obj(fb, crtc->primary->state->rotation);
 cleanup_pending:
        atomic_dec(&intel_crtc->unpin_work_count);
+unlock:
        mutex_unlock(&dev->struct_mutex);
 cleanup:
        crtc->primary->fb = old_fb;
index 4129b12521a67e9296582353a74f418bbf84d1c6..0ae13cd2addaa2f4e53a9b69903c3095912d8460 100644 (file)
@@ -479,7 +479,6 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
  */
 static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
 {
-       struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
        acpi_handle dhandle, atpx_handle;
        acpi_status status;
 
@@ -493,7 +492,6 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
 
        radeon_atpx_priv.dhandle = dhandle;
        radeon_atpx_priv.atpx.handle = atpx_handle;
-       radeon_atpx_priv.bridge_pm_usable = parent_pdev && parent_pdev->bridge_d3;
        return true;
 }
 
@@ -555,11 +553,16 @@ static bool radeon_atpx_detect(void)
        struct pci_dev *pdev = NULL;
        bool has_atpx = false;
        int vga_count = 0;
+       bool d3_supported = false;
+       struct pci_dev *parent_pdev;
 
        while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
                vga_count++;
 
                has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
+
+               parent_pdev = pci_upstream_bridge(pdev);
+               d3_supported |= parent_pdev && parent_pdev->bridge_d3;
        }
 
        /* some newer PX laptops mark the dGPU as a non-VGA display device */
@@ -567,6 +570,9 @@ static bool radeon_atpx_detect(void)
                vga_count++;
 
                has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
+
+               parent_pdev = pci_upstream_bridge(pdev);
+               d3_supported |= parent_pdev && parent_pdev->bridge_d3;
        }
 
        if (has_atpx && vga_count == 2) {
@@ -574,6 +580,7 @@ static bool radeon_atpx_detect(void)
                printk(KERN_INFO "vga_switcheroo: detected switching method %s handle\n",
                       acpi_method_name);
                radeon_atpx_priv.atpx_detected = true;
+               radeon_atpx_priv.bridge_pm_usable = d3_supported;
                radeon_atpx_init();
                return true;
        }
index 419b54bfc7c77a981b754f87fd1cbd116e5c0672..5e63b17f935d5fb09947498331dd90269a78891a 100644 (file)
@@ -381,9 +381,7 @@ static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
                if (result)
                        return result;
 
-               data[i] = octeon_i2c_data_read(i2c, &result);
-               if (result)
-                       return result;
+               data[i] = octeon_i2c_data_read(i2c);
                if (recv_len && i == 0) {
                        if (data[i] > I2C_SMBUS_BLOCK_MAX + 1)
                                return -EPROTO;
index 1db7c835a45454cb03880410745f9563f43945c7..87151ea74acd475a37726fd43fa927f486ddc76e 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/i2c.h>
 #include <linux/i2c-smbus.h>
 #include <linux/io.h>
-#include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 
@@ -145,9 +144,9 @@ static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8
        u64 tmp;
 
        __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI(i2c));
-
-       readq_poll_timeout(i2c->twsi_base + SW_TWSI(i2c), tmp, tmp & SW_TWSI_V,
-                          I2C_OCTEON_EVENT_WAIT, i2c->adap.timeout);
+       do {
+               tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+       } while ((tmp & SW_TWSI_V) != 0);
 }
 
 #define octeon_i2c_ctl_write(i2c, val)                                 \
@@ -164,28 +163,24 @@ static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8
  *
  * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
  */
-static inline int octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg,
-                                     int *error)
+static inline u8 octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg)
 {
        u64 tmp;
-       int ret;
 
        __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI(i2c));
+       do {
+               tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+       } while ((tmp & SW_TWSI_V) != 0);
 
-       ret = readq_poll_timeout(i2c->twsi_base + SW_TWSI(i2c), tmp,
-                                tmp & SW_TWSI_V, I2C_OCTEON_EVENT_WAIT,
-                                i2c->adap.timeout);
-       if (error)
-               *error = ret;
        return tmp & 0xFF;
 }
 
 #define octeon_i2c_ctl_read(i2c)                                       \
-       octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL, NULL)
-#define octeon_i2c_data_read(i2c, error)                               \
-       octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA, error)
+       octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL)
+#define octeon_i2c_data_read(i2c)                                      \
+       octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA)
 #define octeon_i2c_stat_read(i2c)                                      \
-       octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT, NULL)
+       octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT)
 
 /**
  * octeon_i2c_read_int - read the TWSI_INT register
index fb4b185dea963e8a93fba4688a8e7ab5621c2b99..bee2674249722fd4117a7d7de95d222749c6b86a 100644 (file)
@@ -1115,10 +1115,6 @@ static int psmouse_extensions(struct psmouse *psmouse,
                if (psmouse_try_protocol(psmouse, PSMOUSE_TOUCHKIT_PS2,
                                         &max_proto, set_properties, true))
                        return PSMOUSE_TOUCHKIT_PS2;
-
-               if (psmouse_try_protocol(psmouse, PSMOUSE_BYD,
-                                        &max_proto, set_properties, true))
-                       return PSMOUSE_BYD;
        }
 
        /*
index d1f8ab915b15cc69b5fc9564777d413dad0f8318..b90776ef56ec8d2d35e8b51a79f75c2ecd472ab1 100644 (file)
@@ -755,8 +755,10 @@ static int __init ser_gigaset_init(void)
        driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
                                    GIGASET_MODULENAME, GIGASET_DEVNAME,
                                    &ops, THIS_MODULE);
-       if (!driver)
+       if (!driver) {
+               rc = -ENOMEM;
                goto error;
+       }
 
        rc = tty_register_ldisc(N_GIGASET_M101, &gigaset_ldisc);
        if (rc != 0) {
index 9600cd771f1a3a234a3b7c647904f3dbd22385c7..e034ed847ff32ca1fcf0a55e66eebe2171e3d32f 100644 (file)
@@ -1499,6 +1499,7 @@ hfc4s8s_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                printk(KERN_INFO
                       "HFC-4S/8S: failed to request address space at 0x%04x\n",
                       hw->iobase);
+               err = -EBUSY;
                goto out;
        }
 
index e8fc4952c6b074f80a2af132d2bc161e7fd3d8c7..2147678f0225344f1f40ee4a42781f778cee588c 100644 (file)
@@ -43,11 +43,22 @@ struct __packed pucan_command {
        u16     args[3];
 };
 
+#define PUCAN_TSLOW_BRP_BITS           10
+#define PUCAN_TSLOW_TSGEG1_BITS                8
+#define PUCAN_TSLOW_TSGEG2_BITS                7
+#define PUCAN_TSLOW_SJW_BITS           7
+
+#define PUCAN_TSLOW_BRP_MASK           ((1 << PUCAN_TSLOW_BRP_BITS) - 1)
+#define PUCAN_TSLOW_TSEG1_MASK         ((1 << PUCAN_TSLOW_TSGEG1_BITS) - 1)
+#define PUCAN_TSLOW_TSEG2_MASK         ((1 << PUCAN_TSLOW_TSGEG2_BITS) - 1)
+#define PUCAN_TSLOW_SJW_MASK           ((1 << PUCAN_TSLOW_SJW_BITS) - 1)
+
 /* uCAN TIMING_SLOW command fields */
-#define PUCAN_TSLOW_SJW_T(s, t)                (((s) & 0xf) | ((!!(t)) << 7))
-#define PUCAN_TSLOW_TSEG2(t)           ((t) & 0xf)
-#define PUCAN_TSLOW_TSEG1(t)           ((t) & 0x3f)
-#define PUCAN_TSLOW_BRP(b)             ((b) & 0x3ff)
+#define PUCAN_TSLOW_SJW_T(s, t)                (((s) & PUCAN_TSLOW_SJW_MASK) | \
+                                                               ((!!(t)) << 7))
+#define PUCAN_TSLOW_TSEG2(t)           ((t) & PUCAN_TSLOW_TSEG2_MASK)
+#define PUCAN_TSLOW_TSEG1(t)           ((t) & PUCAN_TSLOW_TSEG1_MASK)
+#define PUCAN_TSLOW_BRP(b)             ((b) & PUCAN_TSLOW_BRP_MASK)
 
 struct __packed pucan_timing_slow {
        __le16  opcode_channel;
@@ -60,11 +71,21 @@ struct __packed pucan_timing_slow {
        __le16  brp;            /* BaudRate Prescaler */
 };
 
+#define PUCAN_TFAST_BRP_BITS           10
+#define PUCAN_TFAST_TSGEG1_BITS                5
+#define PUCAN_TFAST_TSGEG2_BITS                4
+#define PUCAN_TFAST_SJW_BITS           4
+
+#define PUCAN_TFAST_BRP_MASK           ((1 << PUCAN_TFAST_BRP_BITS) - 1)
+#define PUCAN_TFAST_TSEG1_MASK         ((1 << PUCAN_TFAST_TSGEG1_BITS) - 1)
+#define PUCAN_TFAST_TSEG2_MASK         ((1 << PUCAN_TFAST_TSGEG2_BITS) - 1)
+#define PUCAN_TFAST_SJW_MASK           ((1 << PUCAN_TFAST_SJW_BITS) - 1)
+
 /* uCAN TIMING_FAST command fields */
-#define PUCAN_TFAST_SJW(s)             ((s) & 0x3)
-#define PUCAN_TFAST_TSEG2(t)           ((t) & 0x7)
-#define PUCAN_TFAST_TSEG1(t)           ((t) & 0xf)
-#define PUCAN_TFAST_BRP(b)             ((b) & 0x3ff)
+#define PUCAN_TFAST_SJW(s)             ((s) & PUCAN_TFAST_SJW_MASK)
+#define PUCAN_TFAST_TSEG2(t)           ((t) & PUCAN_TFAST_TSEG2_MASK)
+#define PUCAN_TFAST_TSEG1(t)           ((t) & PUCAN_TFAST_TSEG1_MASK)
+#define PUCAN_TFAST_BRP(b)             ((b) & PUCAN_TFAST_BRP_MASK)
 
 struct __packed pucan_timing_fast {
        __le16  opcode_channel;
index c06382cdfdfee4d736ef9b86eb2ef33104a62b92..0b0302af3bd2dc3da893ed120afa028d21b219da 100644 (file)
@@ -39,6 +39,7 @@ static struct usb_device_id peak_usb_table[] = {
        {USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBPRO_PRODUCT_ID)},
        {USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBFD_PRODUCT_ID)},
        {USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBPROFD_PRODUCT_ID)},
+       {USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBX6_PRODUCT_ID)},
        {} /* Terminating entry */
 };
 
@@ -50,6 +51,7 @@ static const struct peak_usb_adapter *const peak_usb_adapters_list[] = {
        &pcan_usb_pro,
        &pcan_usb_fd,
        &pcan_usb_pro_fd,
+       &pcan_usb_x6,
 };
 
 /*
@@ -868,23 +870,25 @@ lbl_free_candev:
 static void peak_usb_disconnect(struct usb_interface *intf)
 {
        struct peak_usb_device *dev;
+       struct peak_usb_device *dev_prev_siblings;
 
        /* unregister as many netdev devices as siblings */
-       for (dev = usb_get_intfdata(intf); dev; dev = dev->prev_siblings) {
+       for (dev = usb_get_intfdata(intf); dev; dev = dev_prev_siblings) {
                struct net_device *netdev = dev->netdev;
                char name[IFNAMSIZ];
 
+               dev_prev_siblings = dev->prev_siblings;
                dev->state &= ~PCAN_USB_STATE_CONNECTED;
                strncpy(name, netdev->name, IFNAMSIZ);
 
                unregister_netdev(netdev);
-               free_candev(netdev);
 
                kfree(dev->cmd_buf);
                dev->next_siblings = NULL;
                if (dev->adapter->dev_free)
                        dev->adapter->dev_free(dev);
 
+               free_candev(netdev);
                dev_info(&intf->dev, "%s removed\n", name);
        }
 
index 506fe506c9d37fcb212196457d9db37f3a46cb2a..3cbfb069893d5ce1d2da16969426433240ad4ce6 100644 (file)
@@ -27,6 +27,7 @@
 #define PCAN_USBPRO_PRODUCT_ID         0x000d
 #define PCAN_USBPROFD_PRODUCT_ID       0x0011
 #define PCAN_USBFD_PRODUCT_ID          0x0012
+#define PCAN_USBX6_PRODUCT_ID          0x0014
 
 #define PCAN_USB_DRIVER_NAME           "peak_usb"
 
@@ -90,6 +91,7 @@ extern const struct peak_usb_adapter pcan_usb;
 extern const struct peak_usb_adapter pcan_usb_pro;
 extern const struct peak_usb_adapter pcan_usb_fd;
 extern const struct peak_usb_adapter pcan_usb_pro_fd;
+extern const struct peak_usb_adapter pcan_usb_x6;
 
 struct peak_time_ref {
        struct timeval tv_host_0, tv_host;
index ce44a033f63bb1456d44139b003c14cecb35b7e9..304732550f0a628a7fa9ae9c94e67113d9a869a0 100644 (file)
@@ -993,24 +993,24 @@ static void pcan_usb_fd_free(struct peak_usb_device *dev)
 static const struct can_bittiming_const pcan_usb_fd_const = {
        .name = "pcan_usb_fd",
        .tseg1_min = 1,
-       .tseg1_max = 64,
+       .tseg1_max = (1 << PUCAN_TSLOW_TSGEG1_BITS),
        .tseg2_min = 1,
-       .tseg2_max = 16,
-       .sjw_max = 16,
+       .tseg2_max = (1 << PUCAN_TSLOW_TSGEG2_BITS),
+       .sjw_max = (1 << PUCAN_TSLOW_SJW_BITS),
        .brp_min = 1,
-       .brp_max = 1024,
+       .brp_max = (1 << PUCAN_TSLOW_BRP_BITS),
        .brp_inc = 1,
 };
 
 static const struct can_bittiming_const pcan_usb_fd_data_const = {
        .name = "pcan_usb_fd",
        .tseg1_min = 1,
-       .tseg1_max = 16,
+       .tseg1_max = (1 << PUCAN_TFAST_TSGEG1_BITS),
        .tseg2_min = 1,
-       .tseg2_max = 8,
-       .sjw_max = 4,
+       .tseg2_max = (1 << PUCAN_TFAST_TSGEG2_BITS),
+       .sjw_max = (1 << PUCAN_TFAST_SJW_BITS),
        .brp_min = 1,
-       .brp_max = 1024,
+       .brp_max = (1 << PUCAN_TFAST_BRP_BITS),
        .brp_inc = 1,
 };
 
@@ -1065,24 +1065,24 @@ const struct peak_usb_adapter pcan_usb_fd = {
 static const struct can_bittiming_const pcan_usb_pro_fd_const = {
        .name = "pcan_usb_pro_fd",
        .tseg1_min = 1,
-       .tseg1_max = 64,
+       .tseg1_max = (1 << PUCAN_TSLOW_TSGEG1_BITS),
        .tseg2_min = 1,
-       .tseg2_max = 16,
-       .sjw_max = 16,
+       .tseg2_max = (1 << PUCAN_TSLOW_TSGEG2_BITS),
+       .sjw_max = (1 << PUCAN_TSLOW_SJW_BITS),
        .brp_min = 1,
-       .brp_max = 1024,
+       .brp_max = (1 << PUCAN_TSLOW_BRP_BITS),
        .brp_inc = 1,
 };
 
 static const struct can_bittiming_const pcan_usb_pro_fd_data_const = {
        .name = "pcan_usb_pro_fd",
        .tseg1_min = 1,
-       .tseg1_max = 16,
+       .tseg1_max = (1 << PUCAN_TFAST_TSGEG1_BITS),
        .tseg2_min = 1,
-       .tseg2_max = 8,
-       .sjw_max = 4,
+       .tseg2_max = (1 << PUCAN_TFAST_TSGEG2_BITS),
+       .sjw_max = (1 << PUCAN_TFAST_SJW_BITS),
        .brp_min = 1,
-       .brp_max = 1024,
+       .brp_max = (1 << PUCAN_TFAST_BRP_BITS),
        .brp_inc = 1,
 };
 
@@ -1132,3 +1132,75 @@ const struct peak_usb_adapter pcan_usb_pro_fd = {
 
        .do_get_berr_counter = pcan_usb_fd_get_berr_counter,
 };
+
+/* describes the PCAN-USB X6 adapter */
+static const struct can_bittiming_const pcan_usb_x6_const = {
+       .name = "pcan_usb_x6",
+       .tseg1_min = 1,
+       .tseg1_max = (1 << PUCAN_TSLOW_TSGEG1_BITS),
+       .tseg2_min = 1,
+       .tseg2_max = (1 << PUCAN_TSLOW_TSGEG2_BITS),
+       .sjw_max = (1 << PUCAN_TSLOW_SJW_BITS),
+       .brp_min = 1,
+       .brp_max = (1 << PUCAN_TSLOW_BRP_BITS),
+       .brp_inc = 1,
+};
+
+static const struct can_bittiming_const pcan_usb_x6_data_const = {
+       .name = "pcan_usb_x6",
+       .tseg1_min = 1,
+       .tseg1_max = (1 << PUCAN_TFAST_TSGEG1_BITS),
+       .tseg2_min = 1,
+       .tseg2_max = (1 << PUCAN_TFAST_TSGEG2_BITS),
+       .sjw_max = (1 << PUCAN_TFAST_SJW_BITS),
+       .brp_min = 1,
+       .brp_max = (1 << PUCAN_TFAST_BRP_BITS),
+       .brp_inc = 1,
+};
+
+const struct peak_usb_adapter pcan_usb_x6 = {
+       .name = "PCAN-USB X6",
+       .device_id = PCAN_USBX6_PRODUCT_ID,
+       .ctrl_count = PCAN_USBPROFD_CHANNEL_COUNT,
+       .ctrlmode_supported = CAN_CTRLMODE_FD |
+                       CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY,
+       .clock = {
+               .freq = PCAN_UFD_CRYSTAL_HZ,
+       },
+       .bittiming_const = &pcan_usb_x6_const,
+       .data_bittiming_const = &pcan_usb_x6_data_const,
+
+       /* size of device private data */
+       .sizeof_dev_private = sizeof(struct pcan_usb_fd_device),
+
+       /* timestamps usage */
+       .ts_used_bits = 32,
+       .ts_period = 1000000, /* calibration period in ts. */
+       .us_per_ts_scale = 1, /* us = (ts * scale) >> shift */
+       .us_per_ts_shift = 0,
+
+       /* give here messages in/out endpoints */
+       .ep_msg_in = PCAN_USBPRO_EP_MSGIN,
+       .ep_msg_out = {PCAN_USBPRO_EP_MSGOUT_0, PCAN_USBPRO_EP_MSGOUT_1},
+
+       /* size of rx/tx usb buffers */
+       .rx_buffer_size = PCAN_UFD_RX_BUFFER_SIZE,
+       .tx_buffer_size = PCAN_UFD_TX_BUFFER_SIZE,
+
+       /* device callbacks */
+       .intf_probe = pcan_usb_pro_probe,       /* same as PCAN-USB Pro */
+       .dev_init = pcan_usb_fd_init,
+
+       .dev_exit = pcan_usb_fd_exit,
+       .dev_free = pcan_usb_fd_free,
+       .dev_set_bus = pcan_usb_fd_set_bus,
+       .dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
+       .dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+       .dev_decode_buf = pcan_usb_fd_decode_buf,
+       .dev_start = pcan_usb_fd_start,
+       .dev_stop = pcan_usb_fd_stop,
+       .dev_restart_async = pcan_usb_fd_restart_async,
+       .dev_encode_msg = pcan_usb_fd_encode_msg,
+
+       .do_get_berr_counter = pcan_usb_fd_get_berr_counter,
+};
index bda31f308cc2a0b028273298345b5d43b03908b6..a0eee72186957211329609cd357f5c140278c412 100644 (file)
@@ -400,12 +400,6 @@ static int tse_rx(struct altera_tse_private *priv, int limit)
 
                skb_put(skb, pktlength);
 
-               /* make cache consistent with receive packet buffer */
-               dma_sync_single_for_cpu(priv->device,
-                                       priv->rx_ring[entry].dma_addr,
-                                       priv->rx_ring[entry].len,
-                                       DMA_FROM_DEVICE);
-
                dma_unmap_single(priv->device, priv->rx_ring[entry].dma_addr,
                                 priv->rx_ring[entry].len, DMA_FROM_DEVICE);
 
@@ -469,7 +463,6 @@ static int tse_tx_complete(struct altera_tse_private *priv)
 
        if (unlikely(netif_queue_stopped(priv->dev) &&
                     tse_tx_avail(priv) > TSE_TX_THRESH(priv))) {
-               netif_tx_lock(priv->dev);
                if (netif_queue_stopped(priv->dev) &&
                    tse_tx_avail(priv) > TSE_TX_THRESH(priv)) {
                        if (netif_msg_tx_done(priv))
@@ -477,7 +470,6 @@ static int tse_tx_complete(struct altera_tse_private *priv)
                                           __func__);
                        netif_wake_queue(priv->dev);
                }
-               netif_tx_unlock(priv->dev);
        }
 
        spin_unlock(&priv->tx_lock);
@@ -592,10 +584,6 @@ static int tse_start_xmit(struct sk_buff *skb, struct net_device *dev)
        buffer->dma_addr = dma_addr;
        buffer->len = nopaged_len;
 
-       /* Push data out of the cache hierarchy into main memory */
-       dma_sync_single_for_device(priv->device, buffer->dma_addr,
-                                  buffer->len, DMA_TO_DEVICE);
-
        priv->dmaops->tx_buffer(priv, buffer);
 
        skb_tx_timestamp(skb);
@@ -819,6 +807,8 @@ static int init_phy(struct net_device *dev)
 
        if (!phydev) {
                netdev_err(dev, "Could not find the PHY\n");
+               if (fixed_link)
+                       of_phy_deregister_fixed_link(priv->device->of_node);
                return -ENODEV;
        }
 
@@ -1545,10 +1535,15 @@ err_free_netdev:
 static int altera_tse_remove(struct platform_device *pdev)
 {
        struct net_device *ndev = platform_get_drvdata(pdev);
+       struct altera_tse_private *priv = netdev_priv(ndev);
 
-       if (ndev->phydev)
+       if (ndev->phydev) {
                phy_disconnect(ndev->phydev);
 
+               if (of_phy_is_fixed_link(priv->device->of_node))
+                       of_phy_deregister_fixed_link(priv->device->of_node);
+       }
+
        platform_set_drvdata(pdev, NULL);
        altera_tse_mdio_destroy(ndev);
        unregister_netdev(ndev);
index 9de078819aa676525d4fae65a6a47e3df448dc1e..4f76351782005557a31ecd5f2997f7e8c888e78c 100644 (file)
@@ -829,7 +829,7 @@ static int xgbe_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int xgbe_suspend(struct device *dev)
 {
        struct net_device *netdev = dev_get_drvdata(dev);
@@ -874,7 +874,7 @@ static int xgbe_resume(struct device *dev)
 
        return ret;
 }
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_ACPI
 static const struct acpi_device_id xgbe_acpi_match[] = {
index 00c38bf151e6a3a721b09c284e51c15da239c0b7..e078d8da978c189ccf411c903fadcdb3434ab8b9 100644 (file)
@@ -1466,12 +1466,12 @@ static int nb8800_probe(struct platform_device *pdev)
 
        ret = nb8800_hw_init(dev);
        if (ret)
-               goto err_free_bus;
+               goto err_deregister_fixed_link;
 
        if (ops && ops->init) {
                ret = ops->init(dev);
                if (ret)
-                       goto err_free_bus;
+                       goto err_deregister_fixed_link;
        }
 
        dev->netdev_ops = &nb8800_netdev_ops;
@@ -1504,6 +1504,9 @@ static int nb8800_probe(struct platform_device *pdev)
 
 err_free_dma:
        nb8800_dma_free(dev);
+err_deregister_fixed_link:
+       if (of_phy_is_fixed_link(pdev->dev.of_node))
+               of_phy_deregister_fixed_link(pdev->dev.of_node);
 err_free_bus:
        of_node_put(priv->phy_node);
        mdiobus_unregister(bus);
@@ -1521,6 +1524,8 @@ static int nb8800_remove(struct platform_device *pdev)
        struct nb8800_priv *priv = netdev_priv(ndev);
 
        unregister_netdev(ndev);
+       if (of_phy_is_fixed_link(pdev->dev.of_node))
+               of_phy_deregister_fixed_link(pdev->dev.of_node);
        of_node_put(priv->phy_node);
 
        mdiobus_unregister(priv->mii_bus);
index c3354b9941d1cc733aa7999eaf6fd1f8d4244af1..25d1eb4933d0b8b28dc53d07344eb6a47a263893 100644 (file)
@@ -1755,13 +1755,13 @@ static int bcm_sysport_probe(struct platform_device *pdev)
        if (priv->irq0 <= 0 || priv->irq1 <= 0) {
                dev_err(&pdev->dev, "invalid interrupts\n");
                ret = -EINVAL;
-               goto err;
+               goto err_free_netdev;
        }
 
        priv->base = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(priv->base)) {
                ret = PTR_ERR(priv->base);
-               goto err;
+               goto err_free_netdev;
        }
 
        priv->netdev = dev;
@@ -1779,7 +1779,7 @@ static int bcm_sysport_probe(struct platform_device *pdev)
                ret = of_phy_register_fixed_link(dn);
                if (ret) {
                        dev_err(&pdev->dev, "failed to register fixed PHY\n");
-                       goto err;
+                       goto err_free_netdev;
                }
 
                priv->phy_dn = dn;
@@ -1821,7 +1821,7 @@ static int bcm_sysport_probe(struct platform_device *pdev)
        ret = register_netdev(dev);
        if (ret) {
                dev_err(&pdev->dev, "failed to register net_device\n");
-               goto err;
+               goto err_deregister_fixed_link;
        }
 
        priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK;
@@ -1832,7 +1832,11 @@ static int bcm_sysport_probe(struct platform_device *pdev)
                 priv->base, priv->irq0, priv->irq1, txq, rxq);
 
        return 0;
-err:
+
+err_deregister_fixed_link:
+       if (of_phy_is_fixed_link(dn))
+               of_phy_deregister_fixed_link(dn);
+err_free_netdev:
        free_netdev(dev);
        return ret;
 }
@@ -1840,11 +1844,14 @@ err:
 static int bcm_sysport_remove(struct platform_device *pdev)
 {
        struct net_device *dev = dev_get_drvdata(&pdev->dev);
+       struct device_node *dn = pdev->dev.of_node;
 
        /* Not much to do, ndo_close has been called
         * and we use managed allocations
         */
        unregister_netdev(dev);
+       if (of_phy_is_fixed_link(dn))
+               of_phy_deregister_fixed_link(dn);
        free_netdev(dev);
        dev_set_drvdata(&pdev->dev, NULL);
 
index 85a7800bfc128e56b5a3886cba65b707ed5db57b..5f19427c7b278b99ee34a20b4d854e1d1293578b 100644 (file)
@@ -1872,8 +1872,16 @@ static void bnx2x_get_ringparam(struct net_device *dev,
 
        ering->rx_max_pending = MAX_RX_AVAIL;
 
+       /* If size isn't already set, we give an estimation of the number
+        * of buffers we'll have. We're neglecting some possible conditions
+        * [we couldn't know for certain at this point if number of queues
+        * might shrink] but the number would be correct for the likely
+        * scenario.
+        */
        if (bp->rx_ring_size)
                ering->rx_pending = bp->rx_ring_size;
+       else if (BNX2X_NUM_RX_QUEUES(bp))
+               ering->rx_pending = MAX_RX_AVAIL / BNX2X_NUM_RX_QUEUES(bp);
        else
                ering->rx_pending = MAX_RX_AVAIL;
 
index 0cee4c0283f9b35a4d56cff5936d4e541c7da4e5..4febe60eadc2ef57e592943ef6b3515a22bd3111 100644 (file)
@@ -10138,7 +10138,7 @@ static void __bnx2x_add_udp_port(struct bnx2x *bp, u16 port,
 {
        struct bnx2x_udp_tunnel *udp_port = &bp->udp_tunnel_ports[type];
 
-       if (!netif_running(bp->dev) || !IS_PF(bp))
+       if (!netif_running(bp->dev) || !IS_PF(bp) || CHIP_IS_E1x(bp))
                return;
 
        if (udp_port->count && udp_port->dst_port == port) {
@@ -10163,7 +10163,7 @@ static void __bnx2x_del_udp_port(struct bnx2x *bp, u16 port,
 {
        struct bnx2x_udp_tunnel *udp_port = &bp->udp_tunnel_ports[type];
 
-       if (!IS_PF(bp))
+       if (!IS_PF(bp) || CHIP_IS_E1x(bp))
                return;
 
        if (!udp_port->count || udp_port->dst_port != port) {
@@ -13505,6 +13505,7 @@ static int bnx2x_init_firmware(struct bnx2x *bp)
 
        /* Initialize the pointers to the init arrays */
        /* Blob */
+       rc = -ENOMEM;
        BNX2X_ALLOC_AND_SET(init_data, request_firmware_exit, be32_to_cpu_n);
 
        /* Opcodes */
index ee1a803aa11a3cb505a5b95efcf6069fa01ae201..f08a20b921e7a66f7738c65becb9993523452634 100644 (file)
@@ -4120,7 +4120,7 @@ static int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp)
                bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id;
        }
        mutex_unlock(&bp->hwrm_cmd_lock);
-       return 0;
+       return rc;
 }
 
 static int bnxt_hwrm_func_qcfg(struct bnxt *bp)
index 4464bc5db9347654806831b5e0f1d6042a3f8c75..a4e60e56c14f73495d588f059e815f09d7a9e243 100644 (file)
@@ -1172,6 +1172,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
                                          struct bcmgenet_tx_ring *ring)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
+       struct device *kdev = &priv->pdev->dev;
        struct enet_cb *tx_cb_ptr;
        struct netdev_queue *txq;
        unsigned int pkts_compl = 0;
@@ -1199,13 +1200,13 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
                if (tx_cb_ptr->skb) {
                        pkts_compl++;
                        bytes_compl += GENET_CB(tx_cb_ptr->skb)->bytes_sent;
-                       dma_unmap_single(&dev->dev,
+                       dma_unmap_single(kdev,
                                         dma_unmap_addr(tx_cb_ptr, dma_addr),
                                         dma_unmap_len(tx_cb_ptr, dma_len),
                                         DMA_TO_DEVICE);
                        bcmgenet_free_cb(tx_cb_ptr);
                } else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) {
-                       dma_unmap_page(&dev->dev,
+                       dma_unmap_page(kdev,
                                       dma_unmap_addr(tx_cb_ptr, dma_addr),
                                       dma_unmap_len(tx_cb_ptr, dma_len),
                                       DMA_TO_DEVICE);
@@ -1775,6 +1776,7 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv,
 
 static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
 {
+       struct device *kdev = &priv->pdev->dev;
        struct enet_cb *cb;
        int i;
 
@@ -1782,7 +1784,7 @@ static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
                cb = &priv->rx_cbs[i];
 
                if (dma_unmap_addr(cb, dma_addr)) {
-                       dma_unmap_single(&priv->dev->dev,
+                       dma_unmap_single(kdev,
                                         dma_unmap_addr(cb, dma_addr),
                                         priv->rx_buf_len, DMA_FROM_DEVICE);
                        dma_unmap_addr_set(cb, dma_addr, 0);
index 457c3bc8cfff49654b45e879495e5cbfa88428d6..e87607621e62a076104d67046a10603305d66ecf 100644 (file)
@@ -542,8 +542,10 @@ static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
        /* Make sure we initialize MoCA PHYs with a link down */
        if (phy_mode == PHY_INTERFACE_MODE_MOCA) {
                phydev = of_phy_find_device(dn);
-               if (phydev)
+               if (phydev) {
                        phydev->link = 0;
+                       put_device(&phydev->mdio.dev);
+               }
        }
 
        return 0;
@@ -625,6 +627,7 @@ static int bcmgenet_mii_bus_init(struct bcmgenet_priv *priv)
 int bcmgenet_mii_init(struct net_device *dev)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
+       struct device_node *dn = priv->pdev->dev.of_node;
        int ret;
 
        ret = bcmgenet_mii_alloc(priv);
@@ -638,6 +641,8 @@ int bcmgenet_mii_init(struct net_device *dev)
        return 0;
 
 out:
+       if (of_phy_is_fixed_link(dn))
+               of_phy_deregister_fixed_link(dn);
        of_node_put(priv->phy_dn);
        mdiobus_unregister(priv->mii_bus);
        mdiobus_free(priv->mii_bus);
@@ -647,7 +652,10 @@ out:
 void bcmgenet_mii_exit(struct net_device *dev)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
+       struct device_node *dn = priv->pdev->dev.of_node;
 
+       if (of_phy_is_fixed_link(dn))
+               of_phy_deregister_fixed_link(dn);
        of_node_put(priv->phy_dn);
        mdiobus_unregister(priv->mii_bus);
        mdiobus_free(priv->mii_bus);
index 533653bd7aec99781af410a6c10be47d2ffc6fc0..ec09fcece711dc326dca2c63db8440e193eb2b31 100644 (file)
@@ -975,6 +975,7 @@ static inline void macb_init_rx_ring(struct macb *bp)
                addr += bp->rx_buffer_size;
        }
        bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
+       bp->rx_tail = 0;
 }
 
 static int macb_rx(struct macb *bp, int budget)
@@ -1156,6 +1157,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
                if (status & MACB_BIT(RXUBR)) {
                        ctrl = macb_readl(bp, NCR);
                        macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE));
+                       wmb();
                        macb_writel(bp, NCR, ctrl | MACB_BIT(RE));
 
                        if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
@@ -1616,8 +1618,6 @@ static void macb_init_rings(struct macb *bp)
        bp->queues[0].tx_head = 0;
        bp->queues[0].tx_tail = 0;
        bp->queues[0].tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
-
-       bp->rx_tail = 0;
 }
 
 static void macb_reset_hw(struct macb *bp)
@@ -2770,6 +2770,7 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
        if (intstatus & MACB_BIT(RXUBR)) {
                ctl = macb_readl(lp, NCR);
                macb_writel(lp, NCR, ctl & ~MACB_BIT(RE));
+               wmb();
                macb_writel(lp, NCR, ctl | MACB_BIT(RE));
        }
 
index 57eb4e1345cb00a49666d1ff147aa4ef971d3d26..19dc9e25aa72d20e0050f5b3f2080e9704647f71 100644 (file)
@@ -4931,6 +4931,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
         */
        for_each_port(adapter, i) {
                pi = adap2pinfo(adapter, i);
+               adapter->port[i]->dev_port = pi->lport;
                netif_set_real_num_tx_queues(adapter->port[i], pi->nqsets);
                netif_set_real_num_rx_queues(adapter->port[i], pi->nqsets);
 
index 20dec85da63db1fd2d871bf35f10368c5db39ab9..e8139514d32ca5ee2df37167d480681e381e37ae 100644 (file)
@@ -7851,7 +7851,6 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
                        return ret;
 
                memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN);
-               adap->port[i]->dev_port = j;
                j++;
        }
        return 0;
index df1573c4a6597e17845837d59a7e74d8fbad8838..ecf3ccc257bcc4fc81e8cf35647982f8c4186763 100644 (file)
@@ -168,6 +168,7 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN
        CH_PCI_ID_TABLE_FENTRY(0x509a), /* Custom T520-CR */
        CH_PCI_ID_TABLE_FENTRY(0x509b), /* Custom T540-CR LOM */
        CH_PCI_ID_TABLE_FENTRY(0x509c), /* Custom T520-CR*/
+       CH_PCI_ID_TABLE_FENTRY(0x509d), /* Custom T540-CR*/
 
        /* T6 adapters:
         */
index 100b2cc064a34cafe8faac0e16e9ce44aa1a4f95..a37481c04a87b6a16541e1d2786a2357a946d82d 100644 (file)
@@ -2969,6 +2969,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
 
                netdev->netdev_ops = &cxgb4vf_netdev_ops;
                netdev->ethtool_ops = &cxgb4vf_ethtool_ops;
+               netdev->dev_port = pi->port_id;
 
                /*
                 * Initialize the hardware/software state for the port.
index de9f7c97d916d3d8d760282e726cf49f4181a56b..9a161e98152978fcfbafa51a959e214426a90bd9 100644 (file)
@@ -468,6 +468,9 @@ static void ep93xx_free_buffers(struct ep93xx_priv *ep)
        struct device *dev = ep->dev->dev.parent;
        int i;
 
+       if (!ep->descs)
+               return;
+
        for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
                dma_addr_t d;
 
@@ -490,6 +493,7 @@ static void ep93xx_free_buffers(struct ep93xx_priv *ep)
 
        dma_free_coherent(dev, sizeof(struct ep93xx_descs), ep->descs,
                                                        ep->descs_dma_addr);
+       ep->descs = NULL;
 }
 
 static int ep93xx_alloc_buffers(struct ep93xx_priv *ep)
index 1fb5d72392547dcbc116fabe0fa9699de5e9c304..0e74529a42095b311c97dc367c2ba3b20bdfc27c 100644 (file)
@@ -90,7 +90,8 @@ static struct be_cmd_priv_map cmd_priv_map[] = {
        {
                OPCODE_COMMON_SET_HSW_CONFIG,
                CMD_SUBSYSTEM_COMMON,
-               BE_PRIV_DEVCFG | BE_PRIV_VHADM
+               BE_PRIV_DEVCFG | BE_PRIV_VHADM |
+               BE_PRIV_DEVSEC
        },
        {
                OPCODE_COMMON_GET_EXT_FAT_CAPABILITIES,
index c865135f3cb91bcb120e0b91aaba000577689e66..5ea740b4cf14c9db2350b6f46feb70c365e82a21 100644 (file)
@@ -574,6 +574,8 @@ struct fec_enet_private {
        unsigned int reload_period;
        int pps_enable;
        unsigned int next_counter;
+
+       u64 ethtool_stats[0];
 };
 
 void fec_ptp_init(struct platform_device *pdev);
index 5aa9d4ded214cfd96fe9de816593f76298f2d334..12aef1b15356b00ad0139d6cb26f264ace84925d 100644 (file)
@@ -2313,14 +2313,26 @@ static const struct fec_stat {
        { "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK },
 };
 
-static void fec_enet_get_ethtool_stats(struct net_device *dev,
-       struct ethtool_stats *stats, u64 *data)
+#define FEC_STATS_SIZE         (ARRAY_SIZE(fec_stats) * sizeof(u64))
+
+static void fec_enet_update_ethtool_stats(struct net_device *dev)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
        int i;
 
        for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
-               data[i] = readl(fep->hwp + fec_stats[i].offset);
+               fep->ethtool_stats[i] = readl(fep->hwp + fec_stats[i].offset);
+}
+
+static void fec_enet_get_ethtool_stats(struct net_device *dev,
+                                      struct ethtool_stats *stats, u64 *data)
+{
+       struct fec_enet_private *fep = netdev_priv(dev);
+
+       if (netif_running(dev))
+               fec_enet_update_ethtool_stats(dev);
+
+       memcpy(data, fep->ethtool_stats, FEC_STATS_SIZE);
 }
 
 static void fec_enet_get_strings(struct net_device *netdev,
@@ -2345,6 +2357,12 @@ static int fec_enet_get_sset_count(struct net_device *dev, int sset)
                return -EOPNOTSUPP;
        }
 }
+
+#else  /* !defined(CONFIG_M5272) */
+#define FEC_STATS_SIZE 0
+static inline void fec_enet_update_ethtool_stats(struct net_device *dev)
+{
+}
 #endif /* !defined(CONFIG_M5272) */
 
 static int fec_enet_nway_reset(struct net_device *dev)
@@ -2874,6 +2892,8 @@ fec_enet_close(struct net_device *ndev)
        if (fep->quirks & FEC_QUIRK_ERR006687)
                imx6q_cpuidle_fec_irqs_unused();
 
+       fec_enet_update_ethtool_stats(ndev);
+
        fec_enet_clk_enable(ndev, false);
        pinctrl_pm_select_sleep_state(&fep->pdev->dev);
        pm_runtime_mark_last_busy(&fep->pdev->dev);
@@ -3180,6 +3200,8 @@ static int fec_enet_init(struct net_device *ndev)
 
        fec_restart(ndev);
 
+       fec_enet_update_ethtool_stats(ndev);
+
        return 0;
 }
 
@@ -3278,8 +3300,8 @@ fec_probe(struct platform_device *pdev)
        fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs);
 
        /* Init network device */
-       ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private),
-                                 num_tx_qs, num_rx_qs);
+       ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private) +
+                                 FEC_STATS_SIZE, num_tx_qs, num_rx_qs);
        if (!ndev)
                return -ENOMEM;
 
@@ -3475,6 +3497,8 @@ failed_regulator:
 failed_clk_ipg:
        fec_enet_clk_enable(ndev, false);
 failed_clk:
+       if (of_phy_is_fixed_link(np))
+               of_phy_deregister_fixed_link(np);
 failed_phy:
        of_node_put(phy_node);
 failed_ioremap:
@@ -3488,6 +3512,7 @@ fec_drv_remove(struct platform_device *pdev)
 {
        struct net_device *ndev = platform_get_drvdata(pdev);
        struct fec_enet_private *fep = netdev_priv(ndev);
+       struct device_node *np = pdev->dev.of_node;
 
        cancel_work_sync(&fep->tx_timeout_work);
        fec_ptp_stop(pdev);
@@ -3495,6 +3520,8 @@ fec_drv_remove(struct platform_device *pdev)
        fec_enet_mii_remove(fep);
        if (fep->reg_phy)
                regulator_disable(fep->reg_phy);
+       if (of_phy_is_fixed_link(np))
+               of_phy_deregister_fixed_link(np);
        of_node_put(fep->phy_node);
        free_netdev(ndev);
 
index 53ef51e3bd9ef2cb3c5f8100f807399ab36a31d1..71a5ded9d1de0fda2f08c32985cc7661a3af3966 100644 (file)
@@ -1107,6 +1107,9 @@ int memac_free(struct fman_mac *memac)
 {
        free_init_resources(memac);
 
+       if (memac->pcsphy)
+               put_device(&memac->pcsphy->mdio.dev);
+
        kfree(memac->memac_drv_param);
        kfree(memac);
 
index 8fe6b3e253fa436f0cc87bf8702b827f3b6d9a72..736db9d9b0ad0f2d3be32a033b1a2df176826af6 100644 (file)
@@ -892,6 +892,8 @@ static int mac_probe(struct platform_device *_of_dev)
                priv->fixed_link->duplex = phy->duplex;
                priv->fixed_link->pause = phy->pause;
                priv->fixed_link->asym_pause = phy->asym_pause;
+
+               put_device(&phy->mdio.dev);
        }
 
        err = mac_dev->init(mac_dev);
index dc120c148d9766fcf511f100396cb51f4b61a73b..4b86260584a056ead8a46f418d4a8cf52216aaad 100644 (file)
@@ -980,7 +980,7 @@ static int fs_enet_probe(struct platform_device *ofdev)
                err = clk_prepare_enable(clk);
                if (err) {
                        ret = err;
-                       goto out_free_fpi;
+                       goto out_deregister_fixed_link;
                }
                fpi->clk_per = clk;
        }
@@ -1061,6 +1061,9 @@ out_put:
        of_node_put(fpi->phy_node);
        if (fpi->clk_per)
                clk_disable_unprepare(fpi->clk_per);
+out_deregister_fixed_link:
+       if (of_phy_is_fixed_link(ofdev->dev.of_node))
+               of_phy_deregister_fixed_link(ofdev->dev.of_node);
 out_free_fpi:
        kfree(fpi);
        return ret;
@@ -1079,6 +1082,8 @@ static int fs_enet_remove(struct platform_device *ofdev)
        of_node_put(fep->fpi->phy_node);
        if (fep->fpi->clk_per)
                clk_disable_unprepare(fep->fpi->clk_per);
+       if (of_phy_is_fixed_link(ofdev->dev.of_node))
+               of_phy_deregister_fixed_link(ofdev->dev.of_node);
        free_netdev(ndev);
        return 0;
 }
index 4b4f5bc0e2799cdaea3f1be09fc29e07cbb6b559..9061c2f82b9c504ac2df56ebce199fdf23fe503b 100644 (file)
@@ -1312,6 +1312,7 @@ static void gfar_init_addr_hash_table(struct gfar_private *priv)
  */
 static int gfar_probe(struct platform_device *ofdev)
 {
+       struct device_node *np = ofdev->dev.of_node;
        struct net_device *dev = NULL;
        struct gfar_private *priv = NULL;
        int err = 0, i;
@@ -1462,6 +1463,8 @@ static int gfar_probe(struct platform_device *ofdev)
        return 0;
 
 register_fail:
+       if (of_phy_is_fixed_link(np))
+               of_phy_deregister_fixed_link(np);
        unmap_group_regs(priv);
        gfar_free_rx_queues(priv);
        gfar_free_tx_queues(priv);
@@ -1474,11 +1477,16 @@ register_fail:
 static int gfar_remove(struct platform_device *ofdev)
 {
        struct gfar_private *priv = platform_get_drvdata(ofdev);
+       struct device_node *np = ofdev->dev.of_node;
 
        of_node_put(priv->phy_node);
        of_node_put(priv->tbi_node);
 
        unregister_netdev(priv->ndev);
+
+       if (of_phy_is_fixed_link(np))
+               of_phy_deregister_fixed_link(np);
+
        unmap_group_regs(priv);
        gfar_free_rx_queues(priv);
        gfar_free_tx_queues(priv);
index 186ef8f16c802c5b076c41f1568ef582051cb103..f76d3327945465660508af9acdaaac4b5e90a51d 100644 (file)
@@ -3868,9 +3868,8 @@ static int ucc_geth_probe(struct platform_device* ofdev)
        dev = alloc_etherdev(sizeof(*ugeth));
 
        if (dev == NULL) {
-               of_node_put(ug_info->tbi_node);
-               of_node_put(ug_info->phy_node);
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto err_deregister_fixed_link;
        }
 
        ugeth = netdev_priv(dev);
@@ -3907,10 +3906,7 @@ static int ucc_geth_probe(struct platform_device* ofdev)
                if (netif_msg_probe(ugeth))
                        pr_err("%s: Cannot register net device, aborting\n",
                               dev->name);
-               free_netdev(dev);
-               of_node_put(ug_info->tbi_node);
-               of_node_put(ug_info->phy_node);
-               return err;
+               goto err_free_netdev;
        }
 
        mac_addr = of_get_mac_address(np);
@@ -3923,16 +3919,29 @@ static int ucc_geth_probe(struct platform_device* ofdev)
        ugeth->node = np;
 
        return 0;
+
+err_free_netdev:
+       free_netdev(dev);
+err_deregister_fixed_link:
+       if (of_phy_is_fixed_link(np))
+               of_phy_deregister_fixed_link(np);
+       of_node_put(ug_info->tbi_node);
+       of_node_put(ug_info->phy_node);
+
+       return err;
 }
 
 static int ucc_geth_remove(struct platform_device* ofdev)
 {
        struct net_device *dev = platform_get_drvdata(ofdev);
        struct ucc_geth_private *ugeth = netdev_priv(dev);
+       struct device_node *np = ofdev->dev.of_node;
 
        unregister_netdev(dev);
        free_netdev(dev);
        ucc_geth_memclean(ugeth);
+       if (of_phy_is_fixed_link(np))
+               of_phy_deregister_fixed_link(np);
        of_node_put(ugeth->ug_info->tbi_node);
        of_node_put(ugeth->ug_info->phy_node);
 
index ebe60719e489cd1fbdc12248ee48eed6d0979fd4..a36022ba4e4232025483ec937cb894474886706a 100644 (file)
@@ -58,7 +58,7 @@ static struct kobj_type ktype_veth_pool;
 
 static const char ibmveth_driver_name[] = "ibmveth";
 static const char ibmveth_driver_string[] = "IBM Power Virtual Ethernet Driver";
-#define ibmveth_driver_version "1.05"
+#define ibmveth_driver_version "1.06"
 
 MODULE_AUTHOR("Santiago Leon <santil@linux.vnet.ibm.com>");
 MODULE_DESCRIPTION("IBM Power Virtual Ethernet Driver");
@@ -137,6 +137,11 @@ static inline int ibmveth_rxq_frame_offset(struct ibmveth_adapter *adapter)
        return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_OFF_MASK;
 }
 
+static inline int ibmveth_rxq_large_packet(struct ibmveth_adapter *adapter)
+{
+       return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_LRG_PKT;
+}
+
 static inline int ibmveth_rxq_frame_length(struct ibmveth_adapter *adapter)
 {
        return be32_to_cpu(adapter->rx_queue.queue_addr[adapter->rx_queue.index].length);
@@ -1174,6 +1179,45 @@ map_failed:
        goto retry_bounce;
 }
 
+static void ibmveth_rx_mss_helper(struct sk_buff *skb, u16 mss, int lrg_pkt)
+{
+       int offset = 0;
+
+       /* only TCP packets will be aggregated */
+       if (skb->protocol == htons(ETH_P_IP)) {
+               struct iphdr *iph = (struct iphdr *)skb->data;
+
+               if (iph->protocol == IPPROTO_TCP) {
+                       offset = iph->ihl * 4;
+                       skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+               } else {
+                       return;
+               }
+       } else if (skb->protocol == htons(ETH_P_IPV6)) {
+               struct ipv6hdr *iph6 = (struct ipv6hdr *)skb->data;
+
+               if (iph6->nexthdr == IPPROTO_TCP) {
+                       offset = sizeof(struct ipv6hdr);
+                       skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
+               } else {
+                       return;
+               }
+       } else {
+               return;
+       }
+       /* if mss is not set through Large Packet bit/mss in rx buffer,
+        * expect that the mss will be written to the tcp header checksum.
+        */
+       if (lrg_pkt) {
+               skb_shinfo(skb)->gso_size = mss;
+       } else if (offset) {
+               struct tcphdr *tcph = (struct tcphdr *)(skb->data + offset);
+
+               skb_shinfo(skb)->gso_size = ntohs(tcph->check);
+               tcph->check = 0;
+       }
+}
+
 static int ibmveth_poll(struct napi_struct *napi, int budget)
 {
        struct ibmveth_adapter *adapter =
@@ -1182,6 +1226,7 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
        int frames_processed = 0;
        unsigned long lpar_rc;
        struct iphdr *iph;
+       u16 mss = 0;
 
 restart_poll:
        while (frames_processed < budget) {
@@ -1199,9 +1244,21 @@ restart_poll:
                        int length = ibmveth_rxq_frame_length(adapter);
                        int offset = ibmveth_rxq_frame_offset(adapter);
                        int csum_good = ibmveth_rxq_csum_good(adapter);
+                       int lrg_pkt = ibmveth_rxq_large_packet(adapter);
 
                        skb = ibmveth_rxq_get_buffer(adapter);
 
+                       /* if the large packet bit is set in the rx queue
+                        * descriptor, the mss will be written by PHYP eight
+                        * bytes from the start of the rx buffer, which is
+                        * skb->data at this stage
+                        */
+                       if (lrg_pkt) {
+                               __be64 *rxmss = (__be64 *)(skb->data + 8);
+
+                               mss = (u16)be64_to_cpu(*rxmss);
+                       }
+
                        new_skb = NULL;
                        if (length < rx_copybreak)
                                new_skb = netdev_alloc_skb(netdev, length);
@@ -1235,11 +1292,15 @@ restart_poll:
                                        if (iph->check == 0xffff) {
                                                iph->check = 0;
                                                iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
-                                               adapter->rx_large_packets++;
                                        }
                                }
                        }
 
+                       if (length > netdev->mtu + ETH_HLEN) {
+                               ibmveth_rx_mss_helper(skb, mss, lrg_pkt);
+                               adapter->rx_large_packets++;
+                       }
+
                        napi_gro_receive(napi, skb);    /* send it up */
 
                        netdev->stats.rx_packets++;
index 4eade67fe30c32a0c528631b27ab9042bd1d4caf..7acda04d034e909269bf7c75befe125313150870 100644 (file)
@@ -209,6 +209,7 @@ struct ibmveth_rx_q_entry {
 #define IBMVETH_RXQ_TOGGLE             0x80000000
 #define IBMVETH_RXQ_TOGGLE_SHIFT       31
 #define IBMVETH_RXQ_VALID              0x40000000
+#define IBMVETH_RXQ_LRG_PKT            0x04000000
 #define IBMVETH_RXQ_NO_CSUM            0x02000000
 #define IBMVETH_RXQ_CSUM_GOOD          0x01000000
 #define IBMVETH_RXQ_OFF_MASK           0x0000FFFF
index edc9a6ac5169328b3690672b47a699df8dc2d588..9affd7c198bd2350cadf5d96be70e00369e0976c 100644 (file)
@@ -4931,11 +4931,15 @@ static int igb_tso(struct igb_ring *tx_ring,
 
        /* initialize outer IP header fields */
        if (ip.v4->version == 4) {
+               unsigned char *csum_start = skb_checksum_start(skb);
+               unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);
+
                /* IP header will have to cancel out any data that
                 * is not a part of the outer IP header
                 */
-               ip.v4->check = csum_fold(csum_add(lco_csum(skb),
-                                                 csum_unfold(l4.tcp->check)));
+               ip.v4->check = csum_fold(csum_partial(trans_start,
+                                                     csum_start - trans_start,
+                                                     0));
                type_tucmd |= E1000_ADVTXD_TUCMD_IPV4;
 
                ip.v4->tot_len = 0;
index 12bb877df86091f92716f1225e17a6b66bc1a4b4..7dff7f6239cd770766607102ae532c2ed9129ff2 100644 (file)
@@ -1965,11 +1965,15 @@ static int igbvf_tso(struct igbvf_ring *tx_ring,
 
        /* initialize outer IP header fields */
        if (ip.v4->version == 4) {
+               unsigned char *csum_start = skb_checksum_start(skb);
+               unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);
+
                /* IP header will have to cancel out any data that
                 * is not a part of the outer IP header
                 */
-               ip.v4->check = csum_fold(csum_add(lco_csum(skb),
-                                                 csum_unfold(l4.tcp->check)));
+               ip.v4->check = csum_fold(csum_partial(trans_start,
+                                                     csum_start - trans_start,
+                                                     0));
                type_tucmd |= E1000_ADVTXD_TUCMD_IPV4;
 
                ip.v4->tot_len = 0;
index bd93d823cc25eb6808fbe8a2262bbcf5e15af422..fee1f2918eadc1217cbf8fc96b438651c71dd223 100644 (file)
@@ -7277,11 +7277,15 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring,
 
        /* initialize outer IP header fields */
        if (ip.v4->version == 4) {
+               unsigned char *csum_start = skb_checksum_start(skb);
+               unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);
+
                /* IP header will have to cancel out any data that
                 * is not a part of the outer IP header
                 */
-               ip.v4->check = csum_fold(csum_add(lco_csum(skb),
-                                                 csum_unfold(l4.tcp->check)));
+               ip.v4->check = csum_fold(csum_partial(trans_start,
+                                                     csum_start - trans_start,
+                                                     0));
                type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
 
                ip.v4->tot_len = 0;
index 7eaac323404990073439d243e884801bee61db3c..cbf70fe4028a8191118d8c0b41cec7d202042bc2 100644 (file)
@@ -3329,11 +3329,15 @@ static int ixgbevf_tso(struct ixgbevf_ring *tx_ring,
 
        /* initialize outer IP header fields */
        if (ip.v4->version == 4) {
+               unsigned char *csum_start = skb_checksum_start(skb);
+               unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);
+
                /* IP header will have to cancel out any data that
                 * is not a part of the outer IP header
                 */
-               ip.v4->check = csum_fold(csum_add(lco_csum(skb),
-                                                 csum_unfold(l4.tcp->check)));
+               ip.v4->check = csum_fold(csum_partial(trans_start,
+                                                     csum_start - trans_start,
+                                                     0));
                type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
 
                ip.v4->tot_len = 0;
index 91e09d68b7e25ddd720aefdd7a79720e2e02ae4c..a167fd7ee13e0dcb36ce40fa6ba435c1883e348b 100644 (file)
@@ -704,6 +704,7 @@ ltq_etop_probe(struct platform_device *pdev)
        priv->pldata = dev_get_platdata(&pdev->dev);
        priv->netdev = dev;
        spin_lock_init(&priv->lock);
+       SET_NETDEV_DEV(dev, &pdev->dev);
 
        for (i = 0; i < MAX_DMA_CHAN; i++) {
                if (IS_TX(i))
index 0c0a45af950f0978ee352195a3a27a6439b56d7e..707bc4680b9bd37215e2a75bdeac42cf08f31212 100644 (file)
@@ -4191,6 +4191,8 @@ err_clk:
        clk_disable_unprepare(pp->clk);
 err_put_phy_node:
        of_node_put(phy_node);
+       if (of_phy_is_fixed_link(dn))
+               of_phy_deregister_fixed_link(dn);
 err_free_irq:
        irq_dispose_mapping(dev->irq);
 err_free_netdev:
@@ -4202,6 +4204,7 @@ err_free_netdev:
 static int mvneta_remove(struct platform_device *pdev)
 {
        struct net_device  *dev = platform_get_drvdata(pdev);
+       struct device_node *dn = pdev->dev.of_node;
        struct mvneta_port *pp = netdev_priv(dev);
 
        unregister_netdev(dev);
@@ -4209,6 +4212,8 @@ static int mvneta_remove(struct platform_device *pdev)
        clk_disable_unprepare(pp->clk);
        free_percpu(pp->ports);
        free_percpu(pp->stats);
+       if (of_phy_is_fixed_link(dn))
+               of_phy_deregister_fixed_link(dn);
        irq_dispose_mapping(dev->irq);
        of_node_put(pp->phy_node);
        free_netdev(dev);
index 4a62ffd7729d0327f35b16d4a5b4e3dc89adbb01..86a89cbd3ec95c8e01eba987799bbab196c53eaf 100644 (file)
@@ -318,6 +318,8 @@ static int mtk_phy_connect(struct net_device *dev)
        return 0;
 
 err_phy:
+       if (of_phy_is_fixed_link(mac->of_node))
+               of_phy_deregister_fixed_link(mac->of_node);
        of_node_put(np);
        dev_err(eth->dev, "%s: invalid phy\n", __func__);
        return -EINVAL;
@@ -1923,6 +1925,8 @@ static void mtk_uninit(struct net_device *dev)
        struct mtk_eth *eth = mac->hw;
 
        phy_disconnect(dev->phydev);
+       if (of_phy_is_fixed_link(mac->of_node))
+               of_phy_deregister_fixed_link(mac->of_node);
        mtk_irq_disable(eth, MTK_QDMA_INT_MASK, ~0);
        mtk_irq_disable(eth, MTK_PDMA_INT_MASK, ~0);
 }
index a60f635da78b7d1bf16f6c0f05d66c8be824a7dc..fb8bb027b69c3332ef23d4b59f9288103a5b12ba 100644 (file)
@@ -2079,13 +2079,6 @@ err:
        return -ENOMEM;
 }
 
-static void mlx4_en_shutdown(struct net_device *dev)
-{
-       rtnl_lock();
-       netif_device_detach(dev);
-       mlx4_en_close(dev);
-       rtnl_unlock();
-}
 
 static int mlx4_en_copy_priv(struct mlx4_en_priv *dst,
                             struct mlx4_en_priv *src,
@@ -2162,8 +2155,6 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
 {
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_en_dev *mdev = priv->mdev;
-       bool shutdown = mdev->dev->persist->interface_state &
-                                           MLX4_INTERFACE_STATE_SHUTDOWN;
 
        en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
 
@@ -2171,10 +2162,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
        if (priv->registered) {
                devlink_port_type_clear(mlx4_get_devlink_port(mdev->dev,
                                                              priv->port));
-               if (shutdown)
-                       mlx4_en_shutdown(dev);
-               else
-                       unregister_netdev(dev);
+               unregister_netdev(dev);
        }
 
        if (priv->allocated)
@@ -2203,8 +2191,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
        kfree(priv->tx_ring);
        kfree(priv->tx_cq);
 
-       if (!shutdown)
-               free_netdev(dev);
+       free_netdev(dev);
 }
 
 static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
index 6f4e67bc35382e7a0b8de7c0b52cc24b3d81df91..75d07fa9d0b1bb50f595adf9f65cf4dd9b8e4683 100644 (file)
@@ -4147,11 +4147,8 @@ static void mlx4_shutdown(struct pci_dev *pdev)
 
        mlx4_info(persist->dev, "mlx4_shutdown was called\n");
        mutex_lock(&persist->interface_state_mutex);
-       if (persist->interface_state & MLX4_INTERFACE_STATE_UP) {
-               /* Notify mlx4 clients that the kernel is being shut down */
-               persist->interface_state |= MLX4_INTERFACE_STATE_SHUTDOWN;
+       if (persist->interface_state & MLX4_INTERFACE_STATE_UP)
                mlx4_unload_one(pdev);
-       }
        mutex_unlock(&persist->interface_state_mutex);
 }
 
index 94b891c118c135d3597d90ba3ec9a34d049458ee..1a670b68155550fe9f61fb2bc2c7a3688391249c 100644 (file)
@@ -1457,7 +1457,12 @@ EXPORT_SYMBOL_GPL(mlx4_multicast_detach);
 int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port,
                                u32 qpn, enum mlx4_net_trans_promisc_mode mode)
 {
-       struct mlx4_net_trans_rule rule;
+       struct mlx4_net_trans_rule rule = {
+               .queue_mode = MLX4_NET_TRANS_Q_FIFO,
+               .exclusive = 0,
+               .allow_loopback = 1,
+       };
+
        u64 *regid_p;
 
        switch (mode) {
index aae46884bf93c949325e4bba26316cb9f69e078a..521cfdb7d11e75cdf9b4ebca53b55a60b7f72825 100644 (file)
@@ -18,8 +18,6 @@ config MLX5_CORE_EN
        default n
        ---help---
          Ethernet support in Mellanox Technologies ConnectX-4 NIC.
-         Ethernet and Infiniband support in ConnectX-4 are currently mutually
-         exclusive.
 
 config MLX5_CORE_EN_DCB
        bool "Data Center Bridging (DCB) Support"
index 1e639f88602165fcb4f4454cf6a54148372e3235..bfe410e8a469ee06152f36d63cbb68e8656a861d 100644 (file)
@@ -268,11 +268,6 @@ static void dump_buf(void *buf, int size, int data_only, int offset)
                pr_debug("\n");
 }
 
-enum {
-       MLX5_DRIVER_STATUS_ABORTED = 0xfe,
-       MLX5_DRIVER_SYND = 0xbadd00de,
-};
-
 static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
                                       u32 *synd, u8 *status)
 {
index 7a43502a89ccef8cb4a7484b3a2cd6111876d166..71382df59fc09b805755f06d492fb794a0d13383 100644 (file)
@@ -241,7 +241,7 @@ struct mlx5e_tstamp {
 };
 
 enum {
-       MLX5E_RQ_STATE_FLUSH,
+       MLX5E_RQ_STATE_ENABLED,
        MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS,
        MLX5E_RQ_STATE_AM,
 };
@@ -394,7 +394,7 @@ struct mlx5e_sq_dma {
 };
 
 enum {
-       MLX5E_SQ_STATE_FLUSH,
+       MLX5E_SQ_STATE_ENABLED,
        MLX5E_SQ_STATE_BF_ENABLE,
 };
 
index 84e8b250e2af270e8151ef29e03a2f2a85c0de29..246d98ebb58890c33005ba7d7abab5743e1b45d9 100644 (file)
@@ -759,6 +759,7 @@ static int mlx5e_open_rq(struct mlx5e_channel *c,
        if (err)
                goto err_destroy_rq;
 
+       set_bit(MLX5E_RQ_STATE_ENABLED, &rq->state);
        err = mlx5e_modify_rq_state(rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY);
        if (err)
                goto err_disable_rq;
@@ -773,6 +774,7 @@ static int mlx5e_open_rq(struct mlx5e_channel *c,
        return 0;
 
 err_disable_rq:
+       clear_bit(MLX5E_RQ_STATE_ENABLED, &rq->state);
        mlx5e_disable_rq(rq);
 err_destroy_rq:
        mlx5e_destroy_rq(rq);
@@ -782,7 +784,7 @@ err_destroy_rq:
 
 static void mlx5e_close_rq(struct mlx5e_rq *rq)
 {
-       set_bit(MLX5E_RQ_STATE_FLUSH, &rq->state);
+       clear_bit(MLX5E_RQ_STATE_ENABLED, &rq->state);
        napi_synchronize(&rq->channel->napi); /* prevent mlx5e_post_rx_wqes */
        cancel_work_sync(&rq->am.work);
 
@@ -1006,7 +1008,6 @@ static int mlx5e_enable_sq(struct mlx5e_sq *sq, struct mlx5e_sq_param *param)
        MLX5_SET(sqc,  sqc, min_wqe_inline_mode, sq->min_inline_mode);
        MLX5_SET(sqc,  sqc, state,              MLX5_SQC_STATE_RST);
        MLX5_SET(sqc,  sqc, tis_lst_sz, param->type == MLX5E_SQ_ICO ? 0 : 1);
-       MLX5_SET(sqc,  sqc, flush_in_error_en,  1);
 
        MLX5_SET(wq,   wq, wq_type,       MLX5_WQ_TYPE_CYCLIC);
        MLX5_SET(wq,   wq, uar_page,      sq->uar.index);
@@ -1083,6 +1084,7 @@ static int mlx5e_open_sq(struct mlx5e_channel *c,
        if (err)
                goto err_destroy_sq;
 
+       set_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
        err = mlx5e_modify_sq(sq, MLX5_SQC_STATE_RST, MLX5_SQC_STATE_RDY,
                              false, 0);
        if (err)
@@ -1096,6 +1098,7 @@ static int mlx5e_open_sq(struct mlx5e_channel *c,
        return 0;
 
 err_disable_sq:
+       clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
        mlx5e_disable_sq(sq);
 err_destroy_sq:
        mlx5e_destroy_sq(sq);
@@ -1112,7 +1115,7 @@ static inline void netif_tx_disable_queue(struct netdev_queue *txq)
 
 static void mlx5e_close_sq(struct mlx5e_sq *sq)
 {
-       set_bit(MLX5E_SQ_STATE_FLUSH, &sq->state);
+       clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
        /* prevent netif_tx_wake_queue */
        napi_synchronize(&sq->channel->napi);
 
@@ -3092,7 +3095,7 @@ static void mlx5e_tx_timeout(struct net_device *dev)
                if (!netif_xmit_stopped(netdev_get_tx_queue(dev, i)))
                        continue;
                sched_work = true;
-               set_bit(MLX5E_SQ_STATE_FLUSH, &sq->state);
+               clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
                netdev_err(dev, "TX timeout on queue: %d, SQ: 0x%x, CQ: 0x%x, SQ Cons: 0x%x SQ Prod: 0x%x\n",
                           i, sq->sqn, sq->cq.mcq.cqn, sq->cc, sq->pc);
        }
@@ -3147,13 +3150,13 @@ static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog)
        for (i = 0; i < priv->params.num_channels; i++) {
                struct mlx5e_channel *c = priv->channel[i];
 
-               set_bit(MLX5E_RQ_STATE_FLUSH, &c->rq.state);
+               clear_bit(MLX5E_RQ_STATE_ENABLED, &c->rq.state);
                napi_synchronize(&c->napi);
                /* prevent mlx5e_poll_rx_cq from accessing rq->xdp_prog */
 
                old_prog = xchg(&c->rq.xdp_prog, prog);
 
-               clear_bit(MLX5E_RQ_STATE_FLUSH, &c->rq.state);
+               set_bit(MLX5E_RQ_STATE_ENABLED, &c->rq.state);
                /* napi_schedule in case we have missed anything */
                set_bit(MLX5E_CHANNEL_NAPI_SCHED, &c->flags);
                napi_schedule(&c->napi);
index c6de6fba5843e08a2b92e73fc6549369b48096da..33495d88aeb21469861fd2a9e22463cabe75e9b2 100644 (file)
@@ -340,7 +340,7 @@ static inline void mlx5e_post_umr_wqe(struct mlx5e_rq *rq, u16 ix)
        while ((pi = (sq->pc & wq->sz_m1)) > sq->edge) {
                sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_NOP;
                sq->db.ico_wqe[pi].num_wqebbs = 1;
-               mlx5e_send_nop(sq, true);
+               mlx5e_send_nop(sq, false);
        }
 
        wqe = mlx5_wq_cyc_get_wqe(wq, pi);
@@ -412,7 +412,7 @@ void mlx5e_post_rx_mpwqe(struct mlx5e_rq *rq)
 
        clear_bit(MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS, &rq->state);
 
-       if (unlikely(test_bit(MLX5E_RQ_STATE_FLUSH, &rq->state))) {
+       if (unlikely(!test_bit(MLX5E_RQ_STATE_ENABLED, &rq->state))) {
                mlx5e_free_rx_mpwqe(rq, &rq->mpwqe.info[wq->head]);
                return;
        }
@@ -445,7 +445,7 @@ void mlx5e_dealloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix)
 }
 
 #define RQ_CANNOT_POST(rq) \
-       (test_bit(MLX5E_RQ_STATE_FLUSH, &rq->state) || \
+       (!test_bit(MLX5E_RQ_STATE_ENABLED, &rq->state) || \
         test_bit(MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS, &rq->state))
 
 bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq)
@@ -924,7 +924,7 @@ int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget)
        struct mlx5e_sq *xdp_sq = &rq->channel->xdp_sq;
        int work_done = 0;
 
-       if (unlikely(test_bit(MLX5E_RQ_STATE_FLUSH, &rq->state)))
+       if (unlikely(!test_bit(MLX5E_RQ_STATE_ENABLED, &rq->state)))
                return 0;
 
        if (cq->decmprs_left)
index 70a717382357eecc74c766700a6fbad9d17e93dd..cfb68371c397e0b19b231ba2730d4d54179d0fd5 100644 (file)
@@ -409,7 +409,7 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget)
 
        sq = container_of(cq, struct mlx5e_sq, cq);
 
-       if (unlikely(test_bit(MLX5E_SQ_STATE_FLUSH, &sq->state)))
+       if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)))
                return false;
 
        npkts = 0;
index 5703f19a6a2454551d6ddc29d3644fabd52ea3e0..e5c12a732aa1212274943183ed83696ce2606639 100644 (file)
@@ -56,7 +56,7 @@ static void mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
        struct mlx5_cqe64 *cqe;
        u16 sqcc;
 
-       if (unlikely(test_bit(MLX5E_SQ_STATE_FLUSH, &sq->state)))
+       if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)))
                return;
 
        cqe = mlx5e_get_cqe(cq);
@@ -113,7 +113,7 @@ static inline bool mlx5e_poll_xdp_tx_cq(struct mlx5e_cq *cq)
 
        sq = container_of(cq, struct mlx5e_sq, cq);
 
-       if (unlikely(test_bit(MLX5E_SQ_STATE_FLUSH, &sq->state)))
+       if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)))
                return false;
 
        /* sq->cc must be updated only after mlx5_cqwq_update_db_record(),
index 3b7c6a9f2b5fccb22889a5df35c75f50608dd7e0..ada24e103b02ac927362b0aba5050c251a0e644b 100644 (file)
@@ -62,13 +62,13 @@ MODULE_DESCRIPTION("Mellanox Connect-IB, ConnectX-4 core driver");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(DRIVER_VERSION);
 
-int mlx5_core_debug_mask;
-module_param_named(debug_mask, mlx5_core_debug_mask, int, 0644);
+unsigned int mlx5_core_debug_mask;
+module_param_named(debug_mask, mlx5_core_debug_mask, uint, 0644);
 MODULE_PARM_DESC(debug_mask, "debug mask: 1 = dump cmd data, 2 = dump cmd exec time, 3 = both. Default=0");
 
 #define MLX5_DEFAULT_PROF      2
-static int prof_sel = MLX5_DEFAULT_PROF;
-module_param_named(prof_sel, prof_sel, int, 0444);
+static unsigned int prof_sel = MLX5_DEFAULT_PROF;
+module_param_named(prof_sel, prof_sel, uint, 0444);
 MODULE_PARM_DESC(prof_sel, "profile selector. Valid range 0 - 2");
 
 enum {
@@ -732,13 +732,15 @@ static int mlx5_core_set_issi(struct mlx5_core_dev *dev)
                u8 status;
 
                mlx5_cmd_mbox_status(query_out, &status, &syndrome);
-               if (status == MLX5_CMD_STAT_BAD_OP_ERR) {
-                       pr_debug("Only ISSI 0 is supported\n");
-                       return 0;
+               if (!status || syndrome == MLX5_DRIVER_SYND) {
+                       mlx5_core_err(dev, "Failed to query ISSI err(%d) status(%d) synd(%d)\n",
+                                     err, status, syndrome);
+                       return err;
                }
 
-               pr_err("failed to query ISSI err(%d)\n", err);
-               return err;
+               mlx5_core_warn(dev, "Query ISSI is not supported by FW, ISSI is 0\n");
+               dev->issi = 0;
+               return 0;
        }
 
        sup_issi = MLX5_GET(query_issi_out, query_out, supported_issi_dw0);
@@ -752,7 +754,8 @@ static int mlx5_core_set_issi(struct mlx5_core_dev *dev)
                err = mlx5_cmd_exec(dev, set_in, sizeof(set_in),
                                    set_out, sizeof(set_out));
                if (err) {
-                       pr_err("failed to set ISSI=1 err(%d)\n", err);
+                       mlx5_core_err(dev, "Failed to set ISSI to 1 err(%d)\n",
+                                     err);
                        return err;
                }
 
@@ -1227,13 +1230,6 @@ static int init_one(struct pci_dev *pdev,
 
        dev->pdev = pdev;
        dev->event = mlx5_core_event;
-
-       if (prof_sel < 0 || prof_sel >= ARRAY_SIZE(profile)) {
-               mlx5_core_warn(dev,
-                              "selected profile out of range, selecting default (%d)\n",
-                              MLX5_DEFAULT_PROF);
-               prof_sel = MLX5_DEFAULT_PROF;
-       }
        dev->profile = &profile[prof_sel];
 
        INIT_LIST_HEAD(&priv->ctx_list);
@@ -1450,10 +1446,22 @@ static struct pci_driver mlx5_core_driver = {
        .sriov_configure   = mlx5_core_sriov_configure,
 };
 
+static void mlx5_core_verify_params(void)
+{
+       if (prof_sel >= ARRAY_SIZE(profile)) {
+               pr_warn("mlx5_core: WARNING: Invalid module parameter prof_sel %d, valid range 0-%zu, changing back to default(%d)\n",
+                       prof_sel,
+                       ARRAY_SIZE(profile) - 1,
+                       MLX5_DEFAULT_PROF);
+               prof_sel = MLX5_DEFAULT_PROF;
+       }
+}
+
 static int __init init(void)
 {
        int err;
 
+       mlx5_core_verify_params();
        mlx5_register_debugfs();
 
        err = pci_register_driver(&mlx5_core_driver);
index 187662c8ea96d3915d9968b8932a562fa122f845..63b9a0dba88555510300d68e26918465cadbf8f6 100644 (file)
 
 #define MLX5_TOTAL_VPORTS(mdev) (1 + pci_sriov_get_totalvfs(mdev->pdev))
 
-extern int mlx5_core_debug_mask;
+extern uint mlx5_core_debug_mask;
 
 #define mlx5_core_dbg(__dev, format, ...)                              \
-       dev_dbg(&(__dev)->pdev->dev, "%s:%s:%d:(pid %d): " format,      \
-                (__dev)->priv.name, __func__, __LINE__, current->pid,  \
+       dev_dbg(&(__dev)->pdev->dev, "%s:%d:(pid %d): " format,         \
+                __func__, __LINE__, current->pid,                      \
                 ##__VA_ARGS__)
 
 #define mlx5_core_dbg_mask(__dev, mask, format, ...)                   \
@@ -63,8 +63,8 @@ do {                                                                  \
               ##__VA_ARGS__)
 
 #define mlx5_core_warn(__dev, format, ...)                             \
-       dev_warn(&(__dev)->pdev->dev, "%s:%s:%d:(pid %d): " format,     \
-               (__dev)->priv.name, __func__, __LINE__, current->pid,   \
+       dev_warn(&(__dev)->pdev->dev, "%s:%d:(pid %d): " format,        \
+                __func__, __LINE__, current->pid,                      \
                ##__VA_ARGS__)
 
 #define mlx5_core_info(__dev, format, ...)                             \
@@ -75,6 +75,11 @@ enum {
        MLX5_CMD_TIME, /* print command execution time */
 };
 
+enum {
+       MLX5_DRIVER_STATUS_ABORTED = 0xfe,
+       MLX5_DRIVER_SYND = 0xbadd00de,
+};
+
 int mlx5_query_hca_caps(struct mlx5_core_dev *dev);
 int mlx5_query_board_id(struct mlx5_core_dev *dev);
 int mlx5_cmd_init_hca(struct mlx5_core_dev *dev);
index f95385cbbd40248d79513ad083f8c56232b70aee..62ae55bd81b8cc2940d957e6122471e29f92a6ea 100644 (file)
@@ -1730,6 +1730,7 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb)
                                                       mapping))) {
                                DP_NOTICE(cdev,
                                          "Unable to map frag - dropping packet\n");
+                               rc = -ENOMEM;
                                goto err;
                        }
                } else {
index da4e90db4d989a7d9f74c45279ca36cb675b20bc..99a14df28b9634dd8e6fdeb6bc9bce2d219a3e1a 100644 (file)
@@ -212,6 +212,7 @@ int emac_phy_config(struct platform_device *pdev, struct emac_adapter *adpt)
 
                phy_np = of_parse_phandle(np, "phy-handle", 0);
                adpt->phydev = of_phy_find_device(phy_np);
+               of_node_put(phy_np);
        }
 
        if (!adpt->phydev) {
index 4fede4b8653861e88335759f052051e1fda9183d..57b35aeac51a0e33334319f8e5567ede3fd37ba3 100644 (file)
@@ -711,6 +711,8 @@ static int emac_probe(struct platform_device *pdev)
 err_undo_napi:
        netif_napi_del(&adpt->rx_q.napi);
 err_undo_mdiobus:
+       if (!has_acpi_companion(&pdev->dev))
+               put_device(&adpt->phydev->mdio.dev);
        mdiobus_unregister(adpt->mii_bus);
 err_undo_clocks:
        emac_clks_teardown(adpt);
@@ -730,6 +732,8 @@ static int emac_remove(struct platform_device *pdev)
 
        emac_clks_teardown(adpt);
 
+       if (!has_acpi_companion(&pdev->dev))
+               put_device(&adpt->phydev->mdio.dev);
        mdiobus_unregister(adpt->mii_bus);
        free_netdev(netdev);
 
index 630536bc72f975a171bd3ae85d105b6b2ccbbbf1..d6a217874a8bc2f79fe4c255bc43feea611870a5 100644 (file)
@@ -1008,20 +1008,18 @@ static int ravb_phy_init(struct net_device *ndev)
        of_node_put(pn);
        if (!phydev) {
                netdev_err(ndev, "failed to connect PHY\n");
-               return -ENOENT;
+               err = -ENOENT;
+               goto err_deregister_fixed_link;
        }
 
        /* This driver only support 10/100Mbit speeds on Gen3
         * at this time.
         */
        if (priv->chip_id == RCAR_GEN3) {
-               int err;
-
                err = phy_set_max_speed(phydev, SPEED_100);
                if (err) {
                        netdev_err(ndev, "failed to limit PHY to 100Mbit/s\n");
-                       phy_disconnect(phydev);
-                       return err;
+                       goto err_phy_disconnect;
                }
 
                netdev_info(ndev, "limited PHY to 100Mbit/s\n");
@@ -1033,6 +1031,14 @@ static int ravb_phy_init(struct net_device *ndev)
        phy_attached_info(phydev);
 
        return 0;
+
+err_phy_disconnect:
+       phy_disconnect(phydev);
+err_deregister_fixed_link:
+       if (of_phy_is_fixed_link(np))
+               of_phy_deregister_fixed_link(np);
+
+       return err;
 }
 
 /* PHY control start function */
@@ -1634,6 +1640,7 @@ static void ravb_set_rx_mode(struct net_device *ndev)
 /* Device close function for Ethernet AVB */
 static int ravb_close(struct net_device *ndev)
 {
+       struct device_node *np = ndev->dev.parent->of_node;
        struct ravb_private *priv = netdev_priv(ndev);
        struct ravb_tstamp_skb *ts_skb, *ts_skb2;
 
@@ -1663,6 +1670,8 @@ static int ravb_close(struct net_device *ndev)
        if (ndev->phydev) {
                phy_stop(ndev->phydev);
                phy_disconnect(ndev->phydev);
+               if (of_phy_is_fixed_link(np))
+                       of_phy_deregister_fixed_link(np);
        }
 
        if (priv->chip_id != RCAR_GEN2) {
index 05b0dc55de774f486699e066ec24370129b42061..1a92de7051996372975278c0541e1f4c96b8858c 100644 (file)
@@ -518,7 +518,7 @@ static struct sh_eth_cpu_data r7s72100_data = {
 
        .ecsr_value     = ECSR_ICD,
        .ecsipr_value   = ECSIPR_ICDIP,
-       .eesipr_value   = 0xff7f009f,
+       .eesipr_value   = 0xe77f009f,
 
        .tx_check       = EESR_TC1 | EESR_FTC,
        .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
index e9b8579e6241476bd2c82486a0e1a91b2cafcad7..6fb2d15b535132fafce6425666efc01e5c7809d7 100644 (file)
@@ -438,9 +438,16 @@ static int smsc911x_request_resources(struct platform_device *pdev)
        ret = regulator_bulk_get(&pdev->dev,
                        ARRAY_SIZE(pdata->supplies),
                        pdata->supplies);
-       if (ret)
+       if (ret) {
+               /*
+                * Retry on deferrals, else just report the error
+                * and try to continue.
+                */
+               if (ret == -EPROBE_DEFER)
+                       return ret;
                netdev_err(ndev, "couldn't get regulators %d\n",
                                ret);
+       }
 
        /* Request optional RESET GPIO */
        pdata->reset_gpiod = devm_gpiod_get_optional(&pdev->dev,
@@ -2584,6 +2591,9 @@ static int smsc911x_suspend(struct device *dev)
                PMT_CTRL_PM_MODE_D1_ | PMT_CTRL_WOL_EN_ |
                PMT_CTRL_ED_EN_ | PMT_CTRL_PME_EN_);
 
+       pm_runtime_disable(dev);
+       pm_runtime_set_suspended(dev);
+
        return 0;
 }
 
@@ -2593,6 +2603,9 @@ static int smsc911x_resume(struct device *dev)
        struct smsc911x_data *pdata = netdev_priv(ndev);
        unsigned int to = 100;
 
+       pm_runtime_enable(dev);
+       pm_runtime_resume(dev);
+
        /* Note 3.11 from the datasheet:
         *      "When the LAN9220 is in a power saving state, a write of any
         *       data to the BYTE_TEST register will wake-up the device."
index b1e5f24708c923d5b9f4f54924bc1f8c34f64496..e6e6c2fcc4b77b7bffcc8201dc4b64bbbbdd1916 100644 (file)
@@ -50,10 +50,23 @@ static int dwmac_generic_probe(struct platform_device *pdev)
        if (plat_dat->init) {
                ret = plat_dat->init(pdev, plat_dat->bsp_priv);
                if (ret)
-                       return ret;
+                       goto err_remove_config_dt;
        }
 
-       return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       if (ret)
+               goto err_exit;
+
+       return 0;
+
+err_exit:
+       if (plat_dat->exit)
+               plat_dat->exit(pdev, plat_dat->bsp_priv);
+err_remove_config_dt:
+       if (pdev->dev.of_node)
+               stmmac_remove_config_dt(pdev, plat_dat);
+
+       return ret;
 }
 
 static const struct of_device_id dwmac_generic_match[] = {
index 36d3355f2fb00e1ab12dc67813efd7ce5e473251..866444b6c82faa773b622c861bb000e544a05d7a 100644 (file)
@@ -271,15 +271,17 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
                return PTR_ERR(plat_dat);
 
        gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
-       if (!gmac)
-               return -ENOMEM;
+       if (!gmac) {
+               err = -ENOMEM;
+               goto err_remove_config_dt;
+       }
 
        gmac->pdev = pdev;
 
        err = ipq806x_gmac_of_parse(gmac);
        if (err) {
                dev_err(dev, "device tree parsing error\n");
-               return err;
+               goto err_remove_config_dt;
        }
 
        regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
@@ -300,7 +302,8 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
        default:
                dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
                        phy_modes(gmac->phy_mode));
-               return -EINVAL;
+               err = -EINVAL;
+               goto err_remove_config_dt;
        }
        regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
 
@@ -319,7 +322,8 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
        default:
                dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
                        phy_modes(gmac->phy_mode));
-               return -EINVAL;
+               err = -EINVAL;
+               goto err_remove_config_dt;
        }
        regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
 
@@ -346,7 +350,16 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
        plat_dat->bsp_priv = gmac;
        plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
 
-       return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       if (err)
+               goto err_remove_config_dt;
+
+       return 0;
+
+err_remove_config_dt:
+       stmmac_remove_config_dt(pdev, plat_dat);
+
+       return err;
 }
 
 static const struct of_device_id ipq806x_gmac_dwmac_match[] = {
index 78e9d1861896335d86ac31e5701856d9bfe8779b..3d3f43d91b98736003b050937a2b46d2062e9bf9 100644 (file)
@@ -46,7 +46,8 @@ static int lpc18xx_dwmac_probe(struct platform_device *pdev)
        reg = syscon_regmap_lookup_by_compatible("nxp,lpc1850-creg");
        if (IS_ERR(reg)) {
                dev_err(&pdev->dev, "syscon lookup failed\n");
-               return PTR_ERR(reg);
+               ret = PTR_ERR(reg);
+               goto err_remove_config_dt;
        }
 
        if (plat_dat->interface == PHY_INTERFACE_MODE_MII) {
@@ -55,13 +56,23 @@ static int lpc18xx_dwmac_probe(struct platform_device *pdev)
                ethmode = LPC18XX_CREG_CREG6_ETHMODE_RMII;
        } else {
                dev_err(&pdev->dev, "Only MII and RMII mode supported\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_remove_config_dt;
        }
 
        regmap_update_bits(reg, LPC18XX_CREG_CREG6,
                           LPC18XX_CREG_CREG6_ETHMODE_MASK, ethmode);
 
-       return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       if (ret)
+               goto err_remove_config_dt;
+
+       return 0;
+
+err_remove_config_dt:
+       stmmac_remove_config_dt(pdev, plat_dat);
+
+       return ret;
 }
 
 static const struct of_device_id lpc18xx_dwmac_match[] = {
index 309d99536a2c617264167d878a5239b9cdb85865..7fdd1760a74c951a63282db15ab4f9ece2bc8abf 100644 (file)
@@ -64,18 +64,31 @@ static int meson6_dwmac_probe(struct platform_device *pdev)
                return PTR_ERR(plat_dat);
 
        dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
-       if (!dwmac)
-               return -ENOMEM;
+       if (!dwmac) {
+               ret = -ENOMEM;
+               goto err_remove_config_dt;
+       }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
        dwmac->reg = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(dwmac->reg))
-               return PTR_ERR(dwmac->reg);
+       if (IS_ERR(dwmac->reg)) {
+               ret = PTR_ERR(dwmac->reg);
+               goto err_remove_config_dt;
+       }
 
        plat_dat->bsp_priv = dwmac;
        plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed;
 
-       return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       if (ret)
+               goto err_remove_config_dt;
+
+       return 0;
+
+err_remove_config_dt:
+       stmmac_remove_config_dt(pdev, plat_dat);
+
+       return ret;
 }
 
 static const struct of_device_id meson6_dwmac_match[] = {
index 250e4ceafc8dca9c627aeb2a14348c692e438804..ffaed1f35efe0754749a536c563d91937dcb4302 100644 (file)
@@ -264,32 +264,48 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
                return PTR_ERR(plat_dat);
 
        dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
-       if (!dwmac)
-               return -ENOMEM;
+       if (!dwmac) {
+               ret = -ENOMEM;
+               goto err_remove_config_dt;
+       }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
        dwmac->regs = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(dwmac->regs))
-               return PTR_ERR(dwmac->regs);
+       if (IS_ERR(dwmac->regs)) {
+               ret = PTR_ERR(dwmac->regs);
+               goto err_remove_config_dt;
+       }
 
        dwmac->pdev = pdev;
        dwmac->phy_mode = of_get_phy_mode(pdev->dev.of_node);
        if (dwmac->phy_mode < 0) {
                dev_err(&pdev->dev, "missing phy-mode property\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_remove_config_dt;
        }
 
        ret = meson8b_init_clk(dwmac);
        if (ret)
-               return ret;
+               goto err_remove_config_dt;
 
        ret = meson8b_init_prg_eth(dwmac);
        if (ret)
-               return ret;
+               goto err_remove_config_dt;
 
        plat_dat->bsp_priv = dwmac;
 
-       return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       if (ret)
+               goto err_clk_disable;
+
+       return 0;
+
+err_clk_disable:
+       clk_disable_unprepare(dwmac->m25_div_clk);
+err_remove_config_dt:
+       stmmac_remove_config_dt(pdev, plat_dat);
+
+       return ret;
 }
 
 static int meson8b_dwmac_remove(struct platform_device *pdev)
index 3740a4417fa0297c2631a08785dd9345e7cb0371..d80c88bd2bba812123484f9d6b14a373bc33102f 100644 (file)
@@ -981,14 +981,27 @@ static int rk_gmac_probe(struct platform_device *pdev)
        plat_dat->resume = rk_gmac_resume;
 
        plat_dat->bsp_priv = rk_gmac_setup(pdev, data);
-       if (IS_ERR(plat_dat->bsp_priv))
-               return PTR_ERR(plat_dat->bsp_priv);
+       if (IS_ERR(plat_dat->bsp_priv)) {
+               ret = PTR_ERR(plat_dat->bsp_priv);
+               goto err_remove_config_dt;
+       }
 
        ret = rk_gmac_init(pdev, plat_dat->bsp_priv);
        if (ret)
-               return ret;
+               goto err_remove_config_dt;
+
+       ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       if (ret)
+               goto err_gmac_exit;
+
+       return 0;
+
+err_gmac_exit:
+       rk_gmac_exit(pdev, plat_dat->bsp_priv);
+err_remove_config_dt:
+       stmmac_remove_config_dt(pdev, plat_dat);
 
-       return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       return ret;
 }
 
 static const struct of_device_id rk_gmac_dwmac_match[] = {
index bec6963ac71e978e8959fce41607e06ceb955518..0c420e97de1e6693338f0d50174d8c93a47d735c 100644 (file)
@@ -304,6 +304,8 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
        struct device           *dev = &pdev->dev;
        int                     ret;
        struct socfpga_dwmac    *dwmac;
+       struct net_device       *ndev;
+       struct stmmac_priv      *stpriv;
 
        ret = stmmac_get_platform_resources(pdev, &stmmac_res);
        if (ret)
@@ -314,32 +316,43 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
                return PTR_ERR(plat_dat);
 
        dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL);
-       if (!dwmac)
-               return -ENOMEM;
+       if (!dwmac) {
+               ret = -ENOMEM;
+               goto err_remove_config_dt;
+       }
 
        ret = socfpga_dwmac_parse_data(dwmac, dev);
        if (ret) {
                dev_err(dev, "Unable to parse OF data\n");
-               return ret;
+               goto err_remove_config_dt;
        }
 
        plat_dat->bsp_priv = dwmac;
        plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
 
        ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       if (ret)
+               goto err_remove_config_dt;
 
-       if (!ret) {
-               struct net_device *ndev = platform_get_drvdata(pdev);
-               struct stmmac_priv *stpriv = netdev_priv(ndev);
+       ndev = platform_get_drvdata(pdev);
+       stpriv = netdev_priv(ndev);
 
-               /* The socfpga driver needs to control the stmmac reset to
-                * set the phy mode. Create a copy of the core reset handel
-                * so it can be used by the driver later.
-                */
-               dwmac->stmmac_rst = stpriv->stmmac_rst;
+       /* The socfpga driver needs to control the stmmac reset to set the phy
+        * mode. Create a copy of the core reset handle so it can be used by
+        * the driver later.
+        */
+       dwmac->stmmac_rst = stpriv->stmmac_rst;
 
-               ret = socfpga_dwmac_set_phy_mode(dwmac);
-       }
+       ret = socfpga_dwmac_set_phy_mode(dwmac);
+       if (ret)
+               goto err_dvr_remove;
+
+       return 0;
+
+err_dvr_remove:
+       stmmac_dvr_remove(&pdev->dev);
+err_remove_config_dt:
+       stmmac_remove_config_dt(pdev, plat_dat);
 
        return ret;
 }
index 58c05acc2aabbdf63419874605ae11af298471ca..060b98c37a851834f1f1293d67795b9e31ec5a85 100644 (file)
@@ -345,13 +345,15 @@ static int sti_dwmac_probe(struct platform_device *pdev)
                return PTR_ERR(plat_dat);
 
        dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
-       if (!dwmac)
-               return -ENOMEM;
+       if (!dwmac) {
+               ret = -ENOMEM;
+               goto err_remove_config_dt;
+       }
 
        ret = sti_dwmac_parse_data(dwmac, pdev);
        if (ret) {
                dev_err(&pdev->dev, "Unable to parse OF data\n");
-               return ret;
+               goto err_remove_config_dt;
        }
 
        dwmac->fix_retime_src = data->fix_retime_src;
@@ -363,9 +365,20 @@ static int sti_dwmac_probe(struct platform_device *pdev)
 
        ret = sti_dwmac_init(pdev, plat_dat->bsp_priv);
        if (ret)
-               return ret;
+               goto err_remove_config_dt;
+
+       ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       if (ret)
+               goto err_dwmac_exit;
+
+       return 0;
+
+err_dwmac_exit:
+       sti_dwmac_exit(pdev, plat_dat->bsp_priv);
+err_remove_config_dt:
+       stmmac_remove_config_dt(pdev, plat_dat);
 
-       return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       return ret;
 }
 
 static const struct sti_dwmac_of_data stih4xx_dwmac_data = {
index e5a926b8bee7274fc2bd2ce4a60525831e91dce4..61cb24810d101194c5285cf27edd963aa488473f 100644 (file)
@@ -107,24 +107,33 @@ static int stm32_dwmac_probe(struct platform_device *pdev)
                return PTR_ERR(plat_dat);
 
        dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
-       if (!dwmac)
-               return -ENOMEM;
+       if (!dwmac) {
+               ret = -ENOMEM;
+               goto err_remove_config_dt;
+       }
 
        ret = stm32_dwmac_parse_data(dwmac, &pdev->dev);
        if (ret) {
                dev_err(&pdev->dev, "Unable to parse OF data\n");
-               return ret;
+               goto err_remove_config_dt;
        }
 
        plat_dat->bsp_priv = dwmac;
 
        ret = stm32_dwmac_init(plat_dat);
        if (ret)
-               return ret;
+               goto err_remove_config_dt;
 
        ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
        if (ret)
-               stm32_dwmac_clk_disable(dwmac);
+               goto err_clk_disable;
+
+       return 0;
+
+err_clk_disable:
+       stm32_dwmac_clk_disable(dwmac);
+err_remove_config_dt:
+       stmmac_remove_config_dt(pdev, plat_dat);
 
        return ret;
 }
index adff46375a32297ce01a7fdd519483ccc1226012..d07520fb969e687aa6ee5c384c7e23ecf3a8e38a 100644 (file)
@@ -120,22 +120,27 @@ static int sun7i_gmac_probe(struct platform_device *pdev)
                return PTR_ERR(plat_dat);
 
        gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
-       if (!gmac)
-               return -ENOMEM;
+       if (!gmac) {
+               ret = -ENOMEM;
+               goto err_remove_config_dt;
+       }
 
        gmac->interface = of_get_phy_mode(dev->of_node);
 
        gmac->tx_clk = devm_clk_get(dev, "allwinner_gmac_tx");
        if (IS_ERR(gmac->tx_clk)) {
                dev_err(dev, "could not get tx clock\n");
-               return PTR_ERR(gmac->tx_clk);
+               ret = PTR_ERR(gmac->tx_clk);
+               goto err_remove_config_dt;
        }
 
        /* Optional regulator for PHY */
        gmac->regulator = devm_regulator_get_optional(dev, "phy");
        if (IS_ERR(gmac->regulator)) {
-               if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
-                       return -EPROBE_DEFER;
+               if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+                       goto err_remove_config_dt;
+               }
                dev_info(dev, "no regulator found\n");
                gmac->regulator = NULL;
        }
@@ -151,11 +156,18 @@ static int sun7i_gmac_probe(struct platform_device *pdev)
 
        ret = sun7i_gmac_init(pdev, plat_dat->bsp_priv);
        if (ret)
-               return ret;
+               goto err_remove_config_dt;
 
        ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
        if (ret)
-               sun7i_gmac_exit(pdev, plat_dat->bsp_priv);
+               goto err_gmac_exit;
+
+       return 0;
+
+err_gmac_exit:
+       sun7i_gmac_exit(pdev, plat_dat->bsp_priv);
+err_remove_config_dt:
+       stmmac_remove_config_dt(pdev, plat_dat);
 
        return ret;
 }
index 9907469552169094a2fea15812021dde40b4e8e8..f35385266fbf04d595c65b469b14c5abcd7e565c 100644 (file)
@@ -43,9 +43,11 @@ static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
        if (axi->axi_xit_frm)
                value |= DMA_AXI_LPI_XIT_FRM;
 
+       value &= ~DMA_AXI_WR_OSR_LMT;
        value |= (axi->axi_wr_osr_lmt & DMA_AXI_WR_OSR_LMT_MASK) <<
                 DMA_AXI_WR_OSR_LMT_SHIFT;
 
+       value &= ~DMA_AXI_RD_OSR_LMT;
        value |= (axi->axi_rd_osr_lmt & DMA_AXI_RD_OSR_LMT_MASK) <<
                 DMA_AXI_RD_OSR_LMT_SHIFT;
 
index 116151cd6a952378ba8bdc297d8e2e568edabc97..32bc2fc73cdc2b7f228570bdbe4c95760c1f5cc6 100644 (file)
@@ -30,9 +30,11 @@ static void dwmac4_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
        if (axi->axi_xit_frm)
                value |= DMA_AXI_LPI_XIT_FRM;
 
+       value &= ~DMA_AXI_WR_OSR_LMT;
        value |= (axi->axi_wr_osr_lmt & DMA_AXI_OSR_MAX) <<
                 DMA_AXI_WR_OSR_LMT_SHIFT;
 
+       value &= ~DMA_AXI_RD_OSR_LMT;
        value |= (axi->axi_rd_osr_lmt & DMA_AXI_OSR_MAX) <<
                 DMA_AXI_RD_OSR_LMT_SHIFT;
 
index 1f9ec02fa7f856ecf461cc4c5bfa51e7cc79902e..caf069a465f234121315cc39f5f38007791a57ec 100644 (file)
@@ -3416,7 +3416,6 @@ int stmmac_dvr_remove(struct device *dev)
        stmmac_set_mac(priv->ioaddr, false);
        netif_carrier_off(ndev);
        unregister_netdev(ndev);
-       of_node_put(priv->plat->phy_node);
        if (priv->stmmac_rst)
                reset_control_assert(priv->stmmac_rst);
        clk_disable_unprepare(priv->pclk);
index 0a0d6a86f3979d260e2cda42282503e0d50e59ec..ac3d39c69509a72fbe1e094e79f44cf796c93457 100644 (file)
@@ -126,8 +126,10 @@ static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
        axi->axi_mb = of_property_read_bool(np, "snps,axi_mb");
        axi->axi_rb =  of_property_read_bool(np, "snps,axi_rb");
 
-       of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt);
-       of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt);
+       if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt))
+               axi->axi_wr_osr_lmt = 1;
+       if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt))
+               axi->axi_rd_osr_lmt = 1;
        of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
        of_node_put(np);
 
@@ -200,7 +202,6 @@ static int stmmac_dt_phy(struct plat_stmmacenet_data *plat,
 /**
  * stmmac_probe_config_dt - parse device-tree driver parameters
  * @pdev: platform_device structure
- * @plat: driver data platform structure
  * @mac: MAC address to use
  * Description:
  * this function is to read the driver parameters from device-tree and
@@ -306,7 +307,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
                dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
                                       GFP_KERNEL);
                if (!dma_cfg) {
-                       of_node_put(plat->phy_node);
+                       stmmac_remove_config_dt(pdev, plat);
                        return ERR_PTR(-ENOMEM);
                }
                plat->dma_cfg = dma_cfg;
@@ -329,14 +330,37 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
 
        return plat;
 }
+
+/**
+ * stmmac_remove_config_dt - undo the effects of stmmac_probe_config_dt()
+ * @pdev: platform_device structure
+ * @plat: driver data platform structure
+ *
+ * Release resources claimed by stmmac_probe_config_dt().
+ */
+void stmmac_remove_config_dt(struct platform_device *pdev,
+                            struct plat_stmmacenet_data *plat)
+{
+       struct device_node *np = pdev->dev.of_node;
+
+       if (of_phy_is_fixed_link(np))
+               of_phy_deregister_fixed_link(np);
+       of_node_put(plat->phy_node);
+}
 #else
 struct plat_stmmacenet_data *
 stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
 {
        return ERR_PTR(-ENOSYS);
 }
+
+void stmmac_remove_config_dt(struct platform_device *pdev,
+                            struct plat_stmmacenet_data *plat)
+{
+}
 #endif /* CONFIG_OF */
 EXPORT_SYMBOL_GPL(stmmac_probe_config_dt);
+EXPORT_SYMBOL_GPL(stmmac_remove_config_dt);
 
 int stmmac_get_platform_resources(struct platform_device *pdev,
                                  struct stmmac_resources *stmmac_res)
@@ -392,10 +416,13 @@ int stmmac_pltfr_remove(struct platform_device *pdev)
 {
        struct net_device *ndev = platform_get_drvdata(pdev);
        struct stmmac_priv *priv = netdev_priv(ndev);
+       struct plat_stmmacenet_data *plat = priv->plat;
        int ret = stmmac_dvr_remove(&pdev->dev);
 
-       if (priv->plat->exit)
-               priv->plat->exit(pdev, priv->plat->bsp_priv);
+       if (plat->exit)
+               plat->exit(pdev, plat->bsp_priv);
+
+       stmmac_remove_config_dt(pdev, plat);
 
        return ret;
 }
index 64e147f53a9c0cae24a497ea127859580ebde3ad..b72eb0de57b70199c25213ee1b93da856cac22c2 100644 (file)
@@ -23,6 +23,8 @@
 
 struct plat_stmmacenet_data *
 stmmac_probe_config_dt(struct platform_device *pdev, const char **mac);
+void stmmac_remove_config_dt(struct platform_device *pdev,
+                            struct plat_stmmacenet_data *plat);
 
 int stmmac_get_platform_resources(struct platform_device *pdev,
                                  struct stmmac_resources *stmmac_res);
index 4ba2421e625d2f81340c56a0bbb18bcb0f8ad611..97d64bfed465cff42fd463f0d299d2f3e5b7c401 100644 (file)
@@ -2881,7 +2881,7 @@ static int dwceqos_probe(struct platform_device *pdev)
        ret = of_get_phy_mode(lp->pdev->dev.of_node);
        if (ret < 0) {
                dev_err(&lp->pdev->dev, "error in getting phy i/f\n");
-               goto err_out_clk_dis_phy;
+               goto err_out_deregister_fixed_link;
        }
 
        lp->phy_interface = ret;
@@ -2889,14 +2889,14 @@ static int dwceqos_probe(struct platform_device *pdev)
        ret = dwceqos_mii_init(lp);
        if (ret) {
                dev_err(&lp->pdev->dev, "error in dwceqos_mii_init\n");
-               goto err_out_clk_dis_phy;
+               goto err_out_deregister_fixed_link;
        }
 
        ret = dwceqos_mii_probe(ndev);
        if (ret != 0) {
                netdev_err(ndev, "mii_probe fail.\n");
                ret = -ENXIO;
-               goto err_out_clk_dis_phy;
+               goto err_out_deregister_fixed_link;
        }
 
        dwceqos_set_umac_addr(lp, lp->ndev->dev_addr, 0);
@@ -2914,7 +2914,7 @@ static int dwceqos_probe(struct platform_device *pdev)
        if (ret) {
                dev_err(&lp->pdev->dev, "Unable to retrieve DT, error %d\n",
                        ret);
-               goto err_out_clk_dis_phy;
+               goto err_out_deregister_fixed_link;
        }
        dev_info(&lp->pdev->dev, "pdev->id %d, baseaddr 0x%08lx, irq %d\n",
                 pdev->id, ndev->base_addr, ndev->irq);
@@ -2924,7 +2924,7 @@ static int dwceqos_probe(struct platform_device *pdev)
        if (ret) {
                dev_err(&lp->pdev->dev, "Unable to request IRQ %d, error %d\n",
                        ndev->irq, ret);
-               goto err_out_clk_dis_phy;
+               goto err_out_deregister_fixed_link;
        }
 
        if (netif_msg_probe(lp))
@@ -2935,11 +2935,14 @@ static int dwceqos_probe(struct platform_device *pdev)
        ret = register_netdev(ndev);
        if (ret) {
                dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
-                       goto err_out_clk_dis_phy;
+               goto err_out_deregister_fixed_link;
        }
 
        return 0;
 
+err_out_deregister_fixed_link:
+       if (of_phy_is_fixed_link(pdev->dev.of_node))
+               of_phy_deregister_fixed_link(pdev->dev.of_node);
 err_out_clk_dis_phy:
        clk_disable_unprepare(lp->phy_ref_clk);
 err_out_clk_dis_aper:
@@ -2959,8 +2962,11 @@ static int dwceqos_remove(struct platform_device *pdev)
        if (ndev) {
                lp = netdev_priv(ndev);
 
-               if (ndev->phydev)
+               if (ndev->phydev) {
                        phy_disconnect(ndev->phydev);
+                       if (of_phy_is_fixed_link(pdev->dev.of_node))
+                               of_phy_deregister_fixed_link(pdev->dev.of_node);
+               }
                mdiobus_unregister(lp->mii_bus);
                mdiobus_free(lp->mii_bus);
 
index fa0cfda24fd9caaf44d47812d5b1b13a2af73dcf..28097be2ff28340e2010bda5967e9edab8fdc963 100644 (file)
@@ -1113,6 +1113,7 @@ static int cpmac_probe(struct platform_device *pdev)
        if (!dev)
                return -ENOMEM;
 
+       SET_NETDEV_DEV(dev, &pdev->dev);
        platform_set_drvdata(pdev, dev);
        priv = netdev_priv(dev);
 
index ba1e45ff6aaec2ed3dcce6a3a4fc089c3be711d4..18013645e76c8be4a460e50d7edd31abda29900f 100644 (file)
@@ -81,6 +81,7 @@ static void cpsw_gmii_sel_am3352(struct cpsw_phy_sel_priv *priv,
        };
 
        mask = GMII_SEL_MODE_MASK << (slave * 2) | BIT(slave + 6);
+       mask |= BIT(slave + 4);
        mode <<= slave * 2;
 
        if (priv->rmii_clock_external) {
index 58947aae31c7ecba94205838b633d2972d68cee2..b9087b828eff6183b73ba6dfe8c92ec55655b1a9 100644 (file)
@@ -2459,20 +2459,8 @@ static void cpsw_remove_dt(struct platform_device *pdev)
                if (strcmp(slave_node->name, "slave"))
                        continue;
 
-               if (of_phy_is_fixed_link(slave_node)) {
-                       struct phy_device *phydev;
-
-                       phydev = of_phy_find_device(slave_node);
-                       if (phydev) {
-                               fixed_phy_unregister(phydev);
-                               /* Put references taken by
-                                * of_phy_find_device() and
-                                * of_phy_register_fixed_link().
-                                */
-                               phy_device_free(phydev);
-                               phy_device_free(phydev);
-                       }
-               }
+               if (of_phy_is_fixed_link(slave_node))
+                       of_phy_deregister_fixed_link(slave_node);
 
                of_node_put(slave_data->phy_node);
 
@@ -2942,6 +2930,8 @@ static int cpsw_resume(struct device *dev)
        /* Select default pin state */
        pinctrl_pm_select_default_state(dev);
 
+       /* shut up ASSERT_RTNL() warning in netif_set_real_num_tx/rx_queues */
+       rtnl_lock();
        if (cpsw->data.dual_emac) {
                int i;
 
@@ -2953,6 +2943,8 @@ static int cpsw_resume(struct device *dev)
                if (netif_running(ndev))
                        cpsw_ndo_open(ndev);
        }
+       rtnl_unlock();
+
        return 0;
 }
 #endif
index 84fbe5714f8b50edd3902223b02cc42511b20244..481c7bf0395bfcdc3add56da8b01b61432415d81 100644 (file)
@@ -1767,6 +1767,7 @@ static int davinci_emac_try_get_mac(struct platform_device *pdev,
  */
 static int davinci_emac_probe(struct platform_device *pdev)
 {
+       struct device_node *np = pdev->dev.of_node;
        int rc = 0;
        struct resource *res, *res_ctrl;
        struct net_device *ndev;
@@ -1805,7 +1806,7 @@ static int davinci_emac_probe(struct platform_device *pdev)
        if (!pdata) {
                dev_err(&pdev->dev, "no platform data\n");
                rc = -ENODEV;
-               goto no_pdata;
+               goto err_free_netdev;
        }
 
        /* MAC addr and PHY mask , RMII enable info from platform_data */
@@ -1941,6 +1942,10 @@ no_cpdma_chan:
                cpdma_chan_destroy(priv->rxchan);
        cpdma_ctlr_destroy(priv->dma);
 no_pdata:
+       if (of_phy_is_fixed_link(np))
+               of_phy_deregister_fixed_link(np);
+       of_node_put(priv->phy_node);
+err_free_netdev:
        free_netdev(ndev);
        return rc;
 }
@@ -1956,6 +1961,7 @@ static int davinci_emac_remove(struct platform_device *pdev)
 {
        struct net_device *ndev = platform_get_drvdata(pdev);
        struct emac_priv *priv = netdev_priv(ndev);
+       struct device_node *np = pdev->dev.of_node;
 
        dev_notice(&ndev->dev, "DaVinci EMAC: davinci_emac_remove()\n");
 
@@ -1968,6 +1974,8 @@ static int davinci_emac_remove(struct platform_device *pdev)
        unregister_netdev(ndev);
        of_node_put(priv->phy_node);
        pm_runtime_disable(&pdev->dev);
+       if (of_phy_is_fixed_link(np))
+               of_phy_deregister_fixed_link(np);
        free_netdev(ndev);
 
        return 0;
index 42edd7b7902f16125f860fa37d3b1e45d2a4c1a2..8b4822ad27cb0d1c7fb310ca9a076f5d82e61262 100644 (file)
@@ -859,7 +859,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
        struct geneve_dev *geneve = netdev_priv(dev);
        struct geneve_sock *gs4;
        struct rtable *rt = NULL;
-       const struct iphdr *iip; /* interior IP header */
        int err = -EINVAL;
        struct flowi4 fl4;
        __u8 tos, ttl;
@@ -890,8 +889,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
        sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
        skb_reset_mac_header(skb);
 
-       iip = ip_hdr(skb);
-
        if (info) {
                const struct ip_tunnel_key *key = &info->key;
                u8 *opts = NULL;
@@ -911,7 +908,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
                if (unlikely(err))
                        goto tx_error;
 
-               tos = ip_tunnel_ecn_encap(key->tos, iip, skb);
+               tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
                ttl = key->ttl;
                df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
        } else {
@@ -920,7 +917,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
                if (unlikely(err))
                        goto tx_error;
 
-               tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, iip, skb);
+               tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, ip_hdr(skb), skb);
                ttl = geneve->ttl;
                if (!ttl && IN_MULTICAST(ntohl(fl4.daddr)))
                        ttl = 1;
@@ -952,7 +949,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
 {
        struct geneve_dev *geneve = netdev_priv(dev);
        struct dst_entry *dst = NULL;
-       const struct iphdr *iip; /* interior IP header */
        struct geneve_sock *gs6;
        int err = -EINVAL;
        struct flowi6 fl6;
@@ -982,8 +978,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
        sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
        skb_reset_mac_header(skb);
 
-       iip = ip_hdr(skb);
-
        if (info) {
                const struct ip_tunnel_key *key = &info->key;
                u8 *opts = NULL;
@@ -1004,7 +998,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
                if (unlikely(err))
                        goto tx_error;
 
-               prio = ip_tunnel_ecn_encap(key->tos, iip, skb);
+               prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
                ttl = key->ttl;
                label = info->key.label;
        } else {
@@ -1014,7 +1008,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
                        goto tx_error;
 
                prio = ip_tunnel_ecn_encap(ip6_tclass(fl6.flowlabel),
-                                          iip, skb);
+                                          ip_hdr(skb), skb);
                ttl = geneve->ttl;
                if (!ttl && ipv6_addr_is_multicast(&fl6.daddr))
                        ttl = 1;
index f6382150b16a13e7071f4640c548b377023a02b3..c9140c3aeb67d5fc71b3911a8b2ddb51a2ef806a 100644 (file)
                                 NETIF_F_TSO | \
                                 NETIF_F_TSO6 | \
                                 NETIF_F_HW_CSUM)
+
+/* Restrict GSO size to account for NVGRE */
+#define NETVSC_GSO_MAX_SIZE    62768
+
 static int ring_size = 128;
 module_param(ring_size, int, S_IRUGO);
 MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");
@@ -1400,6 +1404,7 @@ static int netvsc_probe(struct hv_device *dev,
        nvdev = net_device_ctx->nvdev;
        netif_set_real_num_tx_queues(net, nvdev->num_chn);
        netif_set_real_num_rx_queues(net, nvdev->num_chn);
+       netif_set_gso_max_size(net, NETVSC_GSO_MAX_SIZE);
 
        ret = register_netdev(net);
        if (ret != 0) {
index f442eb366863e034055c8cf773c9b4b0e287ae87..dfbc4ef6d507b09905f5f9f57717acdebaaa53be 100644 (file)
@@ -497,6 +497,7 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
        struct net_device *phy_dev;
        int err;
        u16 mode = IPVLAN_MODE_L3;
+       bool create = false;
 
        if (!tb[IFLA_LINK])
                return -EINVAL;
@@ -513,6 +514,7 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
                err = ipvlan_port_create(phy_dev);
                if (err < 0)
                        return err;
+               create = true;
        }
 
        if (data && data[IFLA_IPVLAN_MODE])
@@ -536,22 +538,29 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
 
        err = register_netdevice(dev);
        if (err < 0)
-               return err;
+               goto destroy_ipvlan_port;
 
        err = netdev_upper_dev_link(phy_dev, dev);
        if (err) {
-               unregister_netdevice(dev);
-               return err;
+               goto unregister_netdev;
        }
        err = ipvlan_set_port_mode(port, mode);
        if (err) {
-               unregister_netdevice(dev);
-               return err;
+               goto unlink_netdev;
        }
 
        list_add_tail_rcu(&ipvlan->pnode, &port->ipvlans);
        netif_stacked_transfer_operstate(phy_dev, dev);
        return 0;
+
+unlink_netdev:
+       netdev_upper_dev_unlink(phy_dev, dev);
+unregister_netdev:
+       unregister_netdevice(dev);
+destroy_ipvlan_port:
+       if (create)
+               ipvlan_port_destroy(phy_dev);
+       return err;
 }
 
 static void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
index a198946bc54fda6ce8df93c2d4c12b22d32eb117..8716b8c07febf5669b5fe21d78f1b68b4d10ea3f 100644 (file)
@@ -1723,6 +1723,7 @@ static int irda_usb_probe(struct usb_interface *intf,
        /* Don't change this buffer size and allocation without doing
         * some heavy and complete testing. Don't ask why :-(
         * Jean II */
+       ret = -ENOMEM;
        self->speed_buff = kzalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL);
        if (!self->speed_buff)
                goto err_out_3;
index 4e3d2e7c697c76f483eb264b1c5da9244eb434c6..e8c3a8c32534b41d3e44397217da9ae68565b95d 100644 (file)
@@ -518,7 +518,9 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
                
                mtt = irda_get_mtt(skb);
                pr_debug("%s(%ld), mtt=%d\n", __func__ , jiffies, mtt);
-                       if (mtt)
+                       if (mtt > 1000)
+                               mdelay(mtt/1000);
+                       else if (mtt)
                                udelay(mtt);
 
                        /* Enable DMA interrupt */
index 070e3290aa6efea6fcb505cdf0860a4dce676b74..7869b0651576fa6432b9608adb906fc7e1fccd26 100644 (file)
@@ -491,7 +491,13 @@ static int macvtap_newlink(struct net *src_net,
        /* Don't put anything that may fail after macvlan_common_newlink
         * because we can't undo what it does.
         */
-       return macvlan_common_newlink(src_net, dev, tb, data);
+       err = macvlan_common_newlink(src_net, dev, tb, data);
+       if (err) {
+               netdev_rx_handler_unregister(dev);
+               return err;
+       }
+
+       return 0;
 }
 
 static void macvtap_dellink(struct net_device *dev,
@@ -736,13 +742,8 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
 
        if (zerocopy)
                err = zerocopy_sg_from_iter(skb, from);
-       else {
+       else
                err = skb_copy_datagram_from_iter(skb, 0, from, len);
-               if (!err && m && m->msg_control) {
-                       struct ubuf_info *uarg = m->msg_control;
-                       uarg->callback(uarg, false);
-               }
-       }
 
        if (err)
                goto err_kfree;
@@ -773,7 +774,11 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
                skb_shinfo(skb)->destructor_arg = m->msg_control;
                skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
                skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
+       } else if (m && m->msg_control) {
+               struct ubuf_info *uarg = m->msg_control;
+               uarg->callback(uarg, false);
        }
+
        if (vlan) {
                skb->dev = vlan->dev;
                dev_queue_xmit(skb);
index 1a4bf8acad78cb2a901b02520d4802f11e2ad80c..c4ceb082e970e5d2a7d3b8c2c2f75813d52fbcff 100644 (file)
@@ -857,11 +857,17 @@ EXPORT_SYMBOL(phy_attached_print);
 int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
                      u32 flags, phy_interface_t interface)
 {
+       struct module *ndev_owner = dev->dev.parent->driver->owner;
        struct mii_bus *bus = phydev->mdio.bus;
        struct device *d = &phydev->mdio.dev;
        int err;
 
-       if (!try_module_get(bus->owner)) {
+       /* For Ethernet device drivers that register their own MDIO bus, we
+        * will have bus->owner match ndev_mod, so we do not want to increment
+        * our own module->refcnt here, otherwise we would not be able to
+        * unload later on.
+        */
+       if (ndev_owner != bus->owner && !try_module_get(bus->owner)) {
                dev_err(&dev->dev, "failed to get the bus module\n");
                return -EIO;
        }
@@ -921,7 +927,8 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 
 error:
        put_device(d);
-       module_put(bus->owner);
+       if (ndev_owner != bus->owner)
+               module_put(bus->owner);
        return err;
 }
 EXPORT_SYMBOL(phy_attach_direct);
@@ -971,6 +978,8 @@ EXPORT_SYMBOL(phy_attach);
  */
 void phy_detach(struct phy_device *phydev)
 {
+       struct net_device *dev = phydev->attached_dev;
+       struct module *ndev_owner = dev->dev.parent->driver->owner;
        struct mii_bus *bus;
        int i;
 
@@ -998,7 +1007,8 @@ void phy_detach(struct phy_device *phydev)
        bus = phydev->mdio.bus;
 
        put_device(&phydev->mdio.dev);
-       module_put(bus->owner);
+       if (ndev_owner != bus->owner)
+               module_put(bus->owner);
 }
 EXPORT_SYMBOL(phy_detach);
 
index aadd6e9f54adc5b2bb9947dd8ad4ac2f5fffda5f..9cbe645e3d89c98ca5c7974f2d0e39016e71cfa8 100644 (file)
@@ -102,15 +102,19 @@ static int rtl8211f_config_init(struct phy_device *phydev)
        if (ret < 0)
                return ret;
 
-       if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
-               /* enable TXDLY */
-               phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
-               reg = phy_read(phydev, 0x11);
+       phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
+       reg = phy_read(phydev, 0x11);
+
+       /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
+       if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+           phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
                reg |= RTL8211F_TX_DELAY;
-               phy_write(phydev, 0x11, reg);
-               /* restore to default page 0 */
-               phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
-       }
+       else
+               reg &= ~RTL8211F_TX_DELAY;
+
+       phy_write(phydev, 0x11, reg);
+       /* restore to default page 0 */
+       phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
 
        return 0;
 }
index 8093e39ae263a7bd954682125221189499206b7c..db6acecabeaa3f51344ffc366ec0a502da4fea08 100644 (file)
@@ -1246,13 +1246,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 
        if (zerocopy)
                err = zerocopy_sg_from_iter(skb, from);
-       else {
+       else
                err = skb_copy_datagram_from_iter(skb, 0, from, len);
-               if (!err && msg_control) {
-                       struct ubuf_info *uarg = msg_control;
-                       uarg->callback(uarg, false);
-               }
-       }
 
        if (err) {
                this_cpu_inc(tun->pcpu_stats->rx_dropped);
@@ -1298,6 +1293,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
                skb_shinfo(skb)->destructor_arg = msg_control;
                skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
                skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
+       } else if (msg_control) {
+               struct ubuf_info *uarg = msg_control;
+               uarg->callback(uarg, false);
        }
 
        skb_reset_network_header(skb);
index cce24950a0ab65f795230b5d5fa08d09e69dd139..dc7b6392e75ab19bf72dc4b2f330b38d97c7e38b 100644 (file)
@@ -603,12 +603,12 @@ static void ax88772_suspend(struct usbnet *dev)
        u16 medium;
 
        /* Stop MAC operation */
-       medium = asix_read_medium_status(dev, 0);
+       medium = asix_read_medium_status(dev, 1);
        medium &= ~AX_MEDIUM_RE;
-       asix_write_medium_mode(dev, medium, 0);
+       asix_write_medium_mode(dev, medium, 1);
 
        netdev_dbg(dev->net, "ax88772_suspend: medium=0x%04x\n",
-                  asix_read_medium_status(dev, 0));
+                  asix_read_medium_status(dev, 1));
 
        /* Preserve BMCR for restoring */
        priv->presvd_phy_bmcr =
index c47ec0a04c8e5f9ff4d77cf8fade7717ca9cdb75..dd623f6744875969e7eb657612ab1a85b85689eb 100644 (file)
@@ -388,12 +388,6 @@ void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
        case USB_CDC_NOTIFY_NETWORK_CONNECTION:
                netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
                          event->wValue ? "on" : "off");
-
-               /* Work-around for devices with broken off-notifications */
-               if (event->wValue &&
-                   !test_bit(__LINK_STATE_NOCARRIER, &dev->net->state))
-                       usbnet_link_change(dev, 0, 0);
-
                usbnet_link_change(dev, !!event->wValue, 0);
                break;
        case USB_CDC_NOTIFY_SPEED_CHANGE:       /* tx/rx rates */
@@ -466,6 +460,36 @@ static int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
        return 1;
 }
 
+/* Ensure correct link state
+ *
+ * Some devices (ZTE MF823/831/910) export two carrier on notifications when
+ * connected. This causes the link state to be incorrect. Work around this by
+ * always setting the state to off, then on.
+ */
+void usbnet_cdc_zte_status(struct usbnet *dev, struct urb *urb)
+{
+       struct usb_cdc_notification *event;
+
+       if (urb->actual_length < sizeof(*event))
+               return;
+
+       event = urb->transfer_buffer;
+
+       if (event->bNotificationType != USB_CDC_NOTIFY_NETWORK_CONNECTION) {
+               usbnet_cdc_status(dev, urb);
+               return;
+       }
+
+       netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
+                 event->wValue ? "on" : "off");
+
+       if (event->wValue &&
+           netif_carrier_ok(dev->net))
+               netif_carrier_off(dev->net);
+
+       usbnet_link_change(dev, !!event->wValue, 0);
+}
+
 static const struct driver_info        cdc_info = {
        .description =  "CDC Ethernet Device",
        .flags =        FLAG_ETHER | FLAG_POINTTOPOINT,
@@ -481,7 +505,7 @@ static const struct driver_info     zte_cdc_info = {
        .flags =        FLAG_ETHER | FLAG_POINTTOPOINT,
        .bind =         usbnet_cdc_zte_bind,
        .unbind =       usbnet_cdc_unbind,
-       .status =       usbnet_cdc_status,
+       .status =       usbnet_cdc_zte_status,
        .set_rx_mode =  usbnet_cdc_update_filter,
        .manage_power = usbnet_manage_power,
        .rx_fixup = usbnet_cdc_zte_rx_fixup,
index 96a5028621c8b320c2d6feca5911f40cde10771e..3a98f3762a4c81debc023d04b9c01876c6cbdc5f 100644 (file)
@@ -602,6 +602,21 @@ static const struct driver_info cdc_mbim_info_ndp_to_end = {
        .data = CDC_NCM_FLAG_NDP_TO_END,
 };
 
+/* Some modems (e.g. Telit LE922A6) do not work properly with altsetting
+ * toggle done in cdc_ncm_bind_common. CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE
+ * flag is used to avoid this procedure.
+ */
+static const struct driver_info cdc_mbim_info_avoid_altsetting_toggle = {
+       .description = "CDC MBIM",
+       .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN,
+       .bind = cdc_mbim_bind,
+       .unbind = cdc_mbim_unbind,
+       .manage_power = cdc_mbim_manage_power,
+       .rx_fixup = cdc_mbim_rx_fixup,
+       .tx_fixup = cdc_mbim_tx_fixup,
+       .data = CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE,
+};
+
 static const struct usb_device_id mbim_devs[] = {
        /* This duplicate NCM entry is intentional. MBIM devices can
         * be disguised as NCM by default, and this is necessary to
@@ -626,6 +641,12 @@ static const struct usb_device_id mbim_devs[] = {
        { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
          .driver_info = (unsigned long)&cdc_mbim_info_ndp_to_end,
        },
+
+       /* Telit LE922A6 in MBIM composition */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1041, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
+         .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
+       },
+
        /* default entry */
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
          .driver_info = (unsigned long)&cdc_mbim_info_zlp,
index 877c9516e78174dc41bd1e9d3f4c506d193134a9..afbfc0f656f331e82d4c8a528134ff892e2a8635 100644 (file)
@@ -839,11 +839,18 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
 
        iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
 
+       /* Device-specific flags */
+       ctx->drvflags = drvflags;
+
        /* Reset data interface. Some devices will not reset properly
         * unless they are configured first.  Toggle the altsetting to
-        * force a reset
+        * force a reset.
+        * Some other devices do not work properly with this procedure
+        * that can be avoided using quirk CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE
         */
-       usb_set_interface(dev->udev, iface_no, data_altsetting);
+       if (!(ctx->drvflags & CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE))
+               usb_set_interface(dev->udev, iface_no, data_altsetting);
+
        temp = usb_set_interface(dev->udev, iface_no, 0);
        if (temp) {
                dev_dbg(&intf->dev, "set interface failed\n");
@@ -890,9 +897,6 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
        /* finish setting up the device specific data */
        cdc_ncm_setup(dev);
 
-       /* Device-specific flags */
-       ctx->drvflags = drvflags;
-
        /* Allocate the delayed NDP if needed. */
        if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) {
                ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL);
index db558b8b32fe5ba7f9fb71129d41cf806b6c08f4..f33460cec79f394238e8f489453d19d722245009 100644 (file)
@@ -3395,6 +3395,7 @@ static int lan78xx_probe(struct usb_interface *intf,
        if (buf) {
                dev->urb_intr = usb_alloc_urb(0, GFP_KERNEL);
                if (!dev->urb_intr) {
+                       ret = -ENOMEM;
                        kfree(buf);
                        goto out3;
                } else {
index 3ff76c6db4f6d7d8bf7e5baee03cdbcf38976d76..6fe1cdb0174f6cf91f8445dbe86a3e977d327255 100644 (file)
@@ -894,6 +894,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)},    /* Alcatel L800MA */
        {QMI_FIXED_INTF(0x2357, 0x0201, 4)},    /* TP-LINK HSUPA Modem MA180 */
        {QMI_FIXED_INTF(0x2357, 0x9000, 4)},    /* TP-LINK MA260 */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */
        {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},    /* Telit LE920 */
        {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)},    /* Telit LE920 */
        {QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)},    /* XS Stick W100-2 from 4G Systems */
index 7276d5a95bd0ee417a0051990dcb86824e2523d2..cbf1c613c67aefc48692079a5f11f64c34728fa5 100644 (file)
@@ -969,12 +969,17 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p)
        struct virtnet_info *vi = netdev_priv(dev);
        struct virtio_device *vdev = vi->vdev;
        int ret;
-       struct sockaddr *addr = p;
+       struct sockaddr *addr;
        struct scatterlist sg;
 
-       ret = eth_prepare_mac_addr_change(dev, p);
+       addr = kmalloc(sizeof(*addr), GFP_KERNEL);
+       if (!addr)
+               return -ENOMEM;
+       memcpy(addr, p, sizeof(*addr));
+
+       ret = eth_prepare_mac_addr_change(dev, addr);
        if (ret)
-               return ret;
+               goto out;
 
        if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR)) {
                sg_init_one(&sg, addr->sa_data, dev->addr_len);
@@ -982,7 +987,8 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p)
                                          VIRTIO_NET_CTRL_MAC_ADDR_SET, &sg)) {
                        dev_warn(&vdev->dev,
                                 "Failed to set mac address by vq command.\n");
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto out;
                }
        } else if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC) &&
                   !virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
@@ -996,8 +1002,11 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p)
        }
 
        eth_commit_mac_addr_change(dev, p);
+       ret = 0;
 
-       return 0;
+out:
+       kfree(addr);
+       return ret;
 }
 
 static struct rtnl_link_stats64 *virtnet_stats(struct net_device *dev,
index 24532cdebb009a8b1f754af68e4a4f597b020744..2ba01ca02c9c5ed7f8024cbe7370127a3cb33a4c 100644 (file)
@@ -611,6 +611,7 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
        struct vxlan_rdst *rd = NULL;
        struct vxlan_fdb *f;
        int notify = 0;
+       int rc;
 
        f = __vxlan_find_mac(vxlan, mac);
        if (f) {
@@ -641,8 +642,7 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
                if ((flags & NLM_F_APPEND) &&
                    (is_multicast_ether_addr(f->eth_addr) ||
                     is_zero_ether_addr(f->eth_addr))) {
-                       int rc = vxlan_fdb_append(f, ip, port, vni, ifindex,
-                                                 &rd);
+                       rc = vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
 
                        if (rc < 0)
                                return rc;
@@ -673,7 +673,11 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
                INIT_LIST_HEAD(&f->remotes);
                memcpy(f->eth_addr, mac, ETH_ALEN);
 
-               vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
+               rc = vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
+               if (rc < 0) {
+                       kfree(f);
+                       return rc;
+               }
 
                ++vxlan->addrcnt;
                hlist_add_head_rcu(&f->hlist,
index 39ce76ad00bc052d9dc99d5f1162842dc2dc2f3a..16241d21727bf35214ae41424d6b201520471ef2 100644 (file)
@@ -2222,8 +2222,9 @@ done:
                        is_scanning_required = 1;
                } else {
                        mwifiex_dbg(priv->adapter, MSG,
-                                   "info: trying to associate to '%s' bssid %pM\n",
-                                   (char *)req_ssid.ssid, bss->bssid);
+                                   "info: trying to associate to '%.*s' bssid %pM\n",
+                                   req_ssid.ssid_len, (char *)req_ssid.ssid,
+                                   bss->bssid);
                        memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
                        break;
                }
@@ -2283,8 +2284,8 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
        }
 
        mwifiex_dbg(adapter, INFO,
-                   "info: Trying to associate to %s and bssid %pM\n",
-                   (char *)sme->ssid, sme->bssid);
+                   "info: Trying to associate to %.*s and bssid %pM\n",
+                   (int)sme->ssid_len, (char *)sme->ssid, sme->bssid);
 
        if (!mwifiex_stop_bg_scan(priv))
                cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy);
@@ -2417,8 +2418,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
        }
 
        mwifiex_dbg(priv->adapter, MSG,
-                   "info: trying to join to %s and bssid %pM\n",
-                   (char *)params->ssid, params->bssid);
+                   "info: trying to join to %.*s and bssid %pM\n",
+                   params->ssid_len, (char *)params->ssid, params->bssid);
 
        mwifiex_set_ibss_params(priv, params);
 
index a8b6949a8778835a89cef3469f031b77956d0c45..23d4a1728cdfa4993903b6b4504c6a70f5a7fff4 100644 (file)
@@ -715,7 +715,7 @@ EXPORT_SYMBOL_GPL(nd_cmd_in_size);
 
 u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
                const struct nd_cmd_desc *desc, int idx, const u32 *in_field,
-               const u32 *out_field)
+               const u32 *out_field, unsigned long remainder)
 {
        if (idx >= desc->out_num)
                return UINT_MAX;
@@ -727,9 +727,24 @@ u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
                return in_field[1];
        else if (nvdimm && cmd == ND_CMD_VENDOR && idx == 2)
                return out_field[1];
-       else if (!nvdimm && cmd == ND_CMD_ARS_STATUS && idx == 2)
-               return out_field[1] - 8;
-       else if (cmd == ND_CMD_CALL) {
+       else if (!nvdimm && cmd == ND_CMD_ARS_STATUS && idx == 2) {
+               /*
+                * Per table 9-276 ARS Data in ACPI 6.1, out_field[1] is
+                * "Size of Output Buffer in bytes, including this
+                * field."
+                */
+               if (out_field[1] < 4)
+                       return 0;
+               /*
+                * ACPI 6.1 is ambiguous if 'status' is included in the
+                * output size. If we encounter an output size that
+                * overshoots the remainder by 4 bytes, assume it was
+                * including 'status'.
+                */
+               if (out_field[1] - 8 == remainder)
+                       return remainder;
+               return out_field[1] - 4;
+       } else if (cmd == ND_CMD_CALL) {
                struct nd_cmd_pkg *pkg = (struct nd_cmd_pkg *) in_field;
 
                return pkg->nd_size_out;
@@ -876,7 +891,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
        /* process an output envelope */
        for (i = 0; i < desc->out_num; i++) {
                u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i,
-                               (u32 *) in_env, (u32 *) out_env);
+                               (u32 *) in_env, (u32 *) out_env, 0);
                u32 copy;
 
                if (out_size == UINT_MAX) {
index 5a3145a025470dc4c86f8d191a139a8acb85394f..262281bd68fa3c4d39e13f52eeafea1948d1bd22 100644 (file)
@@ -490,3 +490,18 @@ int of_phy_register_fixed_link(struct device_node *np)
        return -ENODEV;
 }
 EXPORT_SYMBOL(of_phy_register_fixed_link);
+
+void of_phy_deregister_fixed_link(struct device_node *np)
+{
+       struct phy_device *phydev;
+
+       phydev = of_phy_find_device(np);
+       if (!phydev)
+               return;
+
+       fixed_phy_unregister(phydev);
+
+       put_device(&phydev->mdio.dev);  /* of_phy_find_device() */
+       phy_device_free(phydev);        /* fixed_phy_register() */
+}
+EXPORT_SYMBOL(of_phy_deregister_fixed_link);
index 8df6312ed3000a9c0587f318416e20f2329f55cc..1a02038c464021b9580a37e2ee70b71a365ecc28 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
  *
- * Authors: Joao Pinto <jpmpinto@gmail.com>
+ * Authors: Joao Pinto <Joao.Pinto@synopsys.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
index db553dc22c8e0fca49ad98ff2f9fd3111e18918a..2b6a59266689b486c9fe42355af77868086a35b1 100644 (file)
@@ -307,20 +307,6 @@ out:
        return 0;
 }
 
-static struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
-{
-       while (1) {
-               if (!pci_is_pcie(dev))
-                       break;
-               if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
-                       return dev;
-               if (!dev->bus->self)
-                       break;
-               dev = dev->bus->self;
-       }
-       return NULL;
-}
-
 static int find_aer_device_iter(struct device *device, void *data)
 {
        struct pcie_device **result = data;
index ab002671fa60e14b83568a24d2cf504687f391f9..104c46d531218874044775b19e68f2ba85c85714 100644 (file)
@@ -1439,6 +1439,21 @@ static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp)
                dev_warn(&dev->dev, "PCI-X settings not supported\n");
 }
 
+static bool pcie_root_rcb_set(struct pci_dev *dev)
+{
+       struct pci_dev *rp = pcie_find_root_port(dev);
+       u16 lnkctl;
+
+       if (!rp)
+               return false;
+
+       pcie_capability_read_word(rp, PCI_EXP_LNKCTL, &lnkctl);
+       if (lnkctl & PCI_EXP_LNKCTL_RCB)
+               return true;
+
+       return false;
+}
+
 static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
 {
        int pos;
@@ -1468,9 +1483,20 @@ 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 (pcie_cap_has_lnkctl(dev))
+       if (pcie_cap_has_lnkctl(dev)) {
+
+               /*
+                * If the Root Port supports Read Completion Boundary of
+                * 128, set RCB to 128.  Otherwise, clear it.
+                */
+               hpp->pci_exp_lnkctl_and |= PCI_EXP_LNKCTL_RCB;
+               hpp->pci_exp_lnkctl_or &= ~PCI_EXP_LNKCTL_RCB;
+               if (pcie_root_rcb_set(dev))
+                       hpp->pci_exp_lnkctl_or |= PCI_EXP_LNKCTL_RCB;
+
                pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
                        ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or);
+       }
 
        /* Find Advanced Error Reporting Enhanced Capability */
        pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
index 01b6d3f9b8fb32aa9877aabbc943bc01abed61d6..56bce1908be2f3af91f5d675667ca02e313e324b 100644 (file)
@@ -143,7 +143,7 @@ static int rockchip_iodomain_notify(struct notifier_block *nb,
        if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
                return NOTIFY_BAD;
 
-       dev_info(supply->iod->dev, "Setting to %d done\n", uV);
+       dev_dbg(supply->iod->dev, "Setting to %d done\n", uV);
        return NOTIFY_OK;
 }
 
index 381871b2bb46ba3439b4ca4bb7ace7277233b372..9d5bd7d5c610b1736eb5698b3b410de6f2c746ed 100644 (file)
@@ -474,6 +474,7 @@ static int meson_pwm_probe(struct platform_device *pdev)
        if (IS_ERR(meson->base))
                return PTR_ERR(meson->base);
 
+       spin_lock_init(&meson->lock);
        meson->chip.dev = &pdev->dev;
        meson->chip.ops = &meson_pwm_ops;
        meson->chip.base = -1;
index 0296d8178ae29d509306670c9bb85147c50f0633..a813239300c3d46bba1320caac77ec7adc8363a8 100644 (file)
@@ -425,6 +425,8 @@ void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
                if (test_bit(PWMF_EXPORTED, &pwm->flags))
                        pwm_unexport_child(parent, pwm);
        }
+
+       put_device(parent);
 }
 
 static int __init pwm_sysfs_init(void)
index aebc4ddb3060ee177c06ec9f11b62a021c346f10..ac05317bba7f3342d016e581b91ae6feffa18eff 100644 (file)
@@ -1083,7 +1083,7 @@ unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba)
        nonemb_cmd = &phba->boot_struct.nonemb_cmd;
        nonemb_cmd->size = sizeof(*resp);
        nonemb_cmd->va = pci_alloc_consistent(phba->ctrl.pdev,
-                                             sizeof(nonemb_cmd->size),
+                                             nonemb_cmd->size,
                                              &nonemb_cmd->dma);
        if (!nonemb_cmd->va) {
                mutex_unlock(&ctrl->mbox_lock);
index d007ec18179af9789a12e6ca7c9f5878374dc593..a1d6ab76a51418f9a4f26ecbb76529ea1b775835 100644 (file)
@@ -2009,7 +2009,7 @@ static struct hpsa_scsi_dev_t *lookup_hpsa_scsi_dev(struct ctlr_info *h,
 
 static int hpsa_slave_alloc(struct scsi_device *sdev)
 {
-       struct hpsa_scsi_dev_t *sd;
+       struct hpsa_scsi_dev_t *sd = NULL;
        unsigned long flags;
        struct ctlr_info *h;
 
@@ -2026,7 +2026,8 @@ static int hpsa_slave_alloc(struct scsi_device *sdev)
                        sd->target = sdev_id(sdev);
                        sd->lun = sdev->lun;
                }
-       } else
+       }
+       if (!sd)
                sd = lookup_hpsa_scsi_dev(h, sdev_channel(sdev),
                                        sdev_id(sdev), sdev->lun);
 
@@ -3840,6 +3841,7 @@ static int hpsa_update_device_info(struct ctlr_info *h,
                sizeof(this_device->vendor));
        memcpy(this_device->model, &inq_buff[16],
                sizeof(this_device->model));
+       this_device->rev = inq_buff[2];
        memset(this_device->device_id, 0,
                sizeof(this_device->device_id));
        if (hpsa_get_device_id(h, scsi3addr, this_device->device_id, 8,
@@ -3929,10 +3931,14 @@ static void figure_bus_target_lun(struct ctlr_info *h,
 
        if (!is_logical_dev_addr_mode(lunaddrbytes)) {
                /* physical device, target and lun filled in later */
-               if (is_hba_lunid(lunaddrbytes))
+               if (is_hba_lunid(lunaddrbytes)) {
+                       int bus = HPSA_HBA_BUS;
+
+                       if (!device->rev)
+                               bus = HPSA_LEGACY_HBA_BUS;
                        hpsa_set_bus_target_lun(device,
-                                       HPSA_HBA_BUS, 0, lunid & 0x3fff);
-               else
+                                       bus, 0, lunid & 0x3fff);
+               else
                        /* defer target, lun assignment for physical devices */
                        hpsa_set_bus_target_lun(device,
                                        HPSA_PHYSICAL_DEVICE_BUS, -1, -1);
index 82cdfad874f3aa363d4989837d2b9455c8e0acdb..9ea162de80dcfa976b737cf209c4570de6003888 100644 (file)
@@ -69,6 +69,7 @@ struct hpsa_scsi_dev_t {
        u64 sas_address;
        unsigned char vendor[8];        /* bytes 8-15 of inquiry data */
        unsigned char model[16];        /* bytes 16-31 of inquiry data */
+       unsigned char rev;              /* byte 2 of inquiry data */
        unsigned char raid_level;       /* from inquiry page 0xC1 */
        unsigned char volume_offline;   /* discovered via TUR or VPD */
        u16 queue_depth;                /* max queue_depth for this device */
@@ -402,6 +403,7 @@ struct offline_device_entry {
 #define HPSA_RAID_VOLUME_BUS           1
 #define HPSA_EXTERNAL_RAID_VOLUME_BUS  2
 #define HPSA_HBA_BUS                   0
+#define HPSA_LEGACY_HBA_BUS            3
 
 /*
        Send the command to the hardware
index 04ce7cfb6d1b6272d26ce138a9b11ee952a20d6f..50c71678a156e8f32d833575de49379e5cd3a151 100644 (file)
@@ -308,7 +308,7 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
        fc_stats = &lport->host_stats;
        memset(fc_stats, 0, sizeof(struct fc_host_statistics));
 
-       fc_stats->seconds_since_last_reset = (lport->boot_time - jiffies) / HZ;
+       fc_stats->seconds_since_last_reset = (jiffies - lport->boot_time) / HZ;
 
        for_each_possible_cpu(cpu) {
                struct fc_stats *stats;
index c5326055beee15bd9937f02c09e9f74aeec1fe6e..f4f77c5b0c83da0520eb868b79095f836179cecf 100644 (file)
@@ -1323,18 +1323,20 @@ lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 {
        lockdep_assert_held(&phba->hbalock);
 
-       BUG_ON(!piocb || !piocb->vport);
+       BUG_ON(!piocb);
 
        list_add_tail(&piocb->list, &pring->txcmplq);
        piocb->iocb_flag |= LPFC_IO_ON_TXCMPLQ;
 
        if ((unlikely(pring->ringno == LPFC_ELS_RING)) &&
           (piocb->iocb.ulpCommand != CMD_ABORT_XRI_CN) &&
-          (piocb->iocb.ulpCommand != CMD_CLOSE_XRI_CN) &&
-           (!(piocb->vport->load_flag & FC_UNLOADING)))
-               mod_timer(&piocb->vport->els_tmofunc,
-                         jiffies +
-                         msecs_to_jiffies(1000 * (phba->fc_ratov << 1)));
+          (piocb->iocb.ulpCommand != CMD_CLOSE_XRI_CN)) {
+               BUG_ON(!piocb->vport);
+               if (!(piocb->vport->load_flag & FC_UNLOADING))
+                       mod_timer(&piocb->vport->els_tmofunc,
+                                 jiffies +
+                                 msecs_to_jiffies(1000 * (phba->fc_ratov << 1)));
+       }
 
        return 0;
 }
index 91b70bc46e7f184ece7d81ac233cb5957b080943..1c4744e78173bc0f78383b8f6cf901715b946d34 100644 (file)
@@ -3885,6 +3885,11 @@ _scsih_temp_threshold_events(struct MPT3SAS_ADAPTER *ioc,
        }
 }
 
+static inline bool ata_12_16_cmd(struct scsi_cmnd *scmd)
+{
+       return (scmd->cmnd[0] == ATA_12 || scmd->cmnd[0] == ATA_16);
+}
+
 /**
  * _scsih_flush_running_cmds - completing outstanding commands.
  * @ioc: per adapter object
@@ -3906,6 +3911,9 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc)
                if (!scmd)
                        continue;
                count++;
+               if (ata_12_16_cmd(scmd))
+                       scsi_internal_device_unblock(scmd->device,
+                                                       SDEV_RUNNING);
                mpt3sas_base_free_smid(ioc, smid);
                scsi_dma_unmap(scmd);
                if (ioc->pci_error_recovery)
@@ -4010,11 +4018,6 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
            SAM_STAT_CHECK_CONDITION;
 }
 
-static inline bool ata_12_16_cmd(struct scsi_cmnd *scmd)
-{
-       return (scmd->cmnd[0] == ATA_12 || scmd->cmnd[0] == ATA_16);
-}
-
 /**
  * scsih_qcmd - main scsi request entry point
  * @scmd: pointer to scsi command object
index 86eb19902bacef9f62e808833cbe86387b1d1771..c7cc8035eacb371eb3ae6e038abb6df7c94e7169 100644 (file)
@@ -791,8 +791,10 @@ static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf
        slot->slot_tag = tag;
 
        slot->buf = pci_pool_alloc(mvi->dma_pool, GFP_ATOMIC, &slot->buf_dma);
-       if (!slot->buf)
+       if (!slot->buf) {
+               rc = -ENOMEM;
                goto err_out_tag;
+       }
        memset(slot->buf, 0, MVS_SLOT_BUF_SZ);
 
        tei.task = task;
index 4377e87ee79c360c4bb797b4a93df405b02c1f00..892a0b058b997e2ffad02d913347aee0d4c9f542 100644 (file)
@@ -356,8 +356,8 @@ struct qlogicpti {
 
        /* The rest of the elements are unimportant for performance. */
        struct qlogicpti         *next;
-       __u32                     res_dvma;             /* Ptr to RESPONSE bufs (DVMA)*/
-       __u32                     req_dvma;             /* Ptr to REQUEST bufs (DVMA) */
+       dma_addr_t                res_dvma;             /* Ptr to RESPONSE bufs (DVMA)*/
+       dma_addr_t                req_dvma;             /* Ptr to REQUEST bufs (DVMA) */
        u_char                    fware_majrev, fware_minrev, fware_micrev;
        struct Scsi_Host         *qhost;
        int                       qpti_id;
index e3b30ea9ece5945c935791798ab27ed8f6c3dd11..a504e2e003da58181e6fbf4e8276c8f4615e18f2 100644 (file)
@@ -506,7 +506,7 @@ static void vhost_vsock_reset_orphans(struct sock *sk)
         * executing.
         */
 
-       if (!vhost_vsock_get(vsk->local_addr.svm_cid)) {
+       if (!vhost_vsock_get(vsk->remote_addr.svm_cid)) {
                sock_set_flag(sk, SOCK_DONE);
                vsk->peer_shutdown = SHUTDOWN_MASK;
                sk->sk_state = SS_UNCONNECTED;
index 78180d1517307ee7b88dd000d162d7e197b19267..a594c7879cc245a764afb945e37de2b908482951 100644 (file)
@@ -1261,26 +1261,30 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
                        return -ECHILD;
 
                op = ceph_snap(dir) == CEPH_SNAPDIR ?
-                       CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP;
+                       CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_GETATTR;
                req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS);
                if (!IS_ERR(req)) {
                        req->r_dentry = dget(dentry);
-                       req->r_num_caps = 2;
+                       req->r_num_caps = op == CEPH_MDS_OP_GETATTR ? 1 : 2;
 
                        mask = CEPH_STAT_CAP_INODE | CEPH_CAP_AUTH_SHARED;
                        if (ceph_security_xattr_wanted(dir))
                                mask |= CEPH_CAP_XATTR_SHARED;
                        req->r_args.getattr.mask = mask;
 
-                       req->r_locked_dir = dir;
                        err = ceph_mdsc_do_request(mdsc, NULL, req);
-                       if (err == 0 || err == -ENOENT) {
-                               if (dentry == req->r_dentry) {
-                                       valid = !d_unhashed(dentry);
-                               } else {
-                                       d_invalidate(req->r_dentry);
-                                       err = -EAGAIN;
-                               }
+                       switch (err) {
+                       case 0:
+                               if (d_really_is_positive(dentry) &&
+                                   d_inode(dentry) == req->r_target_inode)
+                                       valid = 1;
+                               break;
+                       case -ENOENT:
+                               if (d_really_is_negative(dentry))
+                                       valid = 1;
+                               /* Fallthrough */
+                       default:
+                               break;
                        }
                        ceph_mdsc_put_request(req);
                        dout("d_revalidate %p lookup result=%d\n",
index 8347c90cf483cefbce4995a107666bba61ae7ef4..5eb04129f93849c2727a517119bc484761160332 100644 (file)
@@ -808,7 +808,11 @@ calc_seckey(struct cifs_ses *ses)
        struct crypto_skcipher *tfm_arc4;
        struct scatterlist sgin, sgout;
        struct skcipher_request *req;
-       unsigned char sec_key[CIFS_SESS_KEY_SIZE]; /* a nonce */
+       unsigned char *sec_key;
+
+       sec_key = kmalloc(CIFS_SESS_KEY_SIZE, GFP_KERNEL);
+       if (sec_key == NULL)
+               return -ENOMEM;
 
        get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE);
 
@@ -816,7 +820,7 @@ calc_seckey(struct cifs_ses *ses)
        if (IS_ERR(tfm_arc4)) {
                rc = PTR_ERR(tfm_arc4);
                cifs_dbg(VFS, "could not allocate crypto API arc4\n");
-               return rc;
+               goto out;
        }
 
        rc = crypto_skcipher_setkey(tfm_arc4, ses->auth_key.response,
@@ -854,7 +858,8 @@ calc_seckey(struct cifs_ses *ses)
 
 out_free_cipher:
        crypto_free_skcipher(tfm_arc4);
-
+out:
+       kfree(sec_key);
        return rc;
 }
 
index 3f3185febc585f93fb9f88a0b0e96ec49b636f4a..e3fed9249a04f09929e772c0f4c9b0955263b13b 100644 (file)
@@ -3427,6 +3427,7 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
        __u16 rc = 0;
        struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
        struct posix_acl_xattr_header *local_acl = (void *)pACL;
+       struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
        int count;
        int i;
 
@@ -3453,8 +3454,7 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
                return 0;
        }
        for (i = 0; i < count; i++) {
-               rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
-                       (struct posix_acl_xattr_entry *)(local_acl + 1));
+               rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
                if (rc != 0) {
                        /* ACE not converted */
                        break;
index aab5227979e2ee27c1858b47f9bf33c275f27633..4547aeddd12b19459d23c6ac9215f01b39b15189 100644 (file)
@@ -412,6 +412,9 @@ cifs_reconnect(struct TCP_Server_Info *server)
                }
        } while (server->tcpStatus == CifsNeedReconnect);
 
+       if (server->tcpStatus == CifsNeedNegotiate)
+               mod_delayed_work(cifsiod_wq, &server->echo, 0);
+
        return rc;
 }
 
@@ -421,17 +424,25 @@ cifs_echo_request(struct work_struct *work)
        int rc;
        struct TCP_Server_Info *server = container_of(work,
                                        struct TCP_Server_Info, echo.work);
-       unsigned long echo_interval = server->echo_interval;
+       unsigned long echo_interval;
+
+       /*
+        * If we need to renegotiate, set echo interval to zero to
+        * immediately call echo service where we can renegotiate.
+        */
+       if (server->tcpStatus == CifsNeedNegotiate)
+               echo_interval = 0;
+       else
+               echo_interval = server->echo_interval;
 
        /*
-        * We cannot send an echo if it is disabled or until the
-        * NEGOTIATE_PROTOCOL request is done, which is indicated by
-        * server->ops->need_neg() == true. Also, no need to ping if
-        * we got a response recently.
+        * We cannot send an echo if it is disabled.
+        * Also, no need to ping if we got a response recently.
         */
 
        if (server->tcpStatus == CifsNeedReconnect ||
-           server->tcpStatus == CifsExiting || server->tcpStatus == CifsNew ||
+           server->tcpStatus == CifsExiting ||
+           server->tcpStatus == CifsNew ||
            (server->ops->can_echo && !server->ops->can_echo(server)) ||
            time_before(jiffies, server->lstrp + echo_interval - HZ))
                goto requeue_echo;
@@ -442,7 +453,7 @@ cifs_echo_request(struct work_struct *work)
                         server->hostname);
 
 requeue_echo:
-       queue_delayed_work(cifsiod_wq, &server->echo, echo_interval);
+       queue_delayed_work(cifsiod_wq, &server->echo, server->echo_interval);
 }
 
 static bool
index b3ebe512d64c014a70f0802c75a0d7c88305ec10..096f79997f75adf9603c4c6367635588535a8ae3 100644 (file)
@@ -1739,8 +1739,6 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
                 * This should be done on write(), truncate() and chown().
                 */
                if (!fc->handle_killpriv) {
-                       int kill;
-
                        /*
                         * ia_mode calculation may have used stale i_mode.
                         * Refresh and recalculate.
@@ -1750,12 +1748,11 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
                                return ret;
 
                        attr->ia_mode = inode->i_mode;
-                       kill = should_remove_suid(entry);
-                       if (kill & ATTR_KILL_SUID) {
+                       if (inode->i_mode & S_ISUID) {
                                attr->ia_valid |= ATTR_MODE;
                                attr->ia_mode &= ~S_ISUID;
                        }
-                       if (kill & ATTR_KILL_SGID) {
+                       if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
                                attr->ia_valid |= ATTR_MODE;
                                attr->ia_mode &= ~S_ISGID;
                        }
index 98b3eb7d8eaf64d5eb006801aeb130ff8503f593..0ec137310320f080316c5e6111198b842a77303e 100644 (file)
@@ -377,9 +377,9 @@ repeat:
                        {
                                int p;
                                for (p = 0; p < rr->u.ER.len_id; p++)
-                                       printk("%c", rr->u.ER.data[p]);
+                                       printk(KERN_CONT "%c", rr->u.ER.data[p]);
                        }
-                       printk("\n");
+                       printk(KERN_CONT "\n");
                        break;
                case SIG('P', 'X'):
                        inode->i_mode = isonum_733(rr->u.PX.mode);
index edd46a0e951d3e6d5ecbae0de8091c6f903d5297..0e100856c7b8c252b4555b14747197fb6ee5303a 100644 (file)
@@ -328,11 +328,11 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
        if (!real)
                goto bug;
 
+       /* Handle recursion */
+       real = d_real(real, inode, open_flags);
+
        if (!inode || inode == d_inode(real))
                return real;
-
-       /* Handle recursion */
-       return d_real(real, inode, open_flags);
 bug:
        WARN(1, "ovl_d_real(%pd4, %s:%lu): real dentry not found\n", dentry,
             inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0);
index 61580b19f9f6e1e31e42fc6afcd0f416cc2c5f2a..22f884c97387e9929a4fb19e7ee5328bccb34c8d 100644 (file)
@@ -124,6 +124,8 @@ struct drbg_state {
        struct skcipher_request *ctr_req;       /* CTR mode request handle */
        __u8 *ctr_null_value_buf;               /* CTR mode unaligned buffer */
        __u8 *ctr_null_value;                   /* CTR mode aligned zero buf */
+       __u8 *outscratchpadbuf;                 /* CTR mode output scratchpad */
+        __u8 *outscratchpad;                   /* CTR mode aligned outbuf */
        struct completion ctr_completion;       /* CTR mode async handler */
        int ctr_async_err;                      /* CTR mode async error */
 
index 432f5c97e18f4f75fd68b1c1101cf828fb3d4fa0..928e5ca0caee271e849fabeff0fa522a59650cc6 100644 (file)
 #endif
 #endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP && !__CHECKER__ */
 
-#if GCC_VERSION >= 50000
+#if GCC_VERSION >= 70000
+#define KASAN_ABI_VERSION 5
+#elif GCC_VERSION >= 50000
 #define KASAN_ABI_VERSION 4
 #elif GCC_VERSION >= 40902
 #define KASAN_ABI_VERSION 3
index f4947fda11e771c35c6465d3b329a8611249ee8b..8458c5351e562e57ea1161fc5ab234d5e53a47bb 100644 (file)
@@ -143,7 +143,7 @@ u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd,
                const struct nd_cmd_desc *desc, int idx, void *buf);
 u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
                const struct nd_cmd_desc *desc, int idx, const u32 *in_field,
-               const u32 *out_field);
+               const u32 *out_field, unsigned long remainder);
 int nvdimm_bus_check_dimm_count(struct nvdimm_bus *nvdimm_bus, int dimm_count);
 struct nd_region *nvdimm_pmem_region_create(struct nvdimm_bus *nvdimm_bus,
                struct nd_region_desc *ndr_desc);
index 3be7abd6e722d0c0f6a34f40a21327b81251f72e..c9f379689dd068beadbdb828fe8f09b521b28f12 100644 (file)
@@ -476,7 +476,6 @@ enum {
 enum {
        MLX4_INTERFACE_STATE_UP         = 1 << 0,
        MLX4_INTERFACE_STATE_DELETION   = 1 << 1,
-       MLX4_INTERFACE_STATE_SHUTDOWN   = 1 << 2,
 };
 
 #define MSTR_SM_CHANGE_MASK (MLX4_EQ_PORT_INFO_MSTR_SM_SL_CHANGE_MASK | \
index 2ab233661ae5da49cac59c33c38433501b1af4b4..a58cca8bcb29d8c9bdcda71538cfa8f25c913916 100644 (file)
@@ -29,6 +29,7 @@ struct phy_device *of_phy_attach(struct net_device *dev,
 extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np);
 extern int of_mdio_parse_addr(struct device *dev, const struct device_node *np);
 extern int of_phy_register_fixed_link(struct device_node *np);
+extern void of_phy_deregister_fixed_link(struct device_node *np);
 extern bool of_phy_is_fixed_link(struct device_node *np);
 
 #else /* CONFIG_OF */
@@ -83,6 +84,9 @@ static inline int of_phy_register_fixed_link(struct device_node *np)
 {
        return -ENOSYS;
 }
+static inline void of_phy_deregister_fixed_link(struct device_node *np)
+{
+}
 static inline bool of_phy_is_fixed_link(struct device_node *np)
 {
        return false;
index dd15d39e1985908614271dcb8e8712c4fffa4f63..7dbe9148b2f8a661257d0aa620cf1f61fa7d5f57 100644 (file)
@@ -374,16 +374,13 @@ static inline struct page *read_mapping_page(struct address_space *mapping,
 }
 
 /*
- * Get the offset in PAGE_SIZE.
- * (TODO: hugepage should have ->index in PAGE_SIZE)
+ * Get index of the page with in radix-tree
+ * (TODO: remove once hugetlb pages will have ->index in PAGE_SIZE)
  */
-static inline pgoff_t page_to_pgoff(struct page *page)
+static inline pgoff_t page_to_index(struct page *page)
 {
        pgoff_t pgoff;
 
-       if (unlikely(PageHeadHuge(page)))
-               return page->index << compound_order(page);
-
        if (likely(!PageTransTail(page)))
                return page->index;
 
@@ -396,6 +393,18 @@ static inline pgoff_t page_to_pgoff(struct page *page)
        return pgoff;
 }
 
+/*
+ * Get the offset in PAGE_SIZE.
+ * (TODO: hugepage should have ->index in PAGE_SIZE)
+ */
+static inline pgoff_t page_to_pgoff(struct page *page)
+{
+       if (unlikely(PageHeadHuge(page)))
+               return page->index << compound_order(page);
+
+       return page_to_index(page);
+}
+
 /*
  * Return byte-offset into filesystem object for page.
  */
index 0e49f70dbd9b0aaf48d8546d2765f7c4fe813012..a38772a855885e48e0fc5a5f83c942efc9d9db4c 100644 (file)
@@ -1928,6 +1928,20 @@ static inline int pci_pcie_type(const struct pci_dev *dev)
        return (pcie_caps_reg(dev) & PCI_EXP_FLAGS_TYPE) >> 4;
 }
 
+static inline struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
+{
+       while (1) {
+               if (!pci_is_pcie(dev))
+                       break;
+               if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
+                       return dev;
+               if (!dev->bus->self)
+                       break;
+               dev = dev->bus->self;
+       }
+       return NULL;
+}
+
 void pci_request_acs(void);
 bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
 bool pci_acs_path_enabled(struct pci_dev *start,
index a09fe5c009c84a4cd1594f69e599ce37740e5c00..81ece61075dff0e7a04e56f764bdae8a142f08e5 100644 (file)
 #include <linux/err.h>
 #include <linux/of.h>
 #include <linux/notifier.h>
+#include <linux/spinlock.h>
 
 /* Defines used for the flags field in the struct generic_pm_domain */
 #define GENPD_FLAG_PM_CLK      (1U << 0) /* PM domain uses PM clk */
-
-#define GENPD_MAX_NUM_STATES   8 /* Number of possible low power states */
+#define GENPD_FLAG_IRQ_SAFE    (1U << 1) /* PM domain operates in atomic */
 
 enum gpd_status {
        GPD_STATE_ACTIVE = 0,   /* PM domain is active */
@@ -40,15 +40,18 @@ struct gpd_dev_ops {
 struct genpd_power_state {
        s64 power_off_latency_ns;
        s64 power_on_latency_ns;
+       s64 residency_ns;
+       struct fwnode_handle *fwnode;
 };
 
+struct genpd_lock_ops;
+
 struct generic_pm_domain {
        struct dev_pm_domain domain;    /* PM domain operations */
        struct list_head gpd_list_node; /* Node in the global PM domains list */
        struct list_head master_links;  /* Links with PM domain as a master */
        struct list_head slave_links;   /* Links with PM domain as a slave */
        struct list_head dev_list;      /* List of devices */
-       struct mutex lock;
        struct dev_power_governor *gov;
        struct work_struct power_off_work;
        struct fwnode_handle *provider; /* Identity of the domain provider */
@@ -70,9 +73,18 @@ struct generic_pm_domain {
        void (*detach_dev)(struct generic_pm_domain *domain,
                           struct device *dev);
        unsigned int flags;             /* Bit field of configs for genpd */
-       struct genpd_power_state states[GENPD_MAX_NUM_STATES];
+       struct genpd_power_state *states;
        unsigned int state_count; /* number of states */
        unsigned int state_idx; /* state that genpd will go to when off */
+       void *free; /* Free the state that was allocated for default */
+       const struct genpd_lock_ops *lock_ops;
+       union {
+               struct mutex mlock;
+               struct {
+                       spinlock_t slock;
+                       unsigned long lock_flags;
+               };
+       };
 
 };
 
@@ -205,6 +217,8 @@ extern int of_genpd_add_device(struct of_phandle_args *args,
 extern int of_genpd_add_subdomain(struct of_phandle_args *parent,
                                  struct of_phandle_args *new_subdomain);
 extern struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
+extern int of_genpd_parse_idle_states(struct device_node *dn,
+                       struct genpd_power_state **states, int *n);
 
 int genpd_dev_pm_attach(struct device *dev);
 #else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
@@ -234,6 +248,12 @@ static inline int of_genpd_add_subdomain(struct of_phandle_args *parent,
        return -ENODEV;
 }
 
+static inline int of_genpd_parse_idle_states(struct device_node *dn,
+                       struct genpd_power_state **states, int *n)
+{
+       return -ENODEV;
+}
+
 static inline int genpd_dev_pm_attach(struct device *dev)
 {
        return -ENODEV;
index 2e14d2667b6cb82af01145fe52e9ed828beb6812..4957fc185ea99948a350fd3c56da4f901e0599d3 100644 (file)
@@ -61,12 +61,6 @@ static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
        dev->power.ignore_children = enable;
 }
 
-static inline bool pm_children_suspended(struct device *dev)
-{
-       return dev->power.ignore_children
-               || !atomic_read(&dev->power.child_count);
-}
-
 static inline void pm_runtime_get_noresume(struct device *dev)
 {
        atomic_inc(&dev->power.usage_count);
@@ -162,7 +156,6 @@ static inline void pm_runtime_allow(struct device *dev) {}
 static inline void pm_runtime_forbid(struct device *dev) {}
 
 static inline void pm_suspend_ignore_children(struct device *dev, bool enable) {}
-static inline bool pm_children_suspended(struct device *dev) { return false; }
 static inline void pm_runtime_get_noresume(struct device *dev) {}
 static inline void pm_runtime_put_noidle(struct device *dev) {}
 static inline bool device_run_wake(struct device *dev) { return false; }
@@ -265,9 +258,9 @@ static inline int pm_runtime_set_active(struct device *dev)
        return __pm_runtime_set_status(dev, RPM_ACTIVE);
 }
 
-static inline void pm_runtime_set_suspended(struct device *dev)
+static inline int pm_runtime_set_suspended(struct device *dev)
 {
-       __pm_runtime_set_status(dev, RPM_SUSPENDED);
+       return __pm_runtime_set_status(dev, RPM_SUSPENDED);
 }
 
 static inline void pm_runtime_disable(struct device *dev)
index 3a375d07d0dc0284441133228af266956ed94f89..00d232406f18dbd1b6c27d1d24ca4c417d200530 100644 (file)
@@ -81,7 +81,8 @@
 #define CDC_NCM_TIMER_INTERVAL_MAX             (U32_MAX / NSEC_PER_USEC)
 
 /* Driver flags */
-#define CDC_NCM_FLAG_NDP_TO_END        0x02            /* NDP is placed at end of frame */
+#define CDC_NCM_FLAG_NDP_TO_END                        0x02    /* NDP is placed at end of frame */
+#define CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE  0x04    /* Avoid altsetting toggle during init */
 
 #define cdc_ncm_comm_intf_is_mbim(x)  ((x)->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_MBIM && \
                                       (x)->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE)
index 8fed1cd78658a6e088b63f7703290cb02c1969b6..f11ca837361b37f93f4061dcc8945c198be8b1f9 100644 (file)
@@ -970,6 +970,8 @@ int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
 int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
                           char __user *optval, int __user *optlen);
 
+int __ip6_datagram_connect(struct sock *sk, struct sockaddr *addr,
+                          int addr_len);
 int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len);
 int ip6_datagram_connect_v6_only(struct sock *sk, struct sockaddr *addr,
                                 int addr_len);
index 50418052a520f396e8ae550160ca81e51ad89857..d9d52c020a709993fbbb02898ffe2931271a5ff7 100644 (file)
@@ -100,6 +100,9 @@ struct nf_conn {
 
        possible_net_t ct_net;
 
+#if IS_ENABLED(CONFIG_NF_NAT)
+       struct rhlist_head nat_bysource;
+#endif
        /* all members below initialized via memset */
        u8 __nfct_init_offset[0];
 
@@ -117,9 +120,6 @@ struct nf_conn {
        /* Extensions */
        struct nf_ct_ext *ext;
 
-#if IS_ENABLED(CONFIG_NF_NAT)
-       struct rhash_head       nat_bysource;
-#endif
        /* Storage reserved for other modules, must be the last member */
        union nf_conntrack_proto proto;
 };
index d79d1e9b95461bc869c6149f80d7e3789bcb89ac..b02af0bf577796687c457bb10def12d959019cb0 100644 (file)
@@ -313,7 +313,7 @@ void nft_unregister_set(struct nft_set_ops *ops);
  *     @size: maximum set size
  *     @nelems: number of elements
  *     @ndeact: number of deactivated elements queued for removal
- *     @timeout: default timeout value in msecs
+ *     @timeout: default timeout value in jiffies
  *     @gc_int: garbage collection interval in msecs
  *     @policy: set parameterization (see enum nft_set_policies)
  *     @udlen: user data length
index 9692cda5f8fc2fe7789de59f93281cf4c0bd2a5e..c48d93a28d1acbb905b5d62cb2e8436c20ec8c7e 100644 (file)
@@ -196,5 +196,6 @@ struct can_filter {
 };
 
 #define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */
+#define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via setsockopt() */
 
 #endif /* !_UAPI_CAN_H */
index e601c8c3bdc777b6458fe99d39de1f91b16f66d9..1158a043342ac6a77edcd3a4180632b4ef4c87e0 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/hdlc/ioctl.h>
 
 /* For glibc compatibility. An empty enum does not compile. */
-#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 && \
+#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 || \
     __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0
 /**
  * enum net_device_flags - &struct net_device flags
@@ -99,7 +99,7 @@ enum net_device_flags {
        IFF_ECHO                        = 1<<18, /* volatile */
 #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
 };
-#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 && __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0 */
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 || __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0 */
 
 /* for compatibility with glibc net/if.h */
 #if __UAPI_DEF_IF_NET_DEVICE_FLAGS
index d6d071fc3c568249bf70f24602f95770eb1643df..3af60ee69053322b9c6ca72d3120ce9f23da1c80 100644 (file)
  * Control a data application associated with the currently viewed channel,
  * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.)
  */
-#define KEY_DATA                       0x275
+#define KEY_DATA                       0x277
 
 #define BTN_TRIGGER_HAPPY              0x2c0
 #define BTN_TRIGGER_HAPPY1             0x2c0
index cd26d7a0fd07094499f97568dc8ca4f50ae93c0f..03f194aeadc51b56d468236c9bba67afbe0b86bd 100644 (file)
@@ -5,6 +5,7 @@ header-y += nf_conntrack_ftp.h
 header-y += nf_conntrack_sctp.h
 header-y += nf_conntrack_tcp.h
 header-y += nf_conntrack_tuple_common.h
+header-y += nf_log.h
 header-y += nf_tables.h
 header-y += nf_tables_compat.h
 header-y += nf_nat.h
index e3969bd939e41d7fb1ff47f61344fad5f1cae482..e3db7403296fdf8a7f72ec44523acea9ba8b0b9b 100644 (file)
@@ -11,3 +11,5 @@ header-y += tc_vlan.h
 header-y += tc_bpf.h
 header-y += tc_connmark.h
 header-y += tc_ife.h
+header-y += tc_tunnel_key.h
+header-y += tc_skbmod.h
index c4fbc1e55c2539a37486f990efde1d29d44db7a7..34407f15e6d34da57be238f69441f1dad9e60764 100644 (file)
@@ -1945,7 +1945,6 @@ config MODULE_FORCE_UNLOAD
 
 config MODVERSIONS
        bool "Module versioning support"
-       depends on BROKEN
        help
          Usually, you have to use modules compiled with your kernel.
          Saying Y here makes it sometimes possible to use modules
index 6a936159c6e06d629c325978623a32359ec095f4..8199821f54cf2c676204abb7b4cc9fad88524b4a 100644 (file)
@@ -2454,6 +2454,7 @@ static bool states_equal(struct bpf_verifier_env *env,
                         struct bpf_verifier_state *old,
                         struct bpf_verifier_state *cur)
 {
+       bool varlen_map_access = env->varlen_map_value_access;
        struct bpf_reg_state *rold, *rcur;
        int i;
 
@@ -2467,12 +2468,17 @@ static bool states_equal(struct bpf_verifier_env *env,
                /* If the ranges were not the same, but everything else was and
                 * we didn't do a variable access into a map then we are a-ok.
                 */
-               if (!env->varlen_map_value_access &&
+               if (!varlen_map_access &&
                    rold->type == rcur->type && rold->imm == rcur->imm)
                        continue;
 
+               /* If we didn't map access then again we don't care about the
+                * mismatched range values and it's ok if our old type was
+                * UNKNOWN and we didn't go to a NOT_INIT'ed reg.
+                */
                if (rold->type == NOT_INIT ||
-                   (rold->type == UNKNOWN_VALUE && rcur->type != NOT_INIT))
+                   (!varlen_map_access && rold->type == UNKNOWN_VALUE &&
+                    rcur->type != NOT_INIT))
                        continue;
 
                if (rold->type == PTR_TO_PACKET && rcur->type == PTR_TO_PACKET &&
index 6ee1febdf6ff838b21db38277e0760ae0909e91f..02c8421f8c0190135995a31731d6e61c3064a9e8 100644 (file)
@@ -903,17 +903,14 @@ list_update_cgroup_event(struct perf_event *event,
         */
        cpuctx = __get_cpu_context(ctx);
 
-       /* Only set/clear cpuctx->cgrp if current task uses event->cgrp. */
-       if (perf_cgroup_from_task(current, ctx) != event->cgrp) {
-               /*
-                * We are removing the last cpu event in this context.
-                * If that event is not active in this cpu, cpuctx->cgrp
-                * should've been cleared by perf_cgroup_switch.
-                */
-               WARN_ON_ONCE(!add && cpuctx->cgrp);
-               return;
-       }
-       cpuctx->cgrp = add ? event->cgrp : NULL;
+       /*
+        * cpuctx->cgrp is NULL until a cgroup event is sched in or
+        * ctx->nr_cgroup == 0 .
+        */
+       if (add && perf_cgroup_from_task(current, ctx) == event->cgrp)
+               cpuctx->cgrp = event->cgrp;
+       else if (!add)
+               cpuctx->cgrp = NULL;
 }
 
 #else /* !CONFIG_CGROUP_PERF */
index 30e6d05aa5a9f726422c7968dabbff5e1c590c2a..3cbb0c879705f7a29f1d5bfad58551c098e69432 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/printk.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
index 589d763a49b3952322f08c00286675f314a3f76c..4d7ffc0a0d0069af114da7c795967d695a135e14 100644 (file)
@@ -506,13 +506,13 @@ static void __print_lock_name(struct lock_class *class)
        name = class->name;
        if (!name) {
                name = __get_key_name(class->key, str);
-               printk("%s", name);
+               printk(KERN_CONT "%s", name);
        } else {
-               printk("%s", name);
+               printk(KERN_CONT "%s", name);
                if (class->name_version > 1)
-                       printk("#%d", class->name_version);
+                       printk(KERN_CONT "#%d", class->name_version);
                if (class->subclass)
-                       printk("/%d", class->subclass);
+                       printk(KERN_CONT "/%d", class->subclass);
        }
 }
 
@@ -522,9 +522,9 @@ static void print_lock_name(struct lock_class *class)
 
        get_usage_chars(class, usage);
 
-       printk(" (");
+       printk(KERN_CONT " (");
        __print_lock_name(class);
-       printk("){%s}", usage);
+       printk(KERN_CONT "){%s}", usage);
 }
 
 static void print_lockdep_cache(struct lockdep_map *lock)
@@ -536,7 +536,7 @@ static void print_lockdep_cache(struct lockdep_map *lock)
        if (!name)
                name = __get_key_name(lock->key->subkeys, str);
 
-       printk("%s", name);
+       printk(KERN_CONT "%s", name);
 }
 
 static void print_lock(struct held_lock *hlock)
@@ -551,13 +551,13 @@ static void print_lock(struct held_lock *hlock)
        barrier();
 
        if (!class_idx || (class_idx - 1) >= MAX_LOCKDEP_KEYS) {
-               printk("<RELEASED>\n");
+               printk(KERN_CONT "<RELEASED>\n");
                return;
        }
 
        print_lock_name(lock_classes + class_idx - 1);
-       printk(", at: ");
-       print_ip_sym(hlock->acquire_ip);
+       printk(KERN_CONT ", at: [<%p>] %pS\n",
+               (void *)hlock->acquire_ip, (void *)hlock->acquire_ip);
 }
 
 static void lockdep_print_held_locks(struct task_struct *curr)
@@ -792,8 +792,8 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
 
                printk("\nnew class %p: %s", class->key, class->name);
                if (class->name_version > 1)
-                       printk("#%d", class->name_version);
-               printk("\n");
+                       printk(KERN_CONT "#%d", class->name_version);
+               printk(KERN_CONT "\n");
                dump_stack();
 
                if (!graph_lock()) {
@@ -1071,7 +1071,7 @@ print_circular_bug_entry(struct lock_list *target, int depth)
                return 0;
        printk("\n-> #%u", depth);
        print_lock_name(target->class);
-       printk(":\n");
+       printk(KERN_CONT ":\n");
        print_stack_trace(&target->trace, 6);
 
        return 0;
@@ -1102,11 +1102,11 @@ print_circular_lock_scenario(struct held_lock *src,
        if (parent != source) {
                printk("Chain exists of:\n  ");
                __print_lock_name(source);
-               printk(" --> ");
+               printk(KERN_CONT " --> ");
                __print_lock_name(parent);
-               printk(" --> ");
+               printk(KERN_CONT " --> ");
                __print_lock_name(target);
-               printk("\n\n");
+               printk(KERN_CONT "\n\n");
        }
 
        printk(" Possible unsafe locking scenario:\n\n");
@@ -1114,16 +1114,16 @@ print_circular_lock_scenario(struct held_lock *src,
        printk("       ----                    ----\n");
        printk("  lock(");
        __print_lock_name(target);
-       printk(");\n");
+       printk(KERN_CONT ");\n");
        printk("                               lock(");
        __print_lock_name(parent);
-       printk(");\n");
+       printk(KERN_CONT ");\n");
        printk("                               lock(");
        __print_lock_name(target);
-       printk(");\n");
+       printk(KERN_CONT ");\n");
        printk("  lock(");
        __print_lock_name(source);
-       printk(");\n");
+       printk(KERN_CONT ");\n");
        printk("\n *** DEADLOCK ***\n\n");
 }
 
@@ -1359,22 +1359,22 @@ static void print_lock_class_header(struct lock_class *class, int depth)
 
        printk("%*s->", depth, "");
        print_lock_name(class);
-       printk(" ops: %lu", class->ops);
-       printk(" {\n");
+       printk(KERN_CONT " ops: %lu", class->ops);
+       printk(KERN_CONT " {\n");
 
        for (bit = 0; bit < LOCK_USAGE_STATES; bit++) {
                if (class->usage_mask & (1 << bit)) {
                        int len = depth;
 
                        len += printk("%*s   %s", depth, "", usage_str[bit]);
-                       len += printk(" at:\n");
+                       len += printk(KERN_CONT " at:\n");
                        print_stack_trace(class->usage_traces + bit, len);
                }
        }
        printk("%*s }\n", depth, "");
 
-       printk("%*s ... key      at: ",depth,"");
-       print_ip_sym((unsigned long)class->key);
+       printk("%*s ... key      at: [<%p>] %pS\n",
+               depth, "", class->key, class->key);
 }
 
 /*
@@ -1437,11 +1437,11 @@ print_irq_lock_scenario(struct lock_list *safe_entry,
        if (middle_class != unsafe_class) {
                printk("Chain exists of:\n  ");
                __print_lock_name(safe_class);
-               printk(" --> ");
+               printk(KERN_CONT " --> ");
                __print_lock_name(middle_class);
-               printk(" --> ");
+               printk(KERN_CONT " --> ");
                __print_lock_name(unsafe_class);
-               printk("\n\n");
+               printk(KERN_CONT "\n\n");
        }
 
        printk(" Possible interrupt unsafe locking scenario:\n\n");
@@ -1449,18 +1449,18 @@ print_irq_lock_scenario(struct lock_list *safe_entry,
        printk("       ----                    ----\n");
        printk("  lock(");
        __print_lock_name(unsafe_class);
-       printk(");\n");
+       printk(KERN_CONT ");\n");
        printk("                               local_irq_disable();\n");
        printk("                               lock(");
        __print_lock_name(safe_class);
-       printk(");\n");
+       printk(KERN_CONT ");\n");
        printk("                               lock(");
        __print_lock_name(middle_class);
-       printk(");\n");
+       printk(KERN_CONT ");\n");
        printk("  <Interrupt>\n");
        printk("    lock(");
        __print_lock_name(safe_class);
-       printk(");\n");
+       printk(KERN_CONT ");\n");
        printk("\n *** DEADLOCK ***\n\n");
 }
 
@@ -1497,9 +1497,9 @@ print_bad_irq_dependency(struct task_struct *curr,
        print_lock(prev);
        printk("which would create a new lock dependency:\n");
        print_lock_name(hlock_class(prev));
-       printk(" ->");
+       printk(KERN_CONT " ->");
        print_lock_name(hlock_class(next));
-       printk("\n");
+       printk(KERN_CONT "\n");
 
        printk("\nbut this new dependency connects a %s-irq-safe lock:\n",
                irqclass);
@@ -1521,8 +1521,7 @@ print_bad_irq_dependency(struct task_struct *curr,
 
        lockdep_print_held_locks(curr);
 
-       printk("\nthe dependencies between %s-irq-safe lock", irqclass);
-       printk(" and the holding lock:\n");
+       printk("\nthe dependencies between %s-irq-safe lock and the holding lock:\n", irqclass);
        if (!save_trace(&prev_root->trace))
                return 0;
        print_shortest_lock_dependencies(backwards_entry, prev_root);
@@ -1694,10 +1693,10 @@ print_deadlock_scenario(struct held_lock *nxt,
        printk("       ----\n");
        printk("  lock(");
        __print_lock_name(prev);
-       printk(");\n");
+       printk(KERN_CONT ");\n");
        printk("  lock(");
        __print_lock_name(next);
-       printk(");\n");
+       printk(KERN_CONT ");\n");
        printk("\n *** DEADLOCK ***\n\n");
        printk(" May be due to missing lock nesting notation\n\n");
 }
@@ -1891,9 +1890,9 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
                graph_unlock();
                printk("\n new dependency: ");
                print_lock_name(hlock_class(prev));
-               printk(" => ");
+               printk(KERN_CONT " => ");
                print_lock_name(hlock_class(next));
-               printk("\n");
+               printk(KERN_CONT "\n");
                dump_stack();
                return graph_lock();
        }
@@ -2343,11 +2342,11 @@ print_usage_bug_scenario(struct held_lock *lock)
        printk("       ----\n");
        printk("  lock(");
        __print_lock_name(class);
-       printk(");\n");
+       printk(KERN_CONT ");\n");
        printk("  <Interrupt>\n");
        printk("    lock(");
        __print_lock_name(class);
-       printk(");\n");
+       printk(KERN_CONT ");\n");
        printk("\n *** DEADLOCK ***\n\n");
 }
 
@@ -2522,14 +2521,18 @@ check_usage_backwards(struct task_struct *curr, struct held_lock *this,
 void print_irqtrace_events(struct task_struct *curr)
 {
        printk("irq event stamp: %u\n", curr->irq_events);
-       printk("hardirqs last  enabled at (%u): ", curr->hardirq_enable_event);
-       print_ip_sym(curr->hardirq_enable_ip);
-       printk("hardirqs last disabled at (%u): ", curr->hardirq_disable_event);
-       print_ip_sym(curr->hardirq_disable_ip);
-       printk("softirqs last  enabled at (%u): ", curr->softirq_enable_event);
-       print_ip_sym(curr->softirq_enable_ip);
-       printk("softirqs last disabled at (%u): ", curr->softirq_disable_event);
-       print_ip_sym(curr->softirq_disable_ip);
+       printk("hardirqs last  enabled at (%u): [<%p>] %pS\n",
+               curr->hardirq_enable_event, (void *)curr->hardirq_enable_ip,
+               (void *)curr->hardirq_enable_ip);
+       printk("hardirqs last disabled at (%u): [<%p>] %pS\n",
+               curr->hardirq_disable_event, (void *)curr->hardirq_disable_ip,
+               (void *)curr->hardirq_disable_ip);
+       printk("softirqs last  enabled at (%u): [<%p>] %pS\n",
+               curr->softirq_enable_event, (void *)curr->softirq_enable_ip,
+               (void *)curr->softirq_enable_ip);
+       printk("softirqs last disabled at (%u): [<%p>] %pS\n",
+               curr->softirq_disable_event, (void *)curr->softirq_disable_ip,
+               (void *)curr->softirq_disable_ip);
 }
 
 static int HARDIRQ_verbose(struct lock_class *class)
@@ -3235,8 +3238,8 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
        if (very_verbose(class)) {
                printk("\nacquire class [%p] %s", class->key, class->name);
                if (class->name_version > 1)
-                       printk("#%d", class->name_version);
-               printk("\n");
+                       printk(KERN_CONT "#%d", class->name_version);
+               printk(KERN_CONT "\n");
                dump_stack();
        }
 
@@ -3378,7 +3381,7 @@ print_unlock_imbalance_bug(struct task_struct *curr, struct lockdep_map *lock,
        printk("%s/%d is trying to release lock (",
                curr->comm, task_pid_nr(curr));
        print_lockdep_cache(lock);
-       printk(") at:\n");
+       printk(KERN_CONT ") at:\n");
        print_ip_sym(ip);
        printk("but there are no more locks to release!\n");
        printk("\nother info that might help us debug this:\n");
@@ -3871,7 +3874,7 @@ print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock,
        printk("%s/%d is trying to contend lock (",
                curr->comm, task_pid_nr(curr));
        print_lockdep_cache(lock);
-       printk(") at:\n");
+       printk(KERN_CONT ") at:\n");
        print_ip_sym(ip);
        printk("but there are no locks held!\n");
        printk("\nother info that might help us debug this:\n");
index 1ec0f48962b33dce424d4d3f491c6a1fd76ba13d..2c49d76f96c3351c2038b630e5875066a907509b 100644 (file)
@@ -65,8 +65,72 @@ static inline void clear_rt_mutex_waiters(struct rt_mutex *lock)
 
 static void fixup_rt_mutex_waiters(struct rt_mutex *lock)
 {
-       if (!rt_mutex_has_waiters(lock))
-               clear_rt_mutex_waiters(lock);
+       unsigned long owner, *p = (unsigned long *) &lock->owner;
+
+       if (rt_mutex_has_waiters(lock))
+               return;
+
+       /*
+        * The rbtree has no waiters enqueued, now make sure that the
+        * lock->owner still has the waiters bit set, otherwise the
+        * following can happen:
+        *
+        * CPU 0        CPU 1           CPU2
+        * l->owner=T1
+        *              rt_mutex_lock(l)
+        *              lock(l->lock)
+        *              l->owner = T1 | HAS_WAITERS;
+        *              enqueue(T2)
+        *              boost()
+        *                unlock(l->lock)
+        *              block()
+        *
+        *                              rt_mutex_lock(l)
+        *                              lock(l->lock)
+        *                              l->owner = T1 | HAS_WAITERS;
+        *                              enqueue(T3)
+        *                              boost()
+        *                                unlock(l->lock)
+        *                              block()
+        *              signal(->T2)    signal(->T3)
+        *              lock(l->lock)
+        *              dequeue(T2)
+        *              deboost()
+        *                unlock(l->lock)
+        *                              lock(l->lock)
+        *                              dequeue(T3)
+        *                               ==> wait list is empty
+        *                              deboost()
+        *                               unlock(l->lock)
+        *              lock(l->lock)
+        *              fixup_rt_mutex_waiters()
+        *                if (wait_list_empty(l) {
+        *                  l->owner = owner
+        *                  owner = l->owner & ~HAS_WAITERS;
+        *                    ==> l->owner = T1
+        *                }
+        *                              lock(l->lock)
+        * rt_mutex_unlock(l)           fixup_rt_mutex_waiters()
+        *                                if (wait_list_empty(l) {
+        *                                  owner = l->owner & ~HAS_WAITERS;
+        * cmpxchg(l->owner, T1, NULL)
+        *  ===> Success (l->owner = NULL)
+        *
+        *                                  l->owner = owner
+        *                                    ==> l->owner = T1
+        *                                }
+        *
+        * With the check for the waiter bit in place T3 on CPU2 will not
+        * overwrite. All tasks fiddling with the waiters bit are
+        * serialized by l->lock, so nothing else can modify the waiters
+        * bit. If the bit is set then nothing can change l->owner either
+        * so the simple RMW is safe. The cmpxchg() will simply fail if it
+        * happens in the middle of the RMW because the waiters bit is
+        * still set.
+        */
+       owner = READ_ONCE(*p);
+       if (owner & RT_MUTEX_HAS_WAITERS)
+               WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS);
 }
 
 /*
index 4f5f83c7d2d3515cb31dce798815e9614155d291..e317e1cbb3eba80098fa018de8573c1a1c7a86c0 100644 (file)
@@ -75,8 +75,9 @@ task_top_pi_waiter(struct task_struct *p)
 
 static inline struct task_struct *rt_mutex_owner(struct rt_mutex *lock)
 {
-       return (struct task_struct *)
-               ((unsigned long)lock->owner & ~RT_MUTEX_OWNER_MASKALL);
+       unsigned long owner = (unsigned long) READ_ONCE(lock->owner);
+
+       return (struct task_struct *) (owner & ~RT_MUTEX_OWNER_MASKALL);
 }
 
 /*
index f57dd63186e63c647e4566c828b1258fbcdb8724..0e54d5bf0097f57954d4848db6a830f5a0bc7072 100644 (file)
@@ -1301,8 +1301,9 @@ static int check_version(Elf_Shdr *sechdrs,
                goto bad_version;
        }
 
-       pr_warn("%s: no symbol version for %s\n", mod->name, symname);
-       return 0;
+       /* Broken toolchain. Warn once, then let it go.. */
+       pr_warn_once("%s: no symbol version for %s\n", mod->name, symname);
+       return 1;
 
 bad_version:
        pr_warn("%s: disagrees about version of symbol %s\n",
index f1c8fd5662464cd356d174b80e8cff9e0a6a4b12..da39489d2d80e9b8f6781610e97c23ec0014f45b 100644 (file)
@@ -212,6 +212,7 @@ int proc_sched_autogroup_set_nice(struct task_struct *p, int nice)
 {
        static unsigned long next = INITIAL_JIFFIES;
        struct autogroup *ag;
+       unsigned long shares;
        int err;
 
        if (nice < MIN_NICE || nice > MAX_NICE)
@@ -230,9 +231,10 @@ int proc_sched_autogroup_set_nice(struct task_struct *p, int nice)
 
        next = HZ / 10 + jiffies;
        ag = autogroup_task_get(p);
+       shares = scale_load(sched_prio_to_weight[nice + 20]);
 
        down_write(&ag->lock);
-       err = sched_group_set_shares(ag->tg, sched_prio_to_weight[nice + 20]);
+       err = sched_group_set_shares(ag->tg, shares);
        if (!err)
                ag->nice = nice;
        up_write(&ag->lock);
index a8e12601eb37dca5694faa1a5bfc9cb5e45497f1..056052dc8e911f31f20bd5aff4824c94dd9f5e83 100644 (file)
@@ -362,6 +362,7 @@ void debug_object_init(void *addr, struct debug_obj_descr *descr)
 
        __debug_object_init(addr, descr, 0);
 }
+EXPORT_SYMBOL_GPL(debug_object_init);
 
 /**
  * debug_object_init_on_stack - debug checks when an object on stack is
@@ -376,6 +377,7 @@ void debug_object_init_on_stack(void *addr, struct debug_obj_descr *descr)
 
        __debug_object_init(addr, descr, 1);
 }
+EXPORT_SYMBOL_GPL(debug_object_init_on_stack);
 
 /**
  * debug_object_activate - debug checks when an object is activated
@@ -449,6 +451,7 @@ int debug_object_activate(void *addr, struct debug_obj_descr *descr)
        }
        return 0;
 }
+EXPORT_SYMBOL_GPL(debug_object_activate);
 
 /**
  * debug_object_deactivate - debug checks when an object is deactivated
@@ -496,6 +499,7 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr)
 
        raw_spin_unlock_irqrestore(&db->lock, flags);
 }
+EXPORT_SYMBOL_GPL(debug_object_deactivate);
 
 /**
  * debug_object_destroy - debug checks when an object is destroyed
@@ -542,6 +546,7 @@ void debug_object_destroy(void *addr, struct debug_obj_descr *descr)
 out_unlock:
        raw_spin_unlock_irqrestore(&db->lock, flags);
 }
+EXPORT_SYMBOL_GPL(debug_object_destroy);
 
 /**
  * debug_object_free - debug checks when an object is freed
@@ -582,6 +587,7 @@ void debug_object_free(void *addr, struct debug_obj_descr *descr)
 out_unlock:
        raw_spin_unlock_irqrestore(&db->lock, flags);
 }
+EXPORT_SYMBOL_GPL(debug_object_free);
 
 /**
  * debug_object_assert_init - debug checks when object should be init-ed
@@ -626,6 +632,7 @@ void debug_object_assert_init(void *addr, struct debug_obj_descr *descr)
 
        raw_spin_unlock_irqrestore(&db->lock, flags);
 }
+EXPORT_SYMBOL_GPL(debug_object_assert_init);
 
 /**
  * debug_object_active_state - debug checks object usage state machine
@@ -673,6 +680,7 @@ debug_object_active_state(void *addr, struct debug_obj_descr *descr,
 
        raw_spin_unlock_irqrestore(&db->lock, flags);
 }
+EXPORT_SYMBOL_GPL(debug_object_active_state);
 
 #ifdef CONFIG_DEBUG_OBJECTS_FREE
 static void __debug_check_no_obj_freed(const void *address, unsigned long size)
index 872a15a2a6374017af2bc0f8a446f86736f9b45e..f3a217ea03888dcdad20e12fdc8ef196b1897456 100644 (file)
@@ -980,23 +980,23 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
 #ifndef CONFIG_PROVE_LOCKING
        if (expected == FAILURE && debug_locks) {
                expected_testcase_failures++;
-               printk("failed|");
+               pr_cont("failed|");
        }
        else
 #endif
        if (debug_locks != expected) {
                unexpected_testcase_failures++;
-               printk("FAILED|");
+               pr_cont("FAILED|");
 
                dump_stack();
        } else {
                testcase_successes++;
-               printk("  ok  |");
+               pr_cont("  ok  |");
        }
        testcase_total++;
 
        if (debug_locks_verbose)
-               printk(" lockclass mask: %x, debug_locks: %d, expected: %d\n",
+               pr_cont(" lockclass mask: %x, debug_locks: %d, expected: %d\n",
                        lockclass_mask, debug_locks, expected);
        /*
         * Some tests (e.g. double-unlock) might corrupt the preemption
@@ -1021,26 +1021,26 @@ static inline void print_testname(const char *testname)
 #define DO_TESTCASE_1(desc, name, nr)                          \
        print_testname(desc"/"#nr);                             \
        dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK);          \
-       printk("\n");
+       pr_cont("\n");
 
 #define DO_TESTCASE_1B(desc, name, nr)                         \
        print_testname(desc"/"#nr);                             \
        dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK);          \
-       printk("\n");
+       pr_cont("\n");
 
 #define DO_TESTCASE_3(desc, name, nr)                          \
        print_testname(desc"/"#nr);                             \
        dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN);       \
        dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);    \
        dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);    \
-       printk("\n");
+       pr_cont("\n");
 
 #define DO_TESTCASE_3RW(desc, name, nr)                                \
        print_testname(desc"/"#nr);                             \
        dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\
        dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);    \
        dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);    \
-       printk("\n");
+       pr_cont("\n");
 
 #define DO_TESTCASE_6(desc, name)                              \
        print_testname(desc);                                   \
@@ -1050,7 +1050,7 @@ static inline void print_testname(const char *testname)
        dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);          \
        dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);           \
        dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);           \
-       printk("\n");
+       pr_cont("\n");
 
 #define DO_TESTCASE_6_SUCCESS(desc, name)                      \
        print_testname(desc);                                   \
@@ -1060,7 +1060,7 @@ static inline void print_testname(const char *testname)
        dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX);          \
        dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM);           \
        dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM);           \
-       printk("\n");
+       pr_cont("\n");
 
 /*
  * 'read' variant: rlocks must not trigger.
@@ -1073,7 +1073,7 @@ static inline void print_testname(const char *testname)
        dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);          \
        dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);           \
        dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);           \
-       printk("\n");
+       pr_cont("\n");
 
 #define DO_TESTCASE_2I(desc, name, nr)                         \
        DO_TESTCASE_1("hard-"desc, name##_hard, nr);            \
@@ -1726,25 +1726,25 @@ static void ww_tests(void)
        dotest(ww_test_fail_acquire, SUCCESS, LOCKTYPE_WW);
        dotest(ww_test_normal, SUCCESS, LOCKTYPE_WW);
        dotest(ww_test_unneeded_slow, FAILURE, LOCKTYPE_WW);
-       printk("\n");
+       pr_cont("\n");
 
        print_testname("ww contexts mixing");
        dotest(ww_test_two_contexts, FAILURE, LOCKTYPE_WW);
        dotest(ww_test_diff_class, FAILURE, LOCKTYPE_WW);
-       printk("\n");
+       pr_cont("\n");
 
        print_testname("finishing ww context");
        dotest(ww_test_context_done_twice, FAILURE, LOCKTYPE_WW);
        dotest(ww_test_context_unlock_twice, FAILURE, LOCKTYPE_WW);
        dotest(ww_test_context_fini_early, FAILURE, LOCKTYPE_WW);
        dotest(ww_test_context_lock_after_done, FAILURE, LOCKTYPE_WW);
-       printk("\n");
+       pr_cont("\n");
 
        print_testname("locking mismatches");
        dotest(ww_test_object_unlock_twice, FAILURE, LOCKTYPE_WW);
        dotest(ww_test_object_lock_unbalanced, FAILURE, LOCKTYPE_WW);
        dotest(ww_test_object_lock_stale_context, FAILURE, LOCKTYPE_WW);
-       printk("\n");
+       pr_cont("\n");
 
        print_testname("EDEADLK handling");
        dotest(ww_test_edeadlk_normal, SUCCESS, LOCKTYPE_WW);
@@ -1757,11 +1757,11 @@ static void ww_tests(void)
        dotest(ww_test_edeadlk_acquire_more_edeadlk_slow, FAILURE, LOCKTYPE_WW);
        dotest(ww_test_edeadlk_acquire_wrong, FAILURE, LOCKTYPE_WW);
        dotest(ww_test_edeadlk_acquire_wrong_slow, FAILURE, LOCKTYPE_WW);
-       printk("\n");
+       pr_cont("\n");
 
        print_testname("spinlock nest unlocked");
        dotest(ww_test_spin_nest_unlocked, FAILURE, LOCKTYPE_WW);
-       printk("\n");
+       pr_cont("\n");
 
        printk("  -----------------------------------------------------\n");
        printk("                                 |block | try  |context|\n");
@@ -1771,25 +1771,25 @@ static void ww_tests(void)
        dotest(ww_test_context_block, FAILURE, LOCKTYPE_WW);
        dotest(ww_test_context_try, SUCCESS, LOCKTYPE_WW);
        dotest(ww_test_context_context, SUCCESS, LOCKTYPE_WW);
-       printk("\n");
+       pr_cont("\n");
 
        print_testname("try");
        dotest(ww_test_try_block, FAILURE, LOCKTYPE_WW);
        dotest(ww_test_try_try, SUCCESS, LOCKTYPE_WW);
        dotest(ww_test_try_context, FAILURE, LOCKTYPE_WW);
-       printk("\n");
+       pr_cont("\n");
 
        print_testname("block");
        dotest(ww_test_block_block, FAILURE, LOCKTYPE_WW);
        dotest(ww_test_block_try, SUCCESS, LOCKTYPE_WW);
        dotest(ww_test_block_context, FAILURE, LOCKTYPE_WW);
-       printk("\n");
+       pr_cont("\n");
 
        print_testname("spinlock");
        dotest(ww_test_spin_block, FAILURE, LOCKTYPE_WW);
        dotest(ww_test_spin_try, SUCCESS, LOCKTYPE_WW);
        dotest(ww_test_spin_context, FAILURE, LOCKTYPE_WW);
-       printk("\n");
+       pr_cont("\n");
 }
 
 void locking_selftest(void)
@@ -1829,32 +1829,32 @@ void locking_selftest(void)
 
        printk("  --------------------------------------------------------------------------\n");
        print_testname("recursive read-lock");
-       printk("             |");
+       pr_cont("             |");
        dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK);
-       printk("             |");
+       pr_cont("             |");
        dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM);
-       printk("\n");
+       pr_cont("\n");
 
        print_testname("recursive read-lock #2");
-       printk("             |");
+       pr_cont("             |");
        dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK);
-       printk("             |");
+       pr_cont("             |");
        dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM);
-       printk("\n");
+       pr_cont("\n");
 
        print_testname("mixed read-write-lock");
-       printk("             |");
+       pr_cont("             |");
        dotest(rlock_AA2, FAILURE, LOCKTYPE_RWLOCK);
-       printk("             |");
+       pr_cont("             |");
        dotest(rsem_AA2, FAILURE, LOCKTYPE_RWSEM);
-       printk("\n");
+       pr_cont("\n");
 
        print_testname("mixed write-read-lock");
-       printk("             |");
+       pr_cont("             |");
        dotest(rlock_AA3, FAILURE, LOCKTYPE_RWLOCK);
-       printk("             |");
+       pr_cont("             |");
        dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM);
-       printk("\n");
+       pr_cont("\n");
 
        printk("  --------------------------------------------------------------------------\n");
 
index 5e51872b3fc163af2fe82e6d7010b4aba08b612a..fbdf87920093b9b1dbd94e4b370a24e43d6bb8f7 100644 (file)
 #include <linux/uaccess.h>
 #include <linux/module.h>
 
+/*
+ * Note: test functions are marked noinline so that their names appear in
+ * reports.
+ */
+
 static noinline void __init kmalloc_oob_right(void)
 {
        char *ptr;
@@ -411,6 +416,29 @@ static noinline void __init copy_user_test(void)
        kfree(kmem);
 }
 
+static noinline void __init use_after_scope_test(void)
+{
+       volatile char *volatile p;
+
+       pr_info("use-after-scope on int\n");
+       {
+               int local = 0;
+
+               p = (char *)&local;
+       }
+       p[0] = 1;
+       p[3] = 1;
+
+       pr_info("use-after-scope on array\n");
+       {
+               char local[1024] = {0};
+
+               p = local;
+       }
+       p[0] = 1;
+       p[1023] = 1;
+}
+
 static int __init kmalloc_tests_init(void)
 {
        kmalloc_oob_right();
@@ -436,6 +464,7 @@ static int __init kmalloc_tests_init(void)
        kasan_global_oob();
        ksize_unpoisons_memory();
        copy_user_test();
+       use_after_scope_test();
        return -EAGAIN;
 }
 
index eff3de359d50a30588abf70676dc6993c751471d..d4a6e40015128c626f606e339474d8b23d90607e 100644 (file)
@@ -1456,9 +1456,9 @@ bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr,
                new_ptl = pmd_lockptr(mm, new_pmd);
                if (new_ptl != old_ptl)
                        spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
-               if (pmd_present(*old_pmd) && pmd_dirty(*old_pmd))
-                       force_flush = true;
                pmd = pmdp_huge_get_and_clear(mm, old_addr, old_pmd);
+               if (pmd_present(pmd) && pmd_dirty(pmd))
+                       force_flush = true;
                VM_BUG_ON(!pmd_none(*new_pmd));
 
                if (pmd_move_must_withdraw(new_ptl, old_ptl) &&
index 70c009741aab705c6bb344df1f1851d9582bc7a7..0e9505f66ec133bd401d6ec9208d1a6f17b95fb7 100644 (file)
@@ -764,6 +764,25 @@ EXPORT_SYMBOL(__asan_storeN_noabort);
 void __asan_handle_no_return(void) {}
 EXPORT_SYMBOL(__asan_handle_no_return);
 
+/* Emitted by compiler to poison large objects when they go out of scope. */
+void __asan_poison_stack_memory(const void *addr, size_t size)
+{
+       /*
+        * Addr is KASAN_SHADOW_SCALE_SIZE-aligned and the object is surrounded
+        * by redzones, so we simply round up size to simplify logic.
+        */
+       kasan_poison_shadow(addr, round_up(size, KASAN_SHADOW_SCALE_SIZE),
+                           KASAN_USE_AFTER_SCOPE);
+}
+EXPORT_SYMBOL(__asan_poison_stack_memory);
+
+/* Emitted by compiler to unpoison large objects when they go into scope. */
+void __asan_unpoison_stack_memory(const void *addr, size_t size)
+{
+       kasan_unpoison_shadow(addr, size);
+}
+EXPORT_SYMBOL(__asan_unpoison_stack_memory);
+
 #ifdef CONFIG_MEMORY_HOTPLUG
 static int kasan_mem_notifier(struct notifier_block *nb,
                        unsigned long action, void *data)
index e5c2181fee6f5ddeee0a6f912ba810637eeceb0c..1c260e6b3b3c6a1f26fc1e13a0fdb39099bbbf68 100644 (file)
@@ -21,6 +21,7 @@
 #define KASAN_STACK_MID         0xF2
 #define KASAN_STACK_RIGHT       0xF3
 #define KASAN_STACK_PARTIAL     0xF4
+#define KASAN_USE_AFTER_SCOPE   0xF8
 
 /* Don't break randconfig/all*config builds */
 #ifndef KASAN_ABI_VERSION
@@ -53,6 +54,9 @@ struct kasan_global {
 #if KASAN_ABI_VERSION >= 4
        struct kasan_source_location *location;
 #endif
+#if KASAN_ABI_VERSION >= 5
+       char *odr_indicator;
+#endif
 };
 
 /**
index 24c1211fe9d5e16afa715fb0b69f4aee96424224..073325aedc68542a3b05f3859d89a9872aef815f 100644 (file)
@@ -90,6 +90,9 @@ static void print_error_description(struct kasan_access_info *info)
        case KASAN_KMALLOC_FREE:
                bug_type = "use-after-free";
                break;
+       case KASAN_USE_AFTER_SCOPE:
+               bug_type = "use-after-scope";
+               break;
        }
 
        pr_err("BUG: KASAN: %s in %pS at addr %p\n",
index 728d7790dc2da27175d403f314a359cec70da5fc..87e1a7ca38463d0809e54ca8c74d4e2b0eb415eb 100644 (file)
@@ -103,6 +103,7 @@ static struct khugepaged_scan khugepaged_scan = {
        .mm_head = LIST_HEAD_INIT(khugepaged_scan.mm_head),
 };
 
+#ifdef CONFIG_SYSFS
 static ssize_t scan_sleep_millisecs_show(struct kobject *kobj,
                                         struct kobj_attribute *attr,
                                         char *buf)
@@ -295,6 +296,7 @@ struct attribute_group khugepaged_attr_group = {
        .attrs = khugepaged_attr,
        .name = "khugepaged",
 };
+#endif /* CONFIG_SYSFS */
 
 #define VM_NO_KHUGEPAGED (VM_SPECIAL | VM_HUGETLB)
 
index 145a4258ddbc775d1d2acf133a21b83280a8f282..cdbed8aaa4268c94abb44a8adf6c93873d37856a 100644 (file)
@@ -190,10 +190,13 @@ unsigned int munlock_vma_page(struct page *page)
         */
        spin_lock_irq(zone_lru_lock(zone));
 
-       nr_pages = hpage_nr_pages(page);
-       if (!TestClearPageMlocked(page))
+       if (!TestClearPageMlocked(page)) {
+               /* Potentially, PTE-mapped THP: do not skip the rest PTEs */
+               nr_pages = 1;
                goto unlock_out;
+       }
 
+       nr_pages = hpage_nr_pages(page);
        __mod_zone_page_state(zone, NR_MLOCK, -nr_pages);
 
        if (__munlock_isolate_lru_page(page, true)) {
index 6ccecc03f56ad05940484a481c5a092f1ad245ef..30d7d2482eea1d04cf72b03bcd54d1d293f666e4 100644 (file)
@@ -149,14 +149,18 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
                if (pte_none(*old_pte))
                        continue;
 
+               pte = ptep_get_and_clear(mm, old_addr, old_pte);
                /*
-                * We are remapping a dirty PTE, make sure to
-                * flush TLB before we drop the PTL for the
+                * If we are remapping a dirty PTE, make sure
+                * to flush TLB before we drop the PTL for the
                 * old PTE or we may race with page_mkclean().
+                *
+                * This check has to be done after we removed the
+                * old PTE from page tables or another thread may
+                * dirty it after the check and before the removal.
                 */
-               if (pte_present(*old_pte) && pte_dirty(*old_pte))
+               if (pte_present(pte) && pte_dirty(pte))
                        force_flush = true;
-               pte = ptep_get_and_clear(mm, old_addr, old_pte);
                pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
                pte = move_soft_dirty_pte(pte);
                set_pte_at(mm, new_addr, new_pte, pte);
index 166ebf5d2bceda1bdc9a824b6b3040f28588a171..9d32e1cb9f38f7dd508f1be0273d0721974b2c05 100644 (file)
@@ -1848,6 +1848,18 @@ unlock:
        return error;
 }
 
+/*
+ * This is like autoremove_wake_function, but it removes the wait queue
+ * entry unconditionally - even if something else had already woken the
+ * target.
+ */
+static int synchronous_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
+{
+       int ret = default_wake_function(wait, mode, sync, key);
+       list_del_init(&wait->task_list);
+       return ret;
+}
+
 static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
        struct inode *inode = file_inode(vma->vm_file);
@@ -1883,7 +1895,7 @@ static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
                    vmf->pgoff >= shmem_falloc->start &&
                    vmf->pgoff < shmem_falloc->next) {
                        wait_queue_head_t *shmem_falloc_waitq;
-                       DEFINE_WAIT(shmem_fault_wait);
+                       DEFINE_WAIT_FUNC(shmem_fault_wait, synchronous_wake_function);
 
                        ret = VM_FAULT_NOPAGE;
                        if ((vmf->flags & FAULT_FLAG_ALLOW_RETRY) &&
@@ -2665,6 +2677,7 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset,
                spin_lock(&inode->i_lock);
                inode->i_private = NULL;
                wake_up_all(&shmem_falloc_waitq);
+               WARN_ON_ONCE(!list_empty(&shmem_falloc_waitq.task_list));
                spin_unlock(&inode->i_lock);
                error = 0;
                goto out;
index a01cce450a2692bf4b3c28b105d0444256a0f176..8d8c62d89e6d101bce9373c20258d1bbc9df7fa2 100644 (file)
@@ -283,7 +283,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
 
                        if (!trylock_page(page))
                                continue;
-                       WARN_ON(page_to_pgoff(page) != index);
+                       WARN_ON(page_to_index(page) != index);
                        if (PageWriteback(page)) {
                                unlock_page(page);
                                continue;
@@ -371,7 +371,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
                        }
 
                        lock_page(page);
-                       WARN_ON(page_to_pgoff(page) != index);
+                       WARN_ON(page_to_index(page) != index);
                        wait_on_page_writeback(page);
                        truncate_inode_page(mapping, page);
                        unlock_page(page);
@@ -492,7 +492,7 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
                        if (!trylock_page(page))
                                continue;
 
-                       WARN_ON(page_to_pgoff(page) != index);
+                       WARN_ON(page_to_index(page) != index);
 
                        /* Middle of THP: skip */
                        if (PageTransTail(page)) {
@@ -612,7 +612,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
                        }
 
                        lock_page(page);
-                       WARN_ON(page_to_pgoff(page) != index);
+                       WARN_ON(page_to_index(page) != index);
                        if (page->mapping != mapping) {
                                unlock_page(page);
                                continue;
index 76fda22681480b68c9432dce3d18a4e0d89516e7..d75cdf360730183e2f3690795b6bac8bcc594d36 100644 (file)
@@ -2354,6 +2354,8 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc
                        }
                }
 
+               cond_resched();
+
                if (nr_reclaimed < nr_to_reclaim || scan_adjusted)
                        continue;
 
index 617475f529f42aed1e1ba34565e034ed7cad8157..fb1f9183d89a360d7b7851a9083e098ff5696b8c 100644 (file)
@@ -348,7 +348,7 @@ static unsigned long count_shadow_nodes(struct shrinker *shrinker,
        shadow_nodes = list_lru_shrink_count(&workingset_shadow_nodes, sc);
        local_irq_enable();
 
-       if (memcg_kmem_enabled()) {
+       if (sc->memcg) {
                pages = mem_cgroup_node_nr_lru_pages(sc->memcg, sc->nid,
                                                     LRU_ALL_FILE);
        } else {
index 7f663092f6de49831680600b2a83aedc15904bac..0dc85eb1cb7addd08a8b3071e076fcacd784e4e2 100644 (file)
@@ -3282,7 +3282,7 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
                                                             &tvlv_tt_data,
                                                             &tt_change,
                                                             &tt_len);
-               if (!tt_len)
+               if (!tt_len || !tvlv_len)
                        goto unlock;
 
                /* Copy the last orig_node's OGM buffer */
@@ -3300,7 +3300,7 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
                                                             &tvlv_tt_data,
                                                             &tt_change,
                                                             &tt_len);
-               if (!tt_len)
+               if (!tt_len || !tvlv_len)
                        goto out;
 
                /* fill the rest of the tvlv with the real TT entries */
index e120307c6e36ab1173232ee1d4fb1730f5dbae60..f88c4df3f91efc1464a3db29ef961714a2f40506 100644 (file)
@@ -898,6 +898,7 @@ int br_sysfs_addbr(struct net_device *dev)
        if (!br->ifobj) {
                pr_info("%s: can't add kobject (directory) %s/%s\n",
                        __func__, dev->name, SYSFS_BRIDGE_PORT_SUBDIR);
+               err = -ENOMEM;
                goto out3;
        }
        return 0;
index aa209b1066c9699a12510055e70ae79b33ee05b7..92cbbd2afddbf1bfb6a79d2fc7112fdb63b3711e 100644 (file)
@@ -1107,10 +1107,7 @@ static struct net_proto_family caif_family_ops = {
 
 static int __init caif_sktinit_module(void)
 {
-       int err = sock_register(&caif_family_ops);
-       if (!err)
-               return err;
-       return 0;
+       return sock_register(&caif_family_ops);
 }
 
 static void __exit caif_sktexit_module(void)
index 972c187d40abb0f54a30a076e60359a5f1878a0c..b075f028d7e23958e9433a4b19f4475ad930b547 100644 (file)
@@ -499,6 +499,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
                if (optlen % sizeof(struct can_filter) != 0)
                        return -EINVAL;
 
+               if (optlen > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
+                       return -EINVAL;
+
                count = optlen / sizeof(struct can_filter);
 
                if (count > 1) {
index 3937b1b68d5bc7ad50691716ac1612332a5dc997..18e8893d4be59905ba1053fffea7cc16d0e054af 100644 (file)
@@ -95,7 +95,6 @@ static void flow_cache_gc_task(struct work_struct *work)
        list_for_each_entry_safe(fce, n, &gc_list, u.gc_list) {
                flow_entry_kill(fce, xfrm);
                atomic_dec(&xfrm->flow_cache_gc_count);
-               WARN_ON(atomic_read(&xfrm->flow_cache_gc_count) < 0);
        }
 }
 
@@ -236,9 +235,8 @@ flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir,
                if (fcp->hash_count > fc->high_watermark)
                        flow_cache_shrink(fc, fcp);
 
-               if (fcp->hash_count > 2 * fc->high_watermark ||
-                   atomic_read(&net->xfrm.flow_cache_gc_count) > fc->high_watermark) {
-                       atomic_inc(&net->xfrm.flow_cache_genid);
+               if (atomic_read(&net->xfrm.flow_cache_gc_count) >
+                   2 * num_online_cpus() * fc->high_watermark) {
                        flo = ERR_PTR(-ENOBUFS);
                        goto ret_object;
                }
index deb35acbefd0012024e7b73679d26b48a973db8f..a6196cf844f6644782fa8c3a743f35db7b9af33e 100644 (file)
@@ -931,8 +931,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
               + nla_total_size(4) /* IFLA_PROMISCUITY */
               + nla_total_size(4) /* IFLA_NUM_TX_QUEUES */
               + nla_total_size(4) /* IFLA_NUM_RX_QUEUES */
-              + nla_total_size(4) /* IFLA_MAX_GSO_SEGS */
-              + nla_total_size(4) /* IFLA_MAX_GSO_SIZE */
+              + nla_total_size(4) /* IFLA_GSO_MAX_SEGS */
+              + nla_total_size(4) /* IFLA_GSO_MAX_SIZE */
               + nla_total_size(1) /* IFLA_OPERSTATE */
               + nla_total_size(1) /* IFLA_LINKMODE */
               + nla_total_size(4) /* IFLA_CARRIER_CHANGES */
index 5e3ca414357e2404db28eeacc5e9306051161493..00a074dbfe9bf169c2b81498e6ae265199745b22 100644 (file)
@@ -715,7 +715,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
                val = min_t(u32, val, sysctl_wmem_max);
 set_sndbuf:
                sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
-               sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF);
+               sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF);
                /* Wake up sending tasks if we upped the value. */
                sk->sk_write_space(sk);
                break;
@@ -751,7 +751,7 @@ set_rcvbuf:
                 * returning the value we actually used in getsockopt
                 * is the most desirable behavior.
                 */
-               sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);
+               sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF);
                break;
 
        case SO_RCVBUFFORCE:
index 4f6c1862dfd25271303873acbc5c85b80b9f00c1..3202d75329b504b6442441becc31157e0c2be7a5 100644 (file)
@@ -1353,6 +1353,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
 dcb_unlock:
        spin_unlock_bh(&dcb_lock);
 nla_put_failure:
+       err = -EMSGSIZE;
        return err;
 }
 
index b567c8725aea304d2b15f1d6ed2164c1bd16d1a9..edbe59d203efcff5b01978ff27c72756dc4ed6ba 100644 (file)
@@ -700,6 +700,7 @@ int dccp_invalid_packet(struct sk_buff *skb)
 {
        const struct dccp_hdr *dh;
        unsigned int cscov;
+       u8 dccph_doff;
 
        if (skb->pkt_type != PACKET_HOST)
                return 1;
@@ -721,18 +722,19 @@ int dccp_invalid_packet(struct sk_buff *skb)
        /*
         * If P.Data Offset is too small for packet type, drop packet and return
         */
-       if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
-               DCCP_WARN("P.Data Offset(%u) too small\n", dh->dccph_doff);
+       dccph_doff = dh->dccph_doff;
+       if (dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
+               DCCP_WARN("P.Data Offset(%u) too small\n", dccph_doff);
                return 1;
        }
        /*
         * If P.Data Offset is too too large for packet, drop packet and return
         */
-       if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) {
-               DCCP_WARN("P.Data Offset(%u) too large\n", dh->dccph_doff);
+       if (!pskb_may_pull(skb, dccph_doff * sizeof(u32))) {
+               DCCP_WARN("P.Data Offset(%u) too large\n", dccph_doff);
                return 1;
        }
-
+       dh = dccp_hdr(skb);
        /*
         * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet
         * has short sequence numbers), drop packet and return
index a6902c1e2f28f79c609bf511de2781908e2e1abd..7899919cd9f0e3435828b1cca9e2ef897a75a3b7 100644 (file)
@@ -233,6 +233,8 @@ int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct device *dev,
                genphy_read_status(phydev);
                if (ds->ops->adjust_link)
                        ds->ops->adjust_link(ds, port, phydev);
+
+               put_device(&phydev->mdio.dev);
        }
 
        return 0;
@@ -504,15 +506,8 @@ dsa_switch_setup(struct dsa_switch_tree *dst, int index,
 
 void dsa_cpu_dsa_destroy(struct device_node *port_dn)
 {
-       struct phy_device *phydev;
-
-       if (of_phy_is_fixed_link(port_dn)) {
-               phydev = of_phy_find_device(port_dn);
-               if (phydev) {
-                       phy_device_free(phydev);
-                       fixed_phy_unregister(phydev);
-               }
-       }
+       if (of_phy_is_fixed_link(port_dn))
+               of_phy_deregister_fixed_link(port_dn);
 }
 
 static void dsa_switch_destroy(struct dsa_switch *ds)
index f8a7d9aab4372aed09dc9cd12baba0df1ce8f8ba..5fff951a0a4928ccf28fb681be86c7df6a05e94f 100644 (file)
@@ -28,8 +28,10 @@ static struct dsa_switch_tree *dsa_get_dst(u32 tree)
        struct dsa_switch_tree *dst;
 
        list_for_each_entry(dst, &dsa_switch_trees, list)
-               if (dst->tree == tree)
+               if (dst->tree == tree) {
+                       kref_get(&dst->refcount);
                        return dst;
+               }
        return NULL;
 }
 
index 6b1282c006b145d2b96921243b9e26e91c427f88..30e2e21d76196fdfc404ab036a3e6efb9905d3b8 100644 (file)
@@ -1125,7 +1125,7 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
        p->phy_interface = mode;
 
        phy_dn = of_parse_phandle(port_dn, "phy-handle", 0);
-       if (of_phy_is_fixed_link(port_dn)) {
+       if (!phy_dn && of_phy_is_fixed_link(port_dn)) {
                /* In the case of a fixed PHY, the DT node associated
                 * to the fixed PHY is the Port DT node
                 */
@@ -1135,7 +1135,7 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
                        return ret;
                }
                phy_is_fixed = true;
-               phy_dn = port_dn;
+               phy_dn = of_node_get(port_dn);
        }
 
        if (ds->ops->get_phy_flags)
@@ -1154,6 +1154,7 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
                        ret = dsa_slave_phy_connect(p, slave_dev, phy_id);
                        if (ret) {
                                netdev_err(slave_dev, "failed to connect to phy%d: %d\n", phy_id, ret);
+                               of_node_put(phy_dn);
                                return ret;
                        }
                } else {
@@ -1162,6 +1163,8 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
                                                phy_flags,
                                                p->phy_interface);
                }
+
+               of_node_put(phy_dn);
        }
 
        if (p->phy && phy_is_fixed)
@@ -1174,6 +1177,8 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
                ret = dsa_slave_phy_connect(p, slave_dev, p->port);
                if (ret) {
                        netdev_err(slave_dev, "failed to connect to port %d: %d\n", p->port, ret);
+                       if (phy_is_fixed)
+                               of_phy_deregister_fixed_link(port_dn);
                        return ret;
                }
        }
@@ -1289,10 +1294,18 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
 void dsa_slave_destroy(struct net_device *slave_dev)
 {
        struct dsa_slave_priv *p = netdev_priv(slave_dev);
+       struct dsa_switch *ds = p->parent;
+       struct device_node *port_dn;
+
+       port_dn = ds->ports[p->port].dn;
 
        netif_carrier_off(slave_dev);
-       if (p->phy)
+       if (p->phy) {
                phy_disconnect(p->phy);
+
+               if (of_phy_is_fixed_link(port_dn))
+                       of_phy_deregister_fixed_link(port_dn);
+       }
        unregister_netdev(slave_dev);
        free_netdev(slave_dev);
 }
index 300b06888fdfd0139eddf202b1d4ef9ee90c1f76..b54b3ca939db3984e8c5f839d8f56f01e60dea9f 100644 (file)
@@ -715,6 +715,7 @@ config DEFAULT_TCP_CONG
        default "reno" if DEFAULT_RENO
        default "dctcp" if DEFAULT_DCTCP
        default "cdg" if DEFAULT_CDG
+       default "bbr" if DEFAULT_BBR
        default "cubic"
 
 config TCP_MD5SIG
index 5ddf5cda07f4173b0c110c034390428fe2928097..215143246e4b3e57440aba0fd314d0e96acd22a7 100644 (file)
@@ -1233,7 +1233,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
                fixedid = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID);
 
                /* fixed ID is invalid if DF bit is not set */
-               if (fixedid && !(iph->frag_off & htons(IP_DF)))
+               if (fixedid && !(ip_hdr(skb)->frag_off & htons(IP_DF)))
                        goto out;
        }
 
index d95631d0924899f17549e69801567bed076491b9..20fb25e3027bbbf8b8c2068751caf40df939546d 100644 (file)
@@ -476,7 +476,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
                esph = (void *)skb_push(skb, 4);
                *seqhi = esph->spi;
                esph->spi = esph->seq_no;
-               esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.input.hi);
+               esph->seq_no = XFRM_SKB_CB(skb)->seq.input.hi;
                aead_request_set_callback(req, 0, esp_input_done_esn, skb);
        }
 
index 026f309c51e9b6143e74efe2d31c8c5e7a7a3c26..e3665bf7a7f373cfb2cea7a57a9ba478b9cf11df 100644 (file)
@@ -719,6 +719,13 @@ static unsigned char update_suffix(struct key_vector *tn)
 {
        unsigned char slen = tn->pos;
        unsigned long stride, i;
+       unsigned char slen_max;
+
+       /* only vector 0 can have a suffix length greater than or equal to
+        * tn->pos + tn->bits, the second highest node will have a suffix
+        * length at most of tn->pos + tn->bits - 1
+        */
+       slen_max = min_t(unsigned char, tn->pos + tn->bits - 1, tn->slen);
 
        /* search though the list of children looking for nodes that might
         * have a suffix greater than the one we currently have.  This is
@@ -736,12 +743,8 @@ static unsigned char update_suffix(struct key_vector *tn)
                slen = n->slen;
                i &= ~(stride - 1);
 
-               /* if slen covers all but the last bit we can stop here
-                * there will be nothing longer than that since only node
-                * 0 and 1 << (bits - 1) could have that as their suffix
-                * length.
-                */
-               if ((slen + 1) >= (tn->pos + tn->bits))
+               /* stop searching if we have hit the maximum possible value */
+               if (slen >= slen_max)
                        break;
        }
 
@@ -913,39 +916,27 @@ static struct key_vector *resize(struct trie *t, struct key_vector *tn)
                return collapse(t, tn);
 
        /* update parent in case halve failed */
-       tp = node_parent(tn);
-
-       /* Return if at least one deflate was run */
-       if (max_work != MAX_WORK)
-               return tp;
-
-       /* push the suffix length to the parent node */
-       if (tn->slen > tn->pos) {
-               unsigned char slen = update_suffix(tn);
-
-               if (slen > tp->slen)
-                       tp->slen = slen;
-       }
-
-       return tp;
+       return node_parent(tn);
 }
 
-static void leaf_pull_suffix(struct key_vector *tp, struct key_vector *l)
+static void node_pull_suffix(struct key_vector *tn, unsigned char slen)
 {
-       while ((tp->slen > tp->pos) && (tp->slen > l->slen)) {
-               if (update_suffix(tp) > l->slen)
+       unsigned char node_slen = tn->slen;
+
+       while ((node_slen > tn->pos) && (node_slen > slen)) {
+               slen = update_suffix(tn);
+               if (node_slen == slen)
                        break;
-               tp = node_parent(tp);
+
+               tn = node_parent(tn);
+               node_slen = tn->slen;
        }
 }
 
-static void leaf_push_suffix(struct key_vector *tn, struct key_vector *l)
+static void node_push_suffix(struct key_vector *tn, unsigned char slen)
 {
-       /* if this is a new leaf then tn will be NULL and we can sort
-        * out parent suffix lengths as a part of trie_rebalance
-        */
-       while (tn->slen < l->slen) {
-               tn->slen = l->slen;
+       while (tn->slen < slen) {
+               tn->slen = slen;
                tn = node_parent(tn);
        }
 }
@@ -1066,6 +1057,7 @@ static int fib_insert_node(struct trie *t, struct key_vector *tp,
        }
 
        /* Case 3: n is NULL, and will just insert a new leaf */
+       node_push_suffix(tp, new->fa_slen);
        NODE_INIT_PARENT(l, tp);
        put_child_root(tp, key, l);
        trie_rebalance(t, tp);
@@ -1107,7 +1099,7 @@ static int fib_insert_alias(struct trie *t, struct key_vector *tp,
        /* if we added to the tail node then we need to update slen */
        if (l->slen < new->fa_slen) {
                l->slen = new->fa_slen;
-               leaf_push_suffix(tp, l);
+               node_push_suffix(tp, new->fa_slen);
        }
 
        return 0;
@@ -1499,6 +1491,8 @@ static void fib_remove_alias(struct trie *t, struct key_vector *tp,
         * out parent suffix lengths as a part of trie_rebalance
         */
        if (hlist_empty(&l->leaf)) {
+               if (tp->slen == l->slen)
+                       node_pull_suffix(tp, tp->pos);
                put_child_root(tp, l->key, NULL);
                node_free(l);
                trie_rebalance(t, tp);
@@ -1511,7 +1505,7 @@ static void fib_remove_alias(struct trie *t, struct key_vector *tp,
 
        /* update the trie with the latest suffix length */
        l->slen = fa->fa_slen;
-       leaf_pull_suffix(tp, l);
+       node_pull_suffix(tp, fa->fa_slen);
 }
 
 /* Caller must hold RTNL. */
@@ -1783,6 +1777,10 @@ void fib_table_flush_external(struct fib_table *tb)
                        if (IS_TRIE(pn))
                                break;
 
+                       /* update the suffix to address pulled leaves */
+                       if (pn->slen > pn->pos)
+                               update_suffix(pn);
+
                        /* resize completed node */
                        pn = resize(t, pn);
                        cindex = get_index(pkey, pn);
@@ -1849,6 +1847,10 @@ int fib_table_flush(struct net *net, struct fib_table *tb)
                        if (IS_TRIE(pn))
                                break;
 
+                       /* update the suffix to address pulled leaves */
+                       if (pn->slen > pn->pos)
+                               update_suffix(pn);
+
                        /* resize completed node */
                        pn = resize(t, pn);
                        cindex = get_index(pkey, pn);
index 105908d841a359bb433621b286398a2821852645..877bdb02e887f5cf7ce1c4610123484a22f89310 100644 (file)
@@ -107,6 +107,8 @@ int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
        if (unlikely(!skb))
                return 0;
 
+       skb->protocol = htons(ETH_P_IP);
+
        return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
                       net, sk, skb, NULL, skb_dst(skb)->dev,
                       dst_output);
index c3776ff6749f18d1bf3c5c5084d3e7656291539d..b3cc1335adbc1a20dcd225d0501b0a286d27e3c8 100644 (file)
@@ -24,10 +24,11 @@ int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned int addr_t
        struct flowi4 fl4 = {};
        __be32 saddr = iph->saddr;
        __u8 flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
+       struct net_device *dev = skb_dst(skb)->dev;
        unsigned int hh_len;
 
        if (addr_type == RTN_UNSPEC)
-               addr_type = inet_addr_type(net, saddr);
+               addr_type = inet_addr_type_dev_table(net, dev, saddr);
        if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST)
                flags |= FLOWI_FLAG_ANYSRC;
        else
@@ -40,6 +41,8 @@ int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned int addr_t
        fl4.saddr = saddr;
        fl4.flowi4_tos = RT_TOS(iph->tos);
        fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
+       if (!fl4.flowi4_oif)
+               fl4.flowi4_oif = l3mdev_master_ifindex(dev);
        fl4.flowi4_mark = skb->mark;
        fl4.flowi4_flags = flags;
        rt = ip_route_output_key(net, &fl4);
index b31df597fd37e4e8fa41777d7883973a6c852254..697538464e6e31f237d4a909174fe6a5fb267367 100644 (file)
@@ -1201,8 +1201,8 @@ static int translate_compat_table(struct xt_table_info **pinfo,
 
        newinfo->number = compatr->num_entries;
        for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
-               newinfo->hook_entry[i] = info->hook_entry[i];
-               newinfo->underflow[i] = info->underflow[i];
+               newinfo->hook_entry[i] = compatr->hook_entry[i];
+               newinfo->underflow[i] = compatr->underflow[i];
        }
        entry1 = newinfo->entries;
        pos = entry1;
index 205e2000d3950d16b22d5fd16f5ad3289f09c712..96b8e2b957313d36c0c6d339fb21754d71d691ea 100644 (file)
@@ -657,6 +657,10 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len,
        if (len > 0xFFFF)
                return -EMSGSIZE;
 
+       /* Must have at least a full ICMP header. */
+       if (len < icmph_len)
+               return -EINVAL;
+
        /*
         *      Check the flags.
         */
index a27b9c0e27c08b4e4aeaff3d0bfdf3ae561ba4d8..c71d49ce0c9379cd68317bcc135b7a2761110887 100644 (file)
@@ -128,6 +128,23 @@ int sysctl_tcp_invalid_ratelimit __read_mostly = HZ/2;
 #define REXMIT_LOST    1 /* retransmit packets marked lost */
 #define REXMIT_NEW     2 /* FRTO-style transmit of unsent/new packets */
 
+static void tcp_gro_dev_warn(struct sock *sk, const struct sk_buff *skb)
+{
+       static bool __once __read_mostly;
+
+       if (!__once) {
+               struct net_device *dev;
+
+               __once = true;
+
+               rcu_read_lock();
+               dev = dev_get_by_index_rcu(sock_net(sk), skb->skb_iif);
+               pr_warn("%s: Driver has suspect GRO implementation, TCP performance may be compromised.\n",
+                       dev ? dev->name : "Unknown driver");
+               rcu_read_unlock();
+       }
+}
+
 /* Adapt the MSS value used to make delayed ack decision to the
  * real world.
  */
@@ -144,7 +161,10 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)
         */
        len = skb_shinfo(skb)->gso_size ? : skb->len;
        if (len >= icsk->icsk_ack.rcv_mss) {
-               icsk->icsk_ack.rcv_mss = len;
+               icsk->icsk_ack.rcv_mss = min_t(unsigned int, len,
+                                              tcp_sk(sk)->advmss);
+               if (unlikely(icsk->icsk_ack.rcv_mss != len))
+                       tcp_gro_dev_warn(sk, skb);
        } else {
                /* Otherwise, we make more careful check taking into account,
                 * that SACKs block is variable.
index 37874e2f30edf98f31e2a5097761143d507d5b95..ccf40550c475d31bcbc0565daa4a81428e5c9c58 100644 (file)
@@ -139,7 +139,8 @@ void ip6_datagram_release_cb(struct sock *sk)
 }
 EXPORT_SYMBOL_GPL(ip6_datagram_release_cb);
 
-static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr,
+                          int addr_len)
 {
        struct sockaddr_in6     *usin = (struct sockaddr_in6 *) uaddr;
        struct inet_sock        *inet = inet_sk(sk);
@@ -252,6 +253,7 @@ ipv4_connected:
 out:
        return err;
 }
+EXPORT_SYMBOL_GPL(__ip6_datagram_connect);
 
 int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
index 060a60b2f8a6db074167e389b56893337c887fe9..111ba55fd512fb9f2b6f6af6c7084b71cc9bbf22 100644 (file)
@@ -418,7 +418,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
                esph = (void *)skb_push(skb, 4);
                *seqhi = esph->spi;
                esph->spi = esph->seq_no;
-               esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.input.hi);
+               esph->seq_no = XFRM_SKB_CB(skb)->seq.input.hi;
                aead_request_set_callback(req, 0, esp_input_done_esn, skb);
        }
 
index 7370ad2e693a33d7db78c311c7e47c001c80df7c..2772004ba5a18848bd818434951fb10d758be90d 100644 (file)
@@ -447,8 +447,10 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
 
        if (__ipv6_addr_needs_scope_id(addr_type))
                iif = skb->dev->ifindex;
-       else
-               iif = l3mdev_master_ifindex(skb_dst(skb)->dev);
+       else {
+               dst = skb_dst(skb);
+               iif = l3mdev_master_ifindex(dst ? dst->dev : skb->dev);
+       }
 
        /*
         *      Must not send error if the source does not uniquely
index 1fcf61f1cbc33f09919624c78ab918b6258d147f..89c59e656f44939863ceada610d3442d2de666ba 100644 (file)
@@ -99,7 +99,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
                segs = ops->callbacks.gso_segment(skb, features);
        }
 
-       if (IS_ERR(segs))
+       if (IS_ERR_OR_NULL(segs))
                goto out;
 
        gso_partial = !!(skb_shinfo(segs)->gso_type & SKB_GSO_PARTIAL);
index 0a4759b89da24c8bf50830659545b9f7d231a065..d76674efe523cf041bf2ef57f5b861b3707dd05e 100644 (file)
@@ -1181,7 +1181,6 @@ route_lookup:
        if (err)
                return err;
 
-       skb->protocol = htons(ETH_P_IPV6);
        skb_push(skb, sizeof(struct ipv6hdr));
        skb_reset_network_header(skb);
        ipv6h = ipv6_hdr(skb);
index 8a02ca8a11af4b388bfe996711458efd46b641cf..c299c1e2bbf06ed31bc9fd30c7c96111fe606fc5 100644 (file)
@@ -1138,6 +1138,33 @@ static struct xfrm6_protocol vti_ipcomp6_protocol __read_mostly = {
        .priority       =       100,
 };
 
+static bool is_vti6_tunnel(const struct net_device *dev)
+{
+       return dev->netdev_ops == &vti6_netdev_ops;
+}
+
+static int vti6_device_event(struct notifier_block *unused,
+                            unsigned long event, void *ptr)
+{
+       struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+       struct ip6_tnl *t = netdev_priv(dev);
+
+       if (!is_vti6_tunnel(dev))
+               return NOTIFY_DONE;
+
+       switch (event) {
+       case NETDEV_DOWN:
+               if (!net_eq(t->net, dev_net(dev)))
+                       xfrm_garbage_collect(t->net);
+               break;
+       }
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block vti6_notifier_block __read_mostly = {
+       .notifier_call = vti6_device_event,
+};
+
 /**
  * vti6_tunnel_init - register protocol and reserve needed resources
  *
@@ -1148,6 +1175,8 @@ static int __init vti6_tunnel_init(void)
        const char *msg;
        int err;
 
+       register_netdevice_notifier(&vti6_notifier_block);
+
        msg = "tunnel device";
        err = register_pernet_device(&vti6_net_ops);
        if (err < 0)
@@ -1180,6 +1209,7 @@ xfrm_proto_ah_failed:
 xfrm_proto_esp_failed:
        unregister_pernet_device(&vti6_net_ops);
 pernet_dev_failed:
+       unregister_netdevice_notifier(&vti6_notifier_block);
        pr_err("vti6 init: failed to register %s\n", msg);
        return err;
 }
@@ -1194,6 +1224,7 @@ static void __exit vti6_tunnel_cleanup(void)
        xfrm6_protocol_deregister(&vti_ah6_protocol, IPPROTO_AH);
        xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP);
        unregister_pernet_device(&vti6_net_ops);
+       unregister_netdevice_notifier(&vti6_notifier_block);
 }
 
 module_init(vti6_tunnel_init);
index e4347aeb2e65337a1adbf82f66befc22a83c6606..9948b5ce52dad3a823edede517f17069bd7226dc 100644 (file)
@@ -576,11 +576,11 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
        /* Jumbo payload inhibits frag. header */
        if (ipv6_hdr(skb)->payload_len == 0) {
                pr_debug("payload len = 0\n");
-               return -EINVAL;
+               return 0;
        }
 
        if (find_prev_fhdr(skb, &prevhdr, &nhoff, &fhoff) < 0)
-               return -EINVAL;
+               return 0;
 
        if (!pskb_may_pull(skb, fhoff + sizeof(*fhdr)))
                return -ENOMEM;
index f7aab5ab93a558bd7d60010e15ca15169d1d0ba7..f06b0471f39fc0130f9db69e6c05330e8d5c6909 100644 (file)
@@ -69,7 +69,7 @@ static unsigned int ipv6_defrag(void *priv,
        if (err == -EINPROGRESS)
                return NF_STOLEN;
 
-       return NF_ACCEPT;
+       return err == 0 ? NF_ACCEPT : NF_DROP;
 }
 
 static struct nf_hook_ops ipv6_defrag_ops[] = {
index a5400223fd743ff012ab7318c7ad6845c1f6b36c..10090400c72f19b7dd21d6543a2c1d740a9bd595 100644 (file)
@@ -156,6 +156,7 @@ void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
        fl6.daddr = oip6h->saddr;
        fl6.fl6_sport = otcph->dest;
        fl6.fl6_dport = otcph->source;
+       fl6.flowi6_oif = l3mdev_master_ifindex(skb_dst(oldskb)->dev);
        security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6));
        dst = ip6_route_output(net, NULL, &fl6);
        if (dst->error) {
index 7cca8ac66fe9b07a9f91559667c057113ccc3c19..cd4252346a32d90e8e133bd985811b6241e4bcd7 100644 (file)
@@ -155,6 +155,8 @@ int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
        if (unlikely(!skb))
                return 0;
 
+       skb->protocol = htons(ETH_P_IPV6);
+
        return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
                       net, sk, skb, NULL, skb_dst(skb)->dev,
                       dst_output);
index 982f6c44ea01f053a51afcbb4b271a2e77df2178..8938b6ba57a037b6f95f9dcfd2461d7c3951cdfb 100644 (file)
@@ -61,7 +61,8 @@ static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif
                if ((l2tp->conn_id == tunnel_id) &&
                    net_eq(sock_net(sk), net) &&
                    !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
-                   !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
+                   (!sk->sk_bound_dev_if || !dif ||
+                    sk->sk_bound_dev_if == dif))
                        goto found;
        }
 
@@ -182,15 +183,17 @@ pass_up:
                struct iphdr *iph = (struct iphdr *) skb_network_header(skb);
 
                read_lock_bh(&l2tp_ip_lock);
-               sk = __l2tp_ip_bind_lookup(net, iph->daddr, 0, tunnel_id);
+               sk = __l2tp_ip_bind_lookup(net, iph->daddr, inet_iif(skb),
+                                          tunnel_id);
+               if (!sk) {
+                       read_unlock_bh(&l2tp_ip_lock);
+                       goto discard;
+               }
+
+               sock_hold(sk);
                read_unlock_bh(&l2tp_ip_lock);
        }
 
-       if (sk == NULL)
-               goto discard;
-
-       sock_hold(sk);
-
        if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
                goto discard_put;
 
@@ -256,15 +259,9 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        if (addr->l2tp_family != AF_INET)
                return -EINVAL;
 
-       ret = -EADDRINUSE;
-       read_lock_bh(&l2tp_ip_lock);
-       if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr,
-                                 sk->sk_bound_dev_if, addr->l2tp_conn_id))
-               goto out_in_use;
-
-       read_unlock_bh(&l2tp_ip_lock);
-
        lock_sock(sk);
+
+       ret = -EINVAL;
        if (!sock_flag(sk, SOCK_ZAPPED))
                goto out;
 
@@ -281,25 +278,28 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
                inet->inet_rcv_saddr = inet->inet_saddr = addr->l2tp_addr.s_addr;
        if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
                inet->inet_saddr = 0;  /* Use device */
-       sk_dst_reset(sk);
 
+       write_lock_bh(&l2tp_ip_lock);
+       if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr,
+                                 sk->sk_bound_dev_if, addr->l2tp_conn_id)) {
+               write_unlock_bh(&l2tp_ip_lock);
+               ret = -EADDRINUSE;
+               goto out;
+       }
+
+       sk_dst_reset(sk);
        l2tp_ip_sk(sk)->conn_id = addr->l2tp_conn_id;
 
-       write_lock_bh(&l2tp_ip_lock);
        sk_add_bind_node(sk, &l2tp_ip_bind_table);
        sk_del_node_init(sk);
        write_unlock_bh(&l2tp_ip_lock);
+
        ret = 0;
        sock_reset_flag(sk, SOCK_ZAPPED);
 
 out:
        release_sock(sk);
 
-       return ret;
-
-out_in_use:
-       read_unlock_bh(&l2tp_ip_lock);
-
        return ret;
 }
 
@@ -308,21 +308,24 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
        struct sockaddr_l2tpip *lsa = (struct sockaddr_l2tpip *) uaddr;
        int rc;
 
-       if (sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */
-               return -EINVAL;
-
        if (addr_len < sizeof(*lsa))
                return -EINVAL;
 
        if (ipv4_is_multicast(lsa->l2tp_addr.s_addr))
                return -EINVAL;
 
-       rc = ip4_datagram_connect(sk, uaddr, addr_len);
-       if (rc < 0)
-               return rc;
-
        lock_sock(sk);
 
+       /* Must bind first - autobinding does not work */
+       if (sock_flag(sk, SOCK_ZAPPED)) {
+               rc = -EINVAL;
+               goto out_sk;
+       }
+
+       rc = __ip4_datagram_connect(sk, uaddr, addr_len);
+       if (rc < 0)
+               goto out_sk;
+
        l2tp_ip_sk(sk)->peer_conn_id = lsa->l2tp_conn_id;
 
        write_lock_bh(&l2tp_ip_lock);
@@ -330,7 +333,9 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
        sk_add_bind_node(sk, &l2tp_ip_bind_table);
        write_unlock_bh(&l2tp_ip_lock);
 
+out_sk:
        release_sock(sk);
+
        return rc;
 }
 
index 9978d01ba0bae4eaf34810665d581ddd06579e96..aa821cb639e541fa85a062deeee43516e2d4da8d 100644 (file)
@@ -72,8 +72,9 @@ static struct sock *__l2tp_ip6_bind_lookup(struct net *net,
 
                if ((l2tp->conn_id == tunnel_id) &&
                    net_eq(sock_net(sk), net) &&
-                   !(addr && ipv6_addr_equal(addr, laddr)) &&
-                   !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
+                   (!addr || ipv6_addr_equal(addr, laddr)) &&
+                   (!sk->sk_bound_dev_if || !dif ||
+                    sk->sk_bound_dev_if == dif))
                        goto found;
        }
 
@@ -196,16 +197,17 @@ pass_up:
                struct ipv6hdr *iph = ipv6_hdr(skb);
 
                read_lock_bh(&l2tp_ip6_lock);
-               sk = __l2tp_ip6_bind_lookup(net, &iph->daddr,
-                                           0, tunnel_id);
+               sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, inet6_iif(skb),
+                                           tunnel_id);
+               if (!sk) {
+                       read_unlock_bh(&l2tp_ip6_lock);
+                       goto discard;
+               }
+
+               sock_hold(sk);
                read_unlock_bh(&l2tp_ip6_lock);
        }
 
-       if (sk == NULL)
-               goto discard;
-
-       sock_hold(sk);
-
        if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
                goto discard_put;
 
@@ -266,6 +268,7 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        struct sockaddr_l2tpip6 *addr = (struct sockaddr_l2tpip6 *) uaddr;
        struct net *net = sock_net(sk);
        __be32 v4addr = 0;
+       int bound_dev_if;
        int addr_type;
        int err;
 
@@ -284,13 +287,6 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        if (addr_type & IPV6_ADDR_MULTICAST)
                return -EADDRNOTAVAIL;
 
-       err = -EADDRINUSE;
-       read_lock_bh(&l2tp_ip6_lock);
-       if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr,
-                                  sk->sk_bound_dev_if, addr->l2tp_conn_id))
-               goto out_in_use;
-       read_unlock_bh(&l2tp_ip6_lock);
-
        lock_sock(sk);
 
        err = -EINVAL;
@@ -300,28 +296,25 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        if (sk->sk_state != TCP_CLOSE)
                goto out_unlock;
 
+       bound_dev_if = sk->sk_bound_dev_if;
+
        /* Check if the address belongs to the host. */
        rcu_read_lock();
        if (addr_type != IPV6_ADDR_ANY) {
                struct net_device *dev = NULL;
 
                if (addr_type & IPV6_ADDR_LINKLOCAL) {
-                       if (addr_len >= sizeof(struct sockaddr_in6) &&
-                           addr->l2tp_scope_id) {
-                               /* Override any existing binding, if another
-                                * one is supplied by user.
-                                */
-                               sk->sk_bound_dev_if = addr->l2tp_scope_id;
-                       }
+                       if (addr->l2tp_scope_id)
+                               bound_dev_if = addr->l2tp_scope_id;
 
                        /* Binding to link-local address requires an
-                          interface */
-                       if (!sk->sk_bound_dev_if)
+                        * interface.
+                        */
+                       if (!bound_dev_if)
                                goto out_unlock_rcu;
 
                        err = -ENODEV;
-                       dev = dev_get_by_index_rcu(sock_net(sk),
-                                                  sk->sk_bound_dev_if);
+                       dev = dev_get_by_index_rcu(sock_net(sk), bound_dev_if);
                        if (!dev)
                                goto out_unlock_rcu;
                }
@@ -336,13 +329,22 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        }
        rcu_read_unlock();
 
-       inet->inet_rcv_saddr = inet->inet_saddr = v4addr;
+       write_lock_bh(&l2tp_ip6_lock);
+       if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, bound_dev_if,
+                                  addr->l2tp_conn_id)) {
+               write_unlock_bh(&l2tp_ip6_lock);
+               err = -EADDRINUSE;
+               goto out_unlock;
+       }
+
+       inet->inet_saddr = v4addr;
+       inet->inet_rcv_saddr = v4addr;
+       sk->sk_bound_dev_if = bound_dev_if;
        sk->sk_v6_rcv_saddr = addr->l2tp_addr;
        np->saddr = addr->l2tp_addr;
 
        l2tp_ip6_sk(sk)->conn_id = addr->l2tp_conn_id;
 
-       write_lock_bh(&l2tp_ip6_lock);
        sk_add_bind_node(sk, &l2tp_ip6_bind_table);
        sk_del_node_init(sk);
        write_unlock_bh(&l2tp_ip6_lock);
@@ -355,10 +357,7 @@ out_unlock_rcu:
        rcu_read_unlock();
 out_unlock:
        release_sock(sk);
-       return err;
 
-out_in_use:
-       read_unlock_bh(&l2tp_ip6_lock);
        return err;
 }
 
@@ -371,9 +370,6 @@ static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr,
        int     addr_type;
        int rc;
 
-       if (sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */
-               return -EINVAL;
-
        if (addr_len < sizeof(*lsa))
                return -EINVAL;
 
@@ -390,10 +386,18 @@ static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr,
                        return -EINVAL;
        }
 
-       rc = ip6_datagram_connect(sk, uaddr, addr_len);
-
        lock_sock(sk);
 
+        /* Must bind first - autobinding does not work */
+       if (sock_flag(sk, SOCK_ZAPPED)) {
+               rc = -EINVAL;
+               goto out_sk;
+       }
+
+       rc = __ip6_datagram_connect(sk, uaddr, addr_len);
+       if (rc < 0)
+               goto out_sk;
+
        l2tp_ip6_sk(sk)->peer_conn_id = lsa->l2tp_conn_id;
 
        write_lock_bh(&l2tp_ip6_lock);
@@ -401,6 +405,7 @@ static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr,
        sk_add_bind_node(sk, &l2tp_ip6_bind_table);
        write_unlock_bh(&l2tp_ip6_lock);
 
+out_sk:
        release_sock(sk);
 
        return rc;
index 0e4334cbde17519cf69bbc099127c0d81a626467..15fe97644ffe048c9b1d5818c0b1aec56eb988f4 100644 (file)
@@ -1252,7 +1252,7 @@ static int rtm_to_route_config(struct sk_buff *skb,  struct nlmsghdr *nlh,
                if (!nla)
                        continue;
 
-               switch(index) {
+               switch (index) {
                case RTA_OIF:
                        cfg->rc_ifindex = nla_get_u32(nla);
                        break;
index bbb8f3df79f723d544824c2ce49c9bc1095d9276..5b9c884a452e8305e9d3ff0a420887bd7f5e4dd2 100644 (file)
@@ -42,7 +42,7 @@ struct nf_nat_conn_key {
        const struct nf_conntrack_zone *zone;
 };
 
-static struct rhashtable nf_nat_bysource_table;
+static struct rhltable nf_nat_bysource_table;
 
 inline const struct nf_nat_l3proto *
 __nf_nat_l3proto_find(u8 family)
@@ -193,9 +193,12 @@ static int nf_nat_bysource_cmp(struct rhashtable_compare_arg *arg,
        const struct nf_nat_conn_key *key = arg->key;
        const struct nf_conn *ct = obj;
 
-       return same_src(ct, key->tuple) &&
-              net_eq(nf_ct_net(ct), key->net) &&
-              nf_ct_zone_equal(ct, key->zone, IP_CT_DIR_ORIGINAL);
+       if (!same_src(ct, key->tuple) ||
+           !net_eq(nf_ct_net(ct), key->net) ||
+           !nf_ct_zone_equal(ct, key->zone, IP_CT_DIR_ORIGINAL))
+               return 1;
+
+       return 0;
 }
 
 static struct rhashtable_params nf_nat_bysource_params = {
@@ -204,7 +207,6 @@ static struct rhashtable_params nf_nat_bysource_params = {
        .obj_cmpfn = nf_nat_bysource_cmp,
        .nelem_hint = 256,
        .min_size = 1024,
-       .nulls_base = (1U << RHT_BASE_SHIFT),
 };
 
 /* Only called for SRC manip */
@@ -223,12 +225,15 @@ find_appropriate_src(struct net *net,
                .tuple = tuple,
                .zone = zone
        };
+       struct rhlist_head *hl;
 
-       ct = rhashtable_lookup_fast(&nf_nat_bysource_table, &key,
-                                   nf_nat_bysource_params);
-       if (!ct)
+       hl = rhltable_lookup(&nf_nat_bysource_table, &key,
+                            nf_nat_bysource_params);
+       if (!hl)
                return 0;
 
+       ct = container_of(hl, typeof(*ct), nat_bysource);
+
        nf_ct_invert_tuplepr(result,
                             &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
        result->dst = tuple->dst;
@@ -446,11 +451,17 @@ nf_nat_setup_info(struct nf_conn *ct,
        }
 
        if (maniptype == NF_NAT_MANIP_SRC) {
+               struct nf_nat_conn_key key = {
+                       .net = nf_ct_net(ct),
+                       .tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+                       .zone = nf_ct_zone(ct),
+               };
                int err;
 
-               err = rhashtable_insert_fast(&nf_nat_bysource_table,
-                                            &ct->nat_bysource,
-                                            nf_nat_bysource_params);
+               err = rhltable_insert_key(&nf_nat_bysource_table,
+                                         &key,
+                                         &ct->nat_bysource,
+                                         nf_nat_bysource_params);
                if (err)
                        return NF_DROP;
        }
@@ -567,8 +578,8 @@ static int nf_nat_proto_clean(struct nf_conn *ct, void *data)
         * will delete entry from already-freed table.
         */
        ct->status &= ~IPS_NAT_DONE_MASK;
-       rhashtable_remove_fast(&nf_nat_bysource_table, &ct->nat_bysource,
-                              nf_nat_bysource_params);
+       rhltable_remove(&nf_nat_bysource_table, &ct->nat_bysource,
+                       nf_nat_bysource_params);
 
        /* don't delete conntrack.  Although that would make things a lot
         * simpler, we'd end up flushing all conntracks on nat rmmod.
@@ -698,8 +709,8 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
        if (!nat)
                return;
 
-       rhashtable_remove_fast(&nf_nat_bysource_table, &ct->nat_bysource,
-                              nf_nat_bysource_params);
+       rhltable_remove(&nf_nat_bysource_table, &ct->nat_bysource,
+                       nf_nat_bysource_params);
 }
 
 static struct nf_ct_ext_type nat_extend __read_mostly = {
@@ -834,13 +845,13 @@ static int __init nf_nat_init(void)
 {
        int ret;
 
-       ret = rhashtable_init(&nf_nat_bysource_table, &nf_nat_bysource_params);
+       ret = rhltable_init(&nf_nat_bysource_table, &nf_nat_bysource_params);
        if (ret)
                return ret;
 
        ret = nf_ct_extend_register(&nat_extend);
        if (ret < 0) {
-               rhashtable_destroy(&nf_nat_bysource_table);
+               rhltable_destroy(&nf_nat_bysource_table);
                printk(KERN_ERR "nf_nat_core: Unable to register extension\n");
                return ret;
        }
@@ -864,7 +875,7 @@ static int __init nf_nat_init(void)
        return 0;
 
  cleanup_extend:
-       rhashtable_destroy(&nf_nat_bysource_table);
+       rhltable_destroy(&nf_nat_bysource_table);
        nf_ct_extend_unregister(&nat_extend);
        return ret;
 }
@@ -883,7 +894,7 @@ static void __exit nf_nat_cleanup(void)
        for (i = 0; i < NFPROTO_NUMPROTO; i++)
                kfree(nf_nat_l4protos[i]);
 
-       rhashtable_destroy(&nf_nat_bysource_table);
+       rhltable_destroy(&nf_nat_bysource_table);
 }
 
 MODULE_LICENSE("GPL");
index 026581b04ea8d16b805183332ce216aac9c36ebc..e5194f6f906cb28396620917968aae42fb0872b2 100644 (file)
@@ -2570,7 +2570,8 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
        }
 
        if (set->timeout &&
-           nla_put_be64(skb, NFTA_SET_TIMEOUT, cpu_to_be64(set->timeout),
+           nla_put_be64(skb, NFTA_SET_TIMEOUT,
+                        cpu_to_be64(jiffies_to_msecs(set->timeout)),
                         NFTA_SET_PAD))
                goto nla_put_failure;
        if (set->gc_int &&
@@ -2859,7 +2860,8 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
        if (nla[NFTA_SET_TIMEOUT] != NULL) {
                if (!(flags & NFT_SET_TIMEOUT))
                        return -EINVAL;
-               timeout = be64_to_cpu(nla_get_be64(nla[NFTA_SET_TIMEOUT]));
+               timeout = msecs_to_jiffies(be64_to_cpu(nla_get_be64(
+                                               nla[NFTA_SET_TIMEOUT])));
        }
        gc_int = 0;
        if (nla[NFTA_SET_GC_INTERVAL] != NULL) {
@@ -3178,7 +3180,8 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
 
        if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
            nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
-                        cpu_to_be64(*nft_set_ext_timeout(ext)),
+                        cpu_to_be64(jiffies_to_msecs(
+                                               *nft_set_ext_timeout(ext))),
                         NFTA_SET_ELEM_PAD))
                goto nla_put_failure;
 
@@ -3447,7 +3450,7 @@ void *nft_set_elem_init(const struct nft_set *set,
                memcpy(nft_set_ext_data(ext), data, set->dlen);
        if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION))
                *nft_set_ext_expiration(ext) =
-                       jiffies + msecs_to_jiffies(timeout);
+                       jiffies + timeout;
        if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT))
                *nft_set_ext_timeout(ext) = timeout;
 
@@ -3535,7 +3538,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
        if (nla[NFTA_SET_ELEM_TIMEOUT] != NULL) {
                if (!(set->flags & NFT_SET_TIMEOUT))
                        return -EINVAL;
-               timeout = be64_to_cpu(nla_get_be64(nla[NFTA_SET_ELEM_TIMEOUT]));
+               timeout = msecs_to_jiffies(be64_to_cpu(nla_get_be64(
+                                       nla[NFTA_SET_ELEM_TIMEOUT])));
        } else if (set->flags & NFT_SET_TIMEOUT) {
                timeout = set->timeout;
        }
index baf694de3935a29561d513a56dbd3c8f8690e196..d5447a22275c0649cb125364730986a52436816d 100644 (file)
@@ -53,6 +53,7 @@ static int nft_hash_init(const struct nft_ctx *ctx,
 {
        struct nft_hash *priv = nft_expr_priv(expr);
        u32 len;
+       int err;
 
        if (!tb[NFTA_HASH_SREG] ||
            !tb[NFTA_HASH_DREG] ||
@@ -67,8 +68,10 @@ static int nft_hash_init(const struct nft_ctx *ctx,
        priv->sreg = nft_parse_register(tb[NFTA_HASH_SREG]);
        priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]);
 
-       len = ntohl(nla_get_be32(tb[NFTA_HASH_LEN]));
-       if (len == 0 || len > U8_MAX)
+       err = nft_parse_u32_check(tb[NFTA_HASH_LEN], U8_MAX, &len);
+       if (err < 0)
+               return err;
+       if (len == 0)
                return -ERANGE;
 
        priv->len = len;
index fbc88009ca2ef938a5d4b0fd1c597543ff804fcc..8f0aaaea1376eb94e77d2bd21f00b54e6b0c3e6b 100644 (file)
@@ -59,6 +59,12 @@ static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr
        int err;
        u32 op;
 
+       if (!tb[NFTA_RANGE_SREG]      ||
+           !tb[NFTA_RANGE_OP]        ||
+           !tb[NFTA_RANGE_FROM_DATA] ||
+           !tb[NFTA_RANGE_TO_DATA])
+               return -EINVAL;
+
        err = nft_data_init(NULL, &priv->data_from, sizeof(priv->data_from),
                            &desc_from, tb[NFTA_RANGE_FROM_DATA]);
        if (err < 0)
index 62bea4591054820eb516ef016214ee23fe89b6e9..246f29d365c09a7761b8ae0f0a2acd6de8a6f653 100644 (file)
@@ -329,7 +329,6 @@ static void netlink_sock_destruct(struct sock *sk)
        if (nlk->cb_running) {
                if (nlk->cb.done)
                        nlk->cb.done(&nlk->cb);
-
                module_put(nlk->cb.module);
                kfree_skb(nlk->cb.skb);
        }
@@ -346,6 +345,14 @@ static void netlink_sock_destruct(struct sock *sk)
        WARN_ON(nlk_sk(sk)->groups);
 }
 
+static void netlink_sock_destruct_work(struct work_struct *work)
+{
+       struct netlink_sock *nlk = container_of(work, struct netlink_sock,
+                                               work);
+
+       sk_free(&nlk->sk);
+}
+
 /* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on
  * SMP. Look, when several writers sleep and reader wakes them up, all but one
  * immediately hit write lock and grab all the cpus. Exclusive sleep solves
@@ -648,8 +655,18 @@ out_module:
 static void deferred_put_nlk_sk(struct rcu_head *head)
 {
        struct netlink_sock *nlk = container_of(head, struct netlink_sock, rcu);
+       struct sock *sk = &nlk->sk;
+
+       if (!atomic_dec_and_test(&sk->sk_refcnt))
+               return;
+
+       if (nlk->cb_running && nlk->cb.done) {
+               INIT_WORK(&nlk->work, netlink_sock_destruct_work);
+               schedule_work(&nlk->work);
+               return;
+       }
 
-       sock_put(&nlk->sk);
+       sk_free(sk);
 }
 
 static int netlink_release(struct socket *sock)
index 3cfd6cc60504385b98009f52748fc088c62a3b96..4fdb3831897775547f77c069a8018c0d2a253c8c 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/rhashtable.h>
 #include <linux/atomic.h>
+#include <linux/workqueue.h>
 #include <net/sock.h>
 
 #define NLGRPSZ(x)     (ALIGN(x, sizeof(unsigned long) * 8) / 8)
@@ -33,6 +34,7 @@ struct netlink_sock {
 
        struct rhash_head       node;
        struct rcu_head         rcu;
+       struct work_struct      work;
 };
 
 static inline struct netlink_sock *nlk_sk(struct sock *sk)
index 31045ef44a82b925e53ce34da2aca74448dd9c8d..fecefa2dc94e129935bcf9b5d1ff117e58566b9f 100644 (file)
@@ -370,8 +370,11 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key,
                skb_orphan(skb);
                memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm));
                err = nf_ct_frag6_gather(net, skb, user);
-               if (err)
+               if (err) {
+                       if (err != -EINPROGRESS)
+                               kfree_skb(skb);
                        return err;
+               }
 
                key->ip.proto = ipv6_hdr(skb)->nexthdr;
                ovs_cb.mru = IP6CB(skb)->frag_max_size;
index d2238b204691b8e4f2e3acb9bc167b553ba32d50..dd2332390c45bbff7c3fc5d259453f2e1ca352bf 100644 (file)
@@ -3648,19 +3648,25 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
 
                if (optlen != sizeof(val))
                        return -EINVAL;
-               if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
-                       return -EBUSY;
                if (copy_from_user(&val, optval, sizeof(val)))
                        return -EFAULT;
                switch (val) {
                case TPACKET_V1:
                case TPACKET_V2:
                case TPACKET_V3:
-                       po->tp_version = val;
-                       return 0;
+                       break;
                default:
                        return -EINVAL;
                }
+               lock_sock(sk);
+               if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
+                       ret = -EBUSY;
+               } else {
+                       po->tp_version = val;
+                       ret = 0;
+               }
+               release_sock(sk);
+               return ret;
        }
        case PACKET_RESERVE:
        {
@@ -4164,6 +4170,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
        /* Added to avoid minimal code churn */
        struct tpacket_req *req = &req_u->req;
 
+       lock_sock(sk);
        /* Opening a Tx-ring is NOT supported in TPACKET_V3 */
        if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
                net_warn_ratelimited("Tx-ring is not supported.\n");
@@ -4245,7 +4252,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
                        goto out;
        }
 
-       lock_sock(sk);
 
        /* Detach socket from network */
        spin_lock(&po->bind_lock);
@@ -4294,11 +4300,11 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
                if (!tx_ring)
                        prb_shutdown_retire_blk_timer(po, rb_queue);
        }
-       release_sock(sk);
 
        if (pg_vec)
                free_pg_vec(pg_vec, order, req->tp_block_nr);
 out:
+       release_sock(sk);
        return err;
 }
 
index fcddacc92e018bee041f250cde5e48ba8ea70c6a..20e2923dc827fdc447082159bffe34d39caeca51 100644 (file)
@@ -659,6 +659,8 @@ out_recv:
 out_pernet:
        unregister_pernet_subsys(&rds_tcp_net_ops);
 out_slab:
+       if (unregister_netdevice_notifier(&rds_tcp_dev_notifier))
+               pr_warn("could not unregister rds_tcp_dev_notifier\n");
        kmem_cache_destroy(rds_tcp_conn_slab);
 out:
        return ret;
index b54d56d4959b6381d35799ba84f64ea634384cce..cf9b2fe8eac6032f46a570c1482de601b41ac74f 100644 (file)
@@ -108,6 +108,17 @@ static void tcf_pedit_cleanup(struct tc_action *a, int bind)
        kfree(keys);
 }
 
+static bool offset_valid(struct sk_buff *skb, int offset)
+{
+       if (offset > 0 && offset > skb->len)
+               return false;
+
+       if  (offset < 0 && -offset > skb_headroom(skb))
+               return false;
+
+       return true;
+}
+
 static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
                     struct tcf_result *res)
 {
@@ -134,6 +145,11 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
                        if (tkey->offmask) {
                                char *d, _d;
 
+                               if (!offset_valid(skb, off + tkey->at)) {
+                                       pr_info("tc filter pedit 'at' offset %d out of bounds\n",
+                                               off + tkey->at);
+                                       goto bad;
+                               }
                                d = skb_header_pointer(skb, off + tkey->at, 1,
                                                       &_d);
                                if (!d)
@@ -146,10 +162,10 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
                                        " offset must be on 32 bit boundaries\n");
                                goto bad;
                        }
-                       if (offset > 0 && offset > skb->len) {
-                               pr_info("tc filter pedit"
-                                       " offset %d can't exceed pkt length %d\n",
-                                      offset, skb->len);
+
+                       if (!offset_valid(skb, off + offset)) {
+                               pr_info("tc filter pedit offset %d out of bounds\n",
+                                       offset);
                                goto bad;
                        }
 
index eb219b78cd495fcee480f0c0fae355e8a3deea81..5877f6061b57589ce9ba9226281e85f47eafb523 100644 (file)
@@ -62,9 +62,6 @@ static unsigned long basic_get(struct tcf_proto *tp, u32 handle)
        struct basic_head *head = rtnl_dereference(tp->root);
        struct basic_filter *f;
 
-       if (head == NULL)
-               return 0UL;
-
        list_for_each_entry(f, &head->flist, link) {
                if (f->handle == handle) {
                        l = (unsigned long) f;
@@ -109,7 +106,6 @@ static bool basic_destroy(struct tcf_proto *tp, bool force)
                tcf_unbind_filter(tp, &f->res);
                call_rcu(&f->rcu, basic_delete_filter);
        }
-       RCU_INIT_POINTER(tp->root, NULL);
        kfree_rcu(head, rcu);
        return true;
 }
index bb1d5a487081f21f80a3042cd424cf7caedf6b37..0a47ba5e610985d9c19db81a69de5b60db44348b 100644 (file)
@@ -292,7 +292,6 @@ static bool cls_bpf_destroy(struct tcf_proto *tp, bool force)
                call_rcu(&prog->rcu, __cls_bpf_delete_prog);
        }
 
-       RCU_INIT_POINTER(tp->root, NULL);
        kfree_rcu(head, rcu);
        return true;
 }
@@ -303,9 +302,6 @@ static unsigned long cls_bpf_get(struct tcf_proto *tp, u32 handle)
        struct cls_bpf_prog *prog;
        unsigned long ret = 0UL;
 
-       if (head == NULL)
-               return 0UL;
-
        list_for_each_entry(prog, &head->plist, link) {
                if (prog->handle == handle) {
                        ret = (unsigned long) prog;
index 85233c470035f7f618e7550a1789102e2208a757..c1f20077837f06bb1998f5621c797e575e10ca21 100644 (file)
@@ -137,11 +137,10 @@ static bool cls_cgroup_destroy(struct tcf_proto *tp, bool force)
 
        if (!force)
                return false;
-
-       if (head) {
-               RCU_INIT_POINTER(tp->root, NULL);
+       /* Head can still be NULL due to cls_cgroup_init(). */
+       if (head)
                call_rcu(&head->rcu, cls_cgroup_destroy_rcu);
-       }
+
        return true;
 }
 
index e39672394c7b64dc28617878bc7b26ef1ef8abb9..6575aba87630a24052a6374ddfceef1ce597144d 100644 (file)
@@ -596,7 +596,6 @@ static bool flow_destroy(struct tcf_proto *tp, bool force)
                list_del_rcu(&f->list);
                call_rcu(&f->rcu, flow_destroy_filter);
        }
-       RCU_INIT_POINTER(tp->root, NULL);
        kfree_rcu(head, rcu);
        return true;
 }
index f6f40fba599bad3d1db4bb14fcc4f7d663d128bc..904442421db3afae405548a9f5c316ce65e22de3 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/rhashtable.h>
+#include <linux/workqueue.h>
 
 #include <linux/if_ether.h>
 #include <linux/in6.h>
@@ -64,7 +65,10 @@ struct cls_fl_head {
        bool mask_assigned;
        struct list_head filters;
        struct rhashtable_params ht_params;
-       struct rcu_head rcu;
+       union {
+               struct work_struct work;
+               struct rcu_head rcu;
+       };
 };
 
 struct cls_fl_filter {
@@ -269,6 +273,24 @@ static void fl_hw_update_stats(struct tcf_proto *tp, struct cls_fl_filter *f)
        dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol, &tc);
 }
 
+static void fl_destroy_sleepable(struct work_struct *work)
+{
+       struct cls_fl_head *head = container_of(work, struct cls_fl_head,
+                                               work);
+       if (head->mask_assigned)
+               rhashtable_destroy(&head->ht);
+       kfree(head);
+       module_put(THIS_MODULE);
+}
+
+static void fl_destroy_rcu(struct rcu_head *rcu)
+{
+       struct cls_fl_head *head = container_of(rcu, struct cls_fl_head, rcu);
+
+       INIT_WORK(&head->work, fl_destroy_sleepable);
+       schedule_work(&head->work);
+}
+
 static bool fl_destroy(struct tcf_proto *tp, bool force)
 {
        struct cls_fl_head *head = rtnl_dereference(tp->root);
@@ -282,10 +304,9 @@ static bool fl_destroy(struct tcf_proto *tp, bool force)
                list_del_rcu(&f->list);
                call_rcu(&f->rcu, fl_destroy_filter);
        }
-       RCU_INIT_POINTER(tp->root, NULL);
-       if (head->mask_assigned)
-               rhashtable_destroy(&head->ht);
-       kfree_rcu(head, rcu);
+
+       __module_get(THIS_MODULE);
+       call_rcu(&head->rcu, fl_destroy_rcu);
        return true;
 }
 
@@ -711,8 +732,9 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
                goto errout;
 
        if (fold) {
-               rhashtable_remove_fast(&head->ht, &fold->ht_node,
-                                      head->ht_params);
+               if (!tc_skip_sw(fold->flags))
+                       rhashtable_remove_fast(&head->ht, &fold->ht_node,
+                                              head->ht_params);
                fl_hw_destroy_filter(tp, (unsigned long)fold);
        }
 
@@ -739,8 +761,9 @@ static int fl_delete(struct tcf_proto *tp, unsigned long arg)
        struct cls_fl_head *head = rtnl_dereference(tp->root);
        struct cls_fl_filter *f = (struct cls_fl_filter *) arg;
 
-       rhashtable_remove_fast(&head->ht, &f->ht_node,
-                              head->ht_params);
+       if (!tc_skip_sw(f->flags))
+               rhashtable_remove_fast(&head->ht, &f->ht_node,
+                                      head->ht_params);
        list_del_rcu(&f->list);
        fl_hw_destroy_filter(tp, (unsigned long)f);
        tcf_unbind_filter(tp, &f->res);
index 25927b6c4436775a0d80747f7171ddc3d6896dfd..f935429bd5ef1fcbe6a4272876b76e2ebb574c4b 100644 (file)
@@ -114,7 +114,6 @@ static bool mall_destroy(struct tcf_proto *tp, bool force)
 
                call_rcu(&f->rcu, mall_destroy_filter);
        }
-       RCU_INIT_POINTER(tp->root, NULL);
        kfree_rcu(head, rcu);
        return true;
 }
index 4f05a19fb07358d6a1763f279dec9ea5f32f32ad..322438fb3ffcb426194be6c1dd05893b27cdf51c 100644 (file)
@@ -152,7 +152,8 @@ static int rsvp_classify(struct sk_buff *skb, const struct tcf_proto *tp,
                return -1;
        nhptr = ip_hdr(skb);
 #endif
-
+       if (unlikely(!head))
+               return -1;
 restart:
 
 #if RSVP_DST_LEN == 4
index 96144bdf30db37d1ebd7dbaa0314d273f0f6aef2..0751245a6aced60163601b94ab1386e0c5e30565 100644 (file)
@@ -543,7 +543,6 @@ static bool tcindex_destroy(struct tcf_proto *tp, bool force)
        walker.fn = tcindex_destroy_element;
        tcindex_walk(tp, &walker);
 
-       RCU_INIT_POINTER(tp->root, NULL);
        call_rcu(&p->rcu, __tcindex_destroy);
        return true;
 }
index 975dbeb60ab0461ba16094099382ec98cec945d7..52d74760fb68697d508fafb213b56deaed2e8639 100644 (file)
@@ -421,6 +421,10 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
        dev = dev_get_by_name(net, driver_name);
        if (!dev)
                return -ENODEV;
+       if (tipc_mtu_bad(dev, 0)) {
+               dev_put(dev);
+               return -EINVAL;
+       }
 
        /* Associate TIPC bearer with L2 bearer */
        rcu_assign_pointer(b->media_ptr, dev);
@@ -610,8 +614,6 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
        if (!b)
                return NOTIFY_DONE;
 
-       b->mtu = dev->mtu;
-
        switch (evt) {
        case NETDEV_CHANGE:
                if (netif_carrier_ok(dev))
@@ -624,6 +626,11 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
                tipc_reset_bearer(net, b);
                break;
        case NETDEV_CHANGEMTU:
+               if (tipc_mtu_bad(dev, 0)) {
+                       bearer_disable(net, b);
+                       break;
+               }
+               b->mtu = dev->mtu;
                tipc_reset_bearer(net, b);
                break;
        case NETDEV_CHANGEADDR:
index 78892e2f53e306e09cd788e0330c01eddb8df294..278ff7f616f9e884aca58fce761a23cfd1c55f70 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "netlink.h"
 #include "core.h"
+#include "msg.h"
 #include <net/genetlink.h>
 
 #define MAX_MEDIA      3
@@ -59,6 +60,9 @@
 #define TIPC_MEDIA_TYPE_IB     2
 #define TIPC_MEDIA_TYPE_UDP    3
 
+/* minimum bearer MTU */
+#define TIPC_MIN_BEARER_MTU    (MAX_H_SIZE + INT_H_SIZE)
+
 /**
  * struct tipc_media_addr - destination address used by TIPC bearers
  * @value: address info (format defined by media)
@@ -215,4 +219,13 @@ void tipc_bearer_xmit(struct net *net, u32 bearer_id,
 void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
                         struct sk_buff_head *xmitq);
 
+/* check if device MTU is too low for tipc headers */
+static inline bool tipc_mtu_bad(struct net_device *dev, unsigned int reserve)
+{
+       if (dev->mtu >= TIPC_MIN_BEARER_MTU + reserve)
+               return false;
+       netdev_warn(dev, "MTU too low for tipc bearer\n");
+       return true;
+}
+
 #endif /* _TIPC_BEARER_H */
index ecc12411155ea0ec7eeb94d5259ab901029b4d0c..bda89bf9f4ff185f64c68c06d8b88a4385380c58 100644 (file)
@@ -47,8 +47,8 @@
 #include <linux/pkt_sched.h>
 
 struct tipc_stats {
-       u32 sent_info;          /* used in counting # sent packets */
-       u32 recv_info;          /* used in counting # recv'd packets */
+       u32 sent_pkts;
+       u32 recv_pkts;
        u32 sent_states;
        u32 recv_states;
        u32 sent_probes;
@@ -857,7 +857,6 @@ void tipc_link_reset(struct tipc_link *l)
        l->acked = 0;
        l->silent_intv_cnt = 0;
        l->rst_cnt = 0;
-       l->stats.recv_info = 0;
        l->stale_count = 0;
        l->bc_peer_is_up = false;
        memset(&l->mon_state, 0, sizeof(l->mon_state));
@@ -888,6 +887,7 @@ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list,
        struct sk_buff_head *transmq = &l->transmq;
        struct sk_buff_head *backlogq = &l->backlogq;
        struct sk_buff *skb, *_skb, *bskb;
+       int pkt_cnt = skb_queue_len(list);
 
        /* Match msg importance against this and all higher backlog limits: */
        if (!skb_queue_empty(backlogq)) {
@@ -901,6 +901,11 @@ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list,
                return -EMSGSIZE;
        }
 
+       if (pkt_cnt > 1) {
+               l->stats.sent_fragmented++;
+               l->stats.sent_fragments += pkt_cnt;
+       }
+
        /* Prepare each packet for sending, and add to relevant queue: */
        while (skb_queue_len(list)) {
                skb = skb_peek(list);
@@ -920,6 +925,7 @@ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list,
                        __skb_queue_tail(xmitq, _skb);
                        TIPC_SKB_CB(skb)->ackers = l->ackers;
                        l->rcv_unacked = 0;
+                       l->stats.sent_pkts++;
                        seqno++;
                        continue;
                }
@@ -968,6 +974,7 @@ void tipc_link_advance_backlog(struct tipc_link *l, struct sk_buff_head *xmitq)
                msg_set_ack(hdr, ack);
                msg_set_bcast_ack(hdr, bc_ack);
                l->rcv_unacked = 0;
+               l->stats.sent_pkts++;
                seqno++;
        }
        l->snd_nxt = seqno;
@@ -1260,7 +1267,7 @@ int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb,
 
                /* Deliver packet */
                l->rcv_nxt++;
-               l->stats.recv_info++;
+               l->stats.recv_pkts++;
                if (!tipc_data_input(l, skb, l->inputq))
                        rc |= tipc_link_input(l, skb, l->inputq);
                if (unlikely(++l->rcv_unacked >= TIPC_MIN_LINK_WIN))
@@ -1800,10 +1807,6 @@ void tipc_link_set_queue_limits(struct tipc_link *l, u32 win)
 void tipc_link_reset_stats(struct tipc_link *l)
 {
        memset(&l->stats, 0, sizeof(l->stats));
-       if (!link_is_bc_sndlink(l)) {
-               l->stats.sent_info = l->snd_nxt;
-               l->stats.recv_info = l->rcv_nxt;
-       }
 }
 
 static void link_print(struct tipc_link *l, const char *str)
@@ -1867,12 +1870,12 @@ static int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s)
        };
 
        struct nla_map map[] = {
-               {TIPC_NLA_STATS_RX_INFO, s->recv_info},
+               {TIPC_NLA_STATS_RX_INFO, 0},
                {TIPC_NLA_STATS_RX_FRAGMENTS, s->recv_fragments},
                {TIPC_NLA_STATS_RX_FRAGMENTED, s->recv_fragmented},
                {TIPC_NLA_STATS_RX_BUNDLES, s->recv_bundles},
                {TIPC_NLA_STATS_RX_BUNDLED, s->recv_bundled},
-               {TIPC_NLA_STATS_TX_INFO, s->sent_info},
+               {TIPC_NLA_STATS_TX_INFO, 0},
                {TIPC_NLA_STATS_TX_FRAGMENTS, s->sent_fragments},
                {TIPC_NLA_STATS_TX_FRAGMENTED, s->sent_fragmented},
                {TIPC_NLA_STATS_TX_BUNDLES, s->sent_bundles},
@@ -1947,9 +1950,9 @@ int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg,
                goto attr_msg_full;
        if (nla_put_u32(msg->skb, TIPC_NLA_LINK_MTU, link->mtu))
                goto attr_msg_full;
-       if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, link->rcv_nxt))
+       if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, link->stats.recv_pkts))
                goto attr_msg_full;
-       if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, link->snd_nxt))
+       if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, link->stats.sent_pkts))
                goto attr_msg_full;
 
        if (tipc_link_is_up(link))
@@ -2004,12 +2007,12 @@ static int __tipc_nl_add_bc_link_stat(struct sk_buff *skb,
        };
 
        struct nla_map map[] = {
-               {TIPC_NLA_STATS_RX_INFO, stats->recv_info},
+               {TIPC_NLA_STATS_RX_INFO, stats->recv_pkts},
                {TIPC_NLA_STATS_RX_FRAGMENTS, stats->recv_fragments},
                {TIPC_NLA_STATS_RX_FRAGMENTED, stats->recv_fragmented},
                {TIPC_NLA_STATS_RX_BUNDLES, stats->recv_bundles},
                {TIPC_NLA_STATS_RX_BUNDLED, stats->recv_bundled},
-               {TIPC_NLA_STATS_TX_INFO, stats->sent_info},
+               {TIPC_NLA_STATS_TX_INFO, stats->sent_pkts},
                {TIPC_NLA_STATS_TX_FRAGMENTS, stats->sent_fragments},
                {TIPC_NLA_STATS_TX_FRAGMENTED, stats->sent_fragmented},
                {TIPC_NLA_STATS_TX_BUNDLES, stats->sent_bundles},
@@ -2076,9 +2079,9 @@ int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg)
                goto attr_msg_full;
        if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, bcl->name))
                goto attr_msg_full;
-       if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, bcl->rcv_nxt))
+       if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, 0))
                goto attr_msg_full;
-       if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, bcl->snd_nxt))
+       if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, 0))
                goto attr_msg_full;
 
        prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP);
index 78cab9c5a445afd5a57a9b53d6960da533a12ea0..b58dc95f3d3535a305e529c75282360ea731f82d 100644 (file)
@@ -697,6 +697,11 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
                udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
                udp_conf.use_udp_checksums = false;
                ub->ifindex = dev->ifindex;
+               if (tipc_mtu_bad(dev, sizeof(struct iphdr) +
+                                     sizeof(struct udphdr))) {
+                       err = -EINVAL;
+                       goto err;
+               }
                b->mtu = dev->mtu - sizeof(struct iphdr)
                        - sizeof(struct udphdr);
 #if IS_ENABLED(CONFIG_IPV6)
index fd6986634e6fe4dc77993854323d7558637b94bc..5bf7e1bfeac7aa26549cdcac42ddf7cda5a3ad88 100644 (file)
@@ -1268,12 +1268,14 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir,
                        err = security_xfrm_policy_lookup(pol->security,
                                                      fl->flowi_secid,
                                                      policy_to_flow_dir(dir));
-                       if (!err && !xfrm_pol_hold_rcu(pol))
-                               goto again;
-                       else if (err == -ESRCH)
+                       if (!err) {
+                               if (!xfrm_pol_hold_rcu(pol))
+                                       goto again;
+                       } else if (err == -ESRCH) {
                                pol = NULL;
-                       else
+                       } else {
                                pol = ERR_PTR(err);
+                       }
                } else
                        pol = NULL;
        }
index 08892091cfe3a65c13994b2743586f5137c89fd9..671a1d0333f0d2c828c757944016cbe48836ec72 100644 (file)
@@ -2450,7 +2450,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 
 #ifdef CONFIG_COMPAT
        if (in_compat_syscall())
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
 #endif
 
        type = nlh->nlmsg_type;
index 90f44bd2045e16f5dd78ed842381d25a06fffa82..dadd5161bd916a0e7f470d211ffbce00af3cb7d0 100644 (file)
@@ -113,7 +113,7 @@ static int (*bpf_skb_under_cgroup)(void *ctx, void *map, int index) =
 #define PT_REGS_FP(x) ((x)->gprs[11]) /* Works only with CONFIG_FRAME_POINTER */
 #define PT_REGS_RC(x) ((x)->gprs[2])
 #define PT_REGS_SP(x) ((x)->gprs[15])
-#define PT_REGS_IP(x) ((x)->ip)
+#define PT_REGS_IP(x) ((x)->psw.addr)
 
 #elif defined(__aarch64__)
 
index 774a681f374a9781f44f9c0715adb126b47b999d..ceabf31079cf5ef7db360b1182ab64e78d4c05ef 100644 (file)
@@ -25,7 +25,7 @@ int do_sample(struct bpf_perf_event_data *ctx)
        u64 ip;
        u32 *value, init_val = 1;
 
-       ip = ctx->regs.ip;
+       ip = PT_REGS_IP(&ctx->regs);
        value = bpf_map_lookup_elem(&ip_map, &ip);
        if (value)
                *value += 1;
index 71a8ed32823ecc36cfc17b3ec519d611569dc7d6..41b6115a32eb1b0c06f13a0736690903e352839e 100644 (file)
@@ -50,7 +50,7 @@ int bpf_prog1(struct bpf_perf_event_data *ctx)
        key.userstack = bpf_get_stackid(ctx, &stackmap, USER_STACKID_FLAGS);
        if ((int)key.kernstack < 0 && (int)key.userstack < 0) {
                bpf_trace_printk(fmt, sizeof(fmt), cpu, ctx->sample_period,
-                                ctx->regs.ip);
+                                PT_REGS_IP(&ctx->regs));
                return 0;
        }
 
index ebced77deb9c4dc380ab5f58751950adc0ac3d7f..90a091b6ae4de74e6c070d77255b9f4b5655629a 100644 (file)
@@ -35,6 +35,8 @@ nconfig: $(obj)/nconf
 
 silentoldconfig: $(obj)/conf
        $(Q)mkdir -p include/config include/generated
+       $(Q)test -e include/generated/autoksyms.h || \
+           touch   include/generated/autoksyms.h
        $< $(silent) --$@ $(Kconfig)
 
 localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
index 0190cb6332f2d9ff6570d2628442d402f8a1ab29..52063b2626677144d8f47585147cc129011f93c7 100644 (file)
@@ -304,7 +304,7 @@ struct snd_dbri {
        spinlock_t lock;
 
        struct dbri_dma *dma;   /* Pointer to our DMA block */
-       u32 dma_dvma;           /* DBRI visible DMA address */
+       dma_addr_t dma_dvma;    /* DBRI visible DMA address */
 
        void __iomem *regs;     /* dbri HW regs */
        int dbri_irqp;          /* intr queue pointer */
@@ -657,12 +657,14 @@ static void dbri_cmdwait(struct snd_dbri *dbri)
  */
 static s32 *dbri_cmdlock(struct snd_dbri *dbri, int len)
 {
+       u32 dvma_addr = (u32)dbri->dma_dvma;
+
        /* Space for 2 WAIT cmds (replaced later by 1 JUMP cmd) */
        len += 2;
        spin_lock(&dbri->cmdlock);
        if (dbri->cmdptr - dbri->dma->cmd + len < DBRI_NO_CMDS - 2)
                return dbri->cmdptr + 2;
-       else if (len < sbus_readl(dbri->regs + REG8) - dbri->dma_dvma)
+       else if (len < sbus_readl(dbri->regs + REG8) - dvma_addr)
                return dbri->dma->cmd;
        else
                printk(KERN_ERR "DBRI: no space for commands.");
@@ -680,6 +682,7 @@ static s32 *dbri_cmdlock(struct snd_dbri *dbri, int len)
  */
 static void dbri_cmdsend(struct snd_dbri *dbri, s32 *cmd, int len)
 {
+       u32 dvma_addr = (u32)dbri->dma_dvma;
        s32 tmp, addr;
        static int wait_id = 0;
 
@@ -689,7 +692,7 @@ static void dbri_cmdsend(struct snd_dbri *dbri, s32 *cmd, int len)
        *(cmd+1) = DBRI_CMD(D_WAIT, 1, wait_id);
 
        /* Replace the last command with JUMP */
-       addr = dbri->dma_dvma + (cmd - len - dbri->dma->cmd) * sizeof(s32);
+       addr = dvma_addr + (cmd - len - dbri->dma->cmd) * sizeof(s32);
        *(dbri->cmdptr+1) = addr;
        *(dbri->cmdptr) = DBRI_CMD(D_JUMP, 0, 0);
 
@@ -747,6 +750,7 @@ static void dbri_reset(struct snd_dbri *dbri)
 /* Lock must not be held before calling this */
 static void dbri_initialize(struct snd_dbri *dbri)
 {
+       u32 dvma_addr = (u32)dbri->dma_dvma;
        s32 *cmd;
        u32 dma_addr;
        unsigned long flags;
@@ -764,7 +768,7 @@ static void dbri_initialize(struct snd_dbri *dbri)
        /*
         * Initialize the interrupt ring buffer.
         */
-       dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0);
+       dma_addr = dvma_addr + dbri_dma_off(intr, 0);
        dbri->dma->intr[0] = dma_addr;
        dbri->dbri_irqp = 1;
        /*
@@ -778,7 +782,7 @@ static void dbri_initialize(struct snd_dbri *dbri)
        dbri->cmdptr = cmd;
        *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
        *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
-       dma_addr = dbri->dma_dvma + dbri_dma_off(cmd, 0);
+       dma_addr = dvma_addr + dbri_dma_off(cmd, 0);
        sbus_writel(dma_addr, dbri->regs + REG8);
        spin_unlock(&dbri->cmdlock);
 
@@ -1077,6 +1081,7 @@ static void recv_fixed(struct snd_dbri *dbri, int pipe, volatile __u32 *ptr)
 static int setup_descs(struct snd_dbri *dbri, int streamno, unsigned int period)
 {
        struct dbri_streaminfo *info = &dbri->stream_info[streamno];
+       u32 dvma_addr = (u32)dbri->dma_dvma;
        __u32 dvma_buffer;
        int desc;
        int len;
@@ -1177,7 +1182,7 @@ static int setup_descs(struct snd_dbri *dbri, int streamno, unsigned int period)
                else {
                        dbri->next_desc[last_desc] = desc;
                        dbri->dma->desc[last_desc].nda =
-                           dbri->dma_dvma + dbri_dma_off(desc, desc);
+                           dvma_addr + dbri_dma_off(desc, desc);
                }
 
                last_desc = desc;
@@ -1192,7 +1197,7 @@ static int setup_descs(struct snd_dbri *dbri, int streamno, unsigned int period)
        }
 
        dbri->dma->desc[last_desc].nda =
-           dbri->dma_dvma + dbri_dma_off(desc, first_desc);
+           dvma_addr + dbri_dma_off(desc, first_desc);
        dbri->next_desc[last_desc] = first_desc;
        dbri->pipes[info->pipe].first_desc = first_desc;
        dbri->pipes[info->pipe].desc = first_desc;
@@ -1697,6 +1702,7 @@ interrupts are disabled.
 static void xmit_descs(struct snd_dbri *dbri)
 {
        struct dbri_streaminfo *info;
+       u32 dvma_addr;
        s32 *cmd;
        unsigned long flags;
        int first_td;
@@ -1704,6 +1710,7 @@ static void xmit_descs(struct snd_dbri *dbri)
        if (dbri == NULL)
                return;         /* Disabled */
 
+       dvma_addr = (u32)dbri->dma_dvma;
        info = &dbri->stream_info[DBRI_REC];
        spin_lock_irqsave(&dbri->lock, flags);
 
@@ -1718,7 +1725,7 @@ static void xmit_descs(struct snd_dbri *dbri)
                        *(cmd++) = DBRI_CMD(D_SDP, 0,
                                            dbri->pipes[info->pipe].sdp
                                            | D_SDP_P | D_SDP_EVERY | D_SDP_C);
-                       *(cmd++) = dbri->dma_dvma +
+                       *(cmd++) = dvma_addr +
                                   dbri_dma_off(desc, first_td);
                        dbri_cmdsend(dbri, cmd, 2);
 
@@ -1740,7 +1747,7 @@ static void xmit_descs(struct snd_dbri *dbri)
                        *(cmd++) = DBRI_CMD(D_SDP, 0,
                                            dbri->pipes[info->pipe].sdp
                                            | D_SDP_P | D_SDP_EVERY | D_SDP_C);
-                       *(cmd++) = dbri->dma_dvma +
+                       *(cmd++) = dvma_addr +
                                   dbri_dma_off(desc, first_td);
                        dbri_cmdsend(dbri, cmd, 2);
 
@@ -2539,7 +2546,7 @@ static int snd_dbri_create(struct snd_card *card,
        if (!dbri->dma)
                return -ENOMEM;
 
-       dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n",
+       dprintk(D_GEN, "DMA Cmd Block 0x%p (%pad)\n",
                dbri->dma, dbri->dma_dvma);
 
        /* Map the registers into memory. */
index b63a31be1218830eecc6116cf301f375c0a046c1..5e0dea2cdc01f65849f49f10392293a21b3a468d 100644 (file)
@@ -99,7 +99,7 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
                break;
 
        case 0x8d:
-               if (insn.rex_prefix.bytes &&
+               if (insn.rex_prefix.nbytes &&
                    insn.rex_prefix.bytes[0] == 0x48 &&
                    insn.modrm.nbytes && insn.modrm.bytes[0] == 0x2c &&
                    insn.sib.nbytes && insn.sib.bytes[0] == 0x24)
index 582db95127ed41cd5491562613a70ca7623bd190..405212be044a93f77db540eb0ee6d7ba4a62e825 100644 (file)
@@ -14,6 +14,7 @@ ldflags-y += --wrap=devm_memremap_pages
 ldflags-y += --wrap=insert_resource
 ldflags-y += --wrap=remove_resource
 ldflags-y += --wrap=acpi_evaluate_object
+ldflags-y += --wrap=acpi_evaluate_dsm
 
 DRIVERS := ../../../drivers
 NVDIMM_SRC := $(DRIVERS)/nvdimm
index 3ccef732fce9ac67d5012899690149fcc9c8ed47..64cae1a5deff956637a05b08c25565fe1718611b 100644 (file)
@@ -26,14 +26,17 @@ static LIST_HEAD(iomap_head);
 
 static struct iomap_ops {
        nfit_test_lookup_fn nfit_test_lookup;
+       nfit_test_evaluate_dsm_fn evaluate_dsm;
        struct list_head list;
 } iomap_ops = {
        .list = LIST_HEAD_INIT(iomap_ops.list),
 };
 
-void nfit_test_setup(nfit_test_lookup_fn lookup)
+void nfit_test_setup(nfit_test_lookup_fn lookup,
+               nfit_test_evaluate_dsm_fn evaluate)
 {
        iomap_ops.nfit_test_lookup = lookup;
+       iomap_ops.evaluate_dsm = evaluate;
        list_add_rcu(&iomap_ops.list, &iomap_head);
 }
 EXPORT_SYMBOL(nfit_test_setup);
@@ -367,4 +370,22 @@ acpi_status __wrap_acpi_evaluate_object(acpi_handle handle, acpi_string path,
 }
 EXPORT_SYMBOL(__wrap_acpi_evaluate_object);
 
+union acpi_object * __wrap_acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid,
+               u64 rev, u64 func, union acpi_object *argv4)
+{
+       union acpi_object *obj = ERR_PTR(-ENXIO);
+       struct iomap_ops *ops;
+
+       rcu_read_lock();
+       ops = list_first_or_null_rcu(&iomap_head, typeof(*ops), list);
+       if (ops)
+               obj = ops->evaluate_dsm(handle, uuid, rev, func, argv4);
+       rcu_read_unlock();
+
+       if (IS_ERR(obj))
+               return acpi_evaluate_dsm(handle, uuid, rev, func, argv4);
+       return obj;
+}
+EXPORT_SYMBOL(__wrap_acpi_evaluate_dsm);
+
 MODULE_LICENSE("GPL v2");
index c9a6458cb63e7514494811305fe8f41c1d3e6622..71620fa959530211c6c73c25ab71aaaba7cfa50a 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/sizes.h>
 #include <linux/list.h>
 #include <linux/slab.h>
+#include <nd-core.h>
 #include <nfit.h>
 #include <nd.h>
 #include "nfit_test.h"
@@ -1506,6 +1507,225 @@ static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa,
        return 0;
 }
 
+static unsigned long nfit_ctl_handle;
+
+union acpi_object *result;
+
+static union acpi_object *nfit_test_evaluate_dsm(acpi_handle handle,
+               const u8 *uuid, u64 rev, u64 func, union acpi_object *argv4)
+{
+       if (handle != &nfit_ctl_handle)
+               return ERR_PTR(-ENXIO);
+
+       return result;
+}
+
+static int setup_result(void *buf, size_t size)
+{
+       result = kmalloc(sizeof(union acpi_object) + size, GFP_KERNEL);
+       if (!result)
+               return -ENOMEM;
+       result->package.type = ACPI_TYPE_BUFFER,
+       result->buffer.pointer = (void *) (result + 1);
+       result->buffer.length = size;
+       memcpy(result->buffer.pointer, buf, size);
+       memset(buf, 0, size);
+       return 0;
+}
+
+static int nfit_ctl_test(struct device *dev)
+{
+       int rc, cmd_rc;
+       struct nvdimm *nvdimm;
+       struct acpi_device *adev;
+       struct nfit_mem *nfit_mem;
+       struct nd_ars_record *record;
+       struct acpi_nfit_desc *acpi_desc;
+       const u64 test_val = 0x0123456789abcdefULL;
+       unsigned long mask, cmd_size, offset;
+       union {
+               struct nd_cmd_get_config_size cfg_size;
+               struct nd_cmd_ars_status ars_stat;
+               struct nd_cmd_ars_cap ars_cap;
+               char buf[sizeof(struct nd_cmd_ars_status)
+                       + sizeof(struct nd_ars_record)];
+       } cmds;
+
+       adev = devm_kzalloc(dev, sizeof(*adev), GFP_KERNEL);
+       if (!adev)
+               return -ENOMEM;
+       *adev = (struct acpi_device) {
+               .handle = &nfit_ctl_handle,
+               .dev = {
+                       .init_name = "test-adev",
+               },
+       };
+
+       acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
+       if (!acpi_desc)
+               return -ENOMEM;
+       *acpi_desc = (struct acpi_nfit_desc) {
+               .nd_desc = {
+                       .cmd_mask = 1UL << ND_CMD_ARS_CAP
+                               | 1UL << ND_CMD_ARS_START
+                               | 1UL << ND_CMD_ARS_STATUS
+                               | 1UL << ND_CMD_CLEAR_ERROR,
+                       .module = THIS_MODULE,
+                       .provider_name = "ACPI.NFIT",
+                       .ndctl = acpi_nfit_ctl,
+               },
+               .dev = &adev->dev,
+       };
+
+       nfit_mem = devm_kzalloc(dev, sizeof(*nfit_mem), GFP_KERNEL);
+       if (!nfit_mem)
+               return -ENOMEM;
+
+       mask = 1UL << ND_CMD_SMART | 1UL << ND_CMD_SMART_THRESHOLD
+               | 1UL << ND_CMD_DIMM_FLAGS | 1UL << ND_CMD_GET_CONFIG_SIZE
+               | 1UL << ND_CMD_GET_CONFIG_DATA | 1UL << ND_CMD_SET_CONFIG_DATA
+               | 1UL << ND_CMD_VENDOR;
+       *nfit_mem = (struct nfit_mem) {
+               .adev = adev,
+               .family = NVDIMM_FAMILY_INTEL,
+               .dsm_mask = mask,
+       };
+
+       nvdimm = devm_kzalloc(dev, sizeof(*nvdimm), GFP_KERNEL);
+       if (!nvdimm)
+               return -ENOMEM;
+       *nvdimm = (struct nvdimm) {
+               .provider_data = nfit_mem,
+               .cmd_mask = mask,
+               .dev = {
+                       .init_name = "test-dimm",
+               },
+       };
+
+
+       /* basic checkout of a typical 'get config size' command */
+       cmd_size = sizeof(cmds.cfg_size);
+       cmds.cfg_size = (struct nd_cmd_get_config_size) {
+               .status = 0,
+               .config_size = SZ_128K,
+               .max_xfer = SZ_4K,
+       };
+       rc = setup_result(cmds.buf, cmd_size);
+       if (rc)
+               return rc;
+       rc = acpi_nfit_ctl(&acpi_desc->nd_desc, nvdimm, ND_CMD_GET_CONFIG_SIZE,
+                       cmds.buf, cmd_size, &cmd_rc);
+
+       if (rc < 0 || cmd_rc || cmds.cfg_size.status != 0
+                       || cmds.cfg_size.config_size != SZ_128K
+                       || cmds.cfg_size.max_xfer != SZ_4K) {
+               dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
+                               __func__, __LINE__, rc, cmd_rc);
+               return -EIO;
+       }
+
+
+       /* test ars_status with zero output */
+       cmd_size = offsetof(struct nd_cmd_ars_status, address);
+       cmds.ars_stat = (struct nd_cmd_ars_status) {
+               .out_length = 0,
+       };
+       rc = setup_result(cmds.buf, cmd_size);
+       if (rc)
+               return rc;
+       rc = acpi_nfit_ctl(&acpi_desc->nd_desc, NULL, ND_CMD_ARS_STATUS,
+                       cmds.buf, cmd_size, &cmd_rc);
+
+       if (rc < 0 || cmd_rc) {
+               dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
+                               __func__, __LINE__, rc, cmd_rc);
+               return -EIO;
+       }
+
+
+       /* test ars_cap with benign extended status */
+       cmd_size = sizeof(cmds.ars_cap);
+       cmds.ars_cap = (struct nd_cmd_ars_cap) {
+               .status = ND_ARS_PERSISTENT << 16,
+       };
+       offset = offsetof(struct nd_cmd_ars_cap, status);
+       rc = setup_result(cmds.buf + offset, cmd_size - offset);
+       if (rc)
+               return rc;
+       rc = acpi_nfit_ctl(&acpi_desc->nd_desc, NULL, ND_CMD_ARS_CAP,
+                       cmds.buf, cmd_size, &cmd_rc);
+
+       if (rc < 0 || cmd_rc) {
+               dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
+                               __func__, __LINE__, rc, cmd_rc);
+               return -EIO;
+       }
+
+
+       /* test ars_status with 'status' trimmed from 'out_length' */
+       cmd_size = sizeof(cmds.ars_stat) + sizeof(struct nd_ars_record);
+       cmds.ars_stat = (struct nd_cmd_ars_status) {
+               .out_length = cmd_size - 4,
+       };
+       record = &cmds.ars_stat.records[0];
+       *record = (struct nd_ars_record) {
+               .length = test_val,
+       };
+       rc = setup_result(cmds.buf, cmd_size);
+       if (rc)
+               return rc;
+       rc = acpi_nfit_ctl(&acpi_desc->nd_desc, NULL, ND_CMD_ARS_STATUS,
+                       cmds.buf, cmd_size, &cmd_rc);
+
+       if (rc < 0 || cmd_rc || record->length != test_val) {
+               dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
+                               __func__, __LINE__, rc, cmd_rc);
+               return -EIO;
+       }
+
+
+       /* test ars_status with 'Output (Size)' including 'status' */
+       cmd_size = sizeof(cmds.ars_stat) + sizeof(struct nd_ars_record);
+       cmds.ars_stat = (struct nd_cmd_ars_status) {
+               .out_length = cmd_size,
+       };
+       record = &cmds.ars_stat.records[0];
+       *record = (struct nd_ars_record) {
+               .length = test_val,
+       };
+       rc = setup_result(cmds.buf, cmd_size);
+       if (rc)
+               return rc;
+       rc = acpi_nfit_ctl(&acpi_desc->nd_desc, NULL, ND_CMD_ARS_STATUS,
+                       cmds.buf, cmd_size, &cmd_rc);
+
+       if (rc < 0 || cmd_rc || record->length != test_val) {
+               dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
+                               __func__, __LINE__, rc, cmd_rc);
+               return -EIO;
+       }
+
+
+       /* test extended status for get_config_size results in failure */
+       cmd_size = sizeof(cmds.cfg_size);
+       cmds.cfg_size = (struct nd_cmd_get_config_size) {
+               .status = 1 << 16,
+       };
+       rc = setup_result(cmds.buf, cmd_size);
+       if (rc)
+               return rc;
+       rc = acpi_nfit_ctl(&acpi_desc->nd_desc, nvdimm, ND_CMD_GET_CONFIG_SIZE,
+                       cmds.buf, cmd_size, &cmd_rc);
+
+       if (rc < 0 || cmd_rc >= 0) {
+               dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
+                               __func__, __LINE__, rc, cmd_rc);
+               return -EIO;
+       }
+
+       return 0;
+}
+
 static int nfit_test_probe(struct platform_device *pdev)
 {
        struct nvdimm_bus_descriptor *nd_desc;
@@ -1516,6 +1736,12 @@ static int nfit_test_probe(struct platform_device *pdev)
        union acpi_object *obj;
        int rc;
 
+       if (strcmp(dev_name(&pdev->dev), "nfit_test.0") == 0) {
+               rc = nfit_ctl_test(&pdev->dev);
+               if (rc)
+                       return rc;
+       }
+
        nfit_test = to_nfit_test(&pdev->dev);
 
        /* common alloc */
@@ -1639,11 +1865,13 @@ static __init int nfit_test_init(void)
 {
        int rc, i;
 
-       nfit_test_dimm = class_create(THIS_MODULE, "nfit_test_dimm");
-       if (IS_ERR(nfit_test_dimm))
-               return PTR_ERR(nfit_test_dimm);
+       nfit_test_setup(nfit_test_lookup, nfit_test_evaluate_dsm);
 
-       nfit_test_setup(nfit_test_lookup);
+       nfit_test_dimm = class_create(THIS_MODULE, "nfit_test_dimm");
+       if (IS_ERR(nfit_test_dimm)) {
+               rc = PTR_ERR(nfit_test_dimm);
+               goto err_register;
+       }
 
        for (i = 0; i < NUM_NFITS; i++) {
                struct nfit_test *nfit_test;
index c281dd2e5e2d8e631a2424a613841c7a40ab6601..f54c0032c6ff3a34e14504aa8fa5f219148267a3 100644 (file)
@@ -31,11 +31,17 @@ struct nfit_test_resource {
        void *buf;
 };
 
+union acpi_object;
+typedef void *acpi_handle;
+
 typedef struct nfit_test_resource *(*nfit_test_lookup_fn)(resource_size_t);
+typedef union acpi_object *(*nfit_test_evaluate_dsm_fn)(acpi_handle handle,
+               const u8 *uuid, u64 rev, u64 func, union acpi_object *argv4);
 void __iomem *__wrap_ioremap_nocache(resource_size_t offset,
                unsigned long size);
 void __wrap_iounmap(volatile void __iomem *addr);
-void nfit_test_setup(nfit_test_lookup_fn lookup);
+void nfit_test_setup(nfit_test_lookup_fn lookup,
+               nfit_test_evaluate_dsm_fn evaluate);
 void nfit_test_teardown(void);
 struct nfit_test_resource *get_nfit_res(resource_size_t resource);
 #endif
index 0a063af4056546c886d6d7efba987ff5528fcce0..9bab86757fa4f3613c372fbc0250c146284306ff 100644 (file)
@@ -50,8 +50,10 @@ void vgic_v2_process_maintenance(struct kvm_vcpu *vcpu)
 
                        WARN_ON(cpuif->vgic_lr[lr] & GICH_LR_STATE);
 
-                       kvm_notify_acked_irq(vcpu->kvm, 0,
-                                            intid - VGIC_NR_PRIVATE_IRQS);
+                       /* Only SPIs require notification */
+                       if (vgic_valid_spi(vcpu->kvm, intid))
+                               kvm_notify_acked_irq(vcpu->kvm, 0,
+                                                    intid - VGIC_NR_PRIVATE_IRQS);
                }
        }
 
index 9f0dae397d9c818b1d0237076d0bc59020a05950..5c9f9745e6cab8284161397c3d810df65304fae8 100644 (file)
@@ -41,8 +41,10 @@ void vgic_v3_process_maintenance(struct kvm_vcpu *vcpu)
 
                        WARN_ON(cpuif->vgic_lr[lr] & ICH_LR_STATE);
 
-                       kvm_notify_acked_irq(vcpu->kvm, 0,
-                                            intid - VGIC_NR_PRIVATE_IRQS);
+                       /* Only SPIs require notification */
+                       if (vgic_valid_spi(vcpu->kvm, intid))
+                               kvm_notify_acked_irq(vcpu->kvm, 0,
+                                                    intid - VGIC_NR_PRIVATE_IRQS);
                }
 
                /*
index 5c360347a1e9fc2091f5abf0bbb6a3432e13add9..7f9ee2929cfea3ba0d30740e5c82109c14d359e4 100644 (file)
@@ -2889,10 +2889,10 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
 
        ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC);
        if (ret < 0) {
-               ops->destroy(dev);
                mutex_lock(&kvm->lock);
                list_del(&dev->vm_node);
                mutex_unlock(&kvm->lock);
+               ops->destroy(dev);
                return ret;
        }