OSDN Git Service

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 19 Mar 2015 18:19:44 +0000 (11:19 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 19 Mar 2015 18:19:44 +0000 (11:19 -0700)
Pull networking fixes from David Miller:

 1) Fix packet header offset calculation in _decode_session6(), from
    Hajime Tazaki.

 2) Fix route leak in error paths of xfrm_lookup(), from Huaibin Wang.

 3) Be sure to clear state properly when scans fail in iwlwifi mvm code,
    from Luciano Coelho.

 4) iwlwifi tries to stop scans that aren't actually running, also from
    Luciano Coelho.

 5) mac80211 should drop mesh frames that are not encrypted, fix from
    Bob Copeland.

 6) Add new device ID to b43 wireless driver for BCM432228 chips, from
    Rafał Miłecki.

 7) Fix accidental addition of members after variable sized array in
    struct tc_u_hnode, from WANG Cong.

 8) Don't re-enable interrupts until after we call napi_complete() in
    ibmveth and WIZnet drivers, frm Yongbae Park.

 9) Fix regression in vlan tag handling of fec driver, from Fugang Duan.

10) If a network namespace change fails during rtnl_newlink(), we don't
    unwind the device registry properly.

11) Fix two TCP regressions, from Neal Cardwell:
  - Don't allow snd_cwnd_cnt to accumulate huge values due to missing
    test in tcp_cong_avoid_ai().
  - Restore CUBIC back to advancing cwnd by 1.5x packets per RTT.

12) Fix performance regression in xne-netback involving push TX
    notifications, from David Vrabel.

13) __skb_tstamp_tx() can be called with a NULL sk pointer, do not
    dereference blindly.  From Willem de Bruijn.

14) Fix potential stack overflow in RDS protocol stack, from Arnd
    Bergmann.

15) VXLAN_VID_MASK used incorrectly in new remote checksum offload
    support of VXLAN driver.  Fix from Alexey Kodanev.

16) Fix too small netlink SKB allocation in inet_diag layer, from Eric
    Dumazet.

17) ieee80211_check_combinations() does not count interfaces correctly,
    from Andrei Otcheretianski.

18) Hardware feature determination in bxn2x driver references a piece of
    software state that actually isn't initialized yet, fix from Michal
    Schmidt.

19) inet_csk_wait_for_connect() needs a sched_annotate_sleep()
    annoation, from Eric Dumazet.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (56 commits)
  Revert "net: cx82310_eth: use common match macro"
  net/mlx4_en: Set statistics bitmap at port init
  IB/mlx4: Saturate RoCE port PMA counters in case of overflow
  net/mlx4_en: Fix off-by-one in ethtool statistics display
  IB/mlx4: Verify net device validity on port change event
  act_bpf: allow non-default TC_ACT opcodes as BPF exec outcome
  Revert "smc91x: retrieve IRQ and trigger flags in a modern way"
  inet: Clean up inet_csk_wait_for_connect() vs. might_sleep()
  ip6_tunnel: fix error code when tunnel exists
  netdevice.h: fix ndo_bridge_* comments
  bnx2x: fix encapsulation features on 57710/57711
  mac80211: ignore CSA to same channel
  nl80211: ignore HT/VHT capabilities without QoS/WMM
  mac80211: ask for ECSA IE to be considered for beacon parse CRC
  mac80211: count interfaces correctly for combination checks
  isdn: icn: use strlcpy() when parsing setup options
  rxrpc: bogus MSG_PEEK test in rxrpc_recvmsg()
  caif: fix MSG_OOB test in caif_seqpkt_recvmsg()
  bridge: reset bridge mtu after deleting an interface
  can: kvaser_usb: Fix tx queue start/stop race conditions
  ...

254 files changed:
Documentation/devicetree/bindings/arm/exynos/power_domain.txt
Documentation/devicetree/bindings/arm/sti.txt
Documentation/devicetree/bindings/power/power_domain.txt
Documentation/devicetree/bindings/serial/8250.txt [moved from Documentation/devicetree/bindings/serial/of-serial.txt with 100% similarity]
Documentation/devicetree/bindings/serial/axis,etraxfs-uart.txt [new file with mode: 0644]
Documentation/devicetree/bindings/submitting-patches.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
MAINTAINERS
Makefile
arch/arm/Makefile
arch/arm/boot/dts/am335x-bone-common.dtsi
arch/arm/boot/dts/am335x-bone.dts
arch/arm/boot/dts/am335x-lxm.dts
arch/arm/boot/dts/am33xx-clocks.dtsi
arch/arm/boot/dts/am43xx-clocks.dtsi
arch/arm/boot/dts/at91sam9260.dtsi
arch/arm/boot/dts/at91sam9261.dtsi
arch/arm/boot/dts/at91sam9263.dtsi
arch/arm/boot/dts/at91sam9g45.dtsi
arch/arm/boot/dts/at91sam9n12.dtsi
arch/arm/boot/dts/at91sam9x5.dtsi
arch/arm/boot/dts/dra7-evm.dts
arch/arm/boot/dts/dra72-evm.dts
arch/arm/boot/dts/dra7xx-clocks.dtsi
arch/arm/boot/dts/exynos3250.dtsi
arch/arm/boot/dts/exynos4-cpu-thermal.dtsi [new file with mode: 0644]
arch/arm/boot/dts/exynos4.dtsi
arch/arm/boot/dts/exynos4210-trats.dts
arch/arm/boot/dts/exynos4210-universal_c210.dts
arch/arm/boot/dts/exynos4210.dtsi
arch/arm/boot/dts/exynos4212.dtsi
arch/arm/boot/dts/exynos4412-odroid-common.dtsi
arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi [new file with mode: 0644]
arch/arm/boot/dts/exynos4412-trats2.dts
arch/arm/boot/dts/exynos4412.dtsi
arch/arm/boot/dts/exynos4x12.dtsi
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5420-trip-points.dtsi [new file with mode: 0644]
arch/arm/boot/dts/exynos5420.dtsi
arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi [new file with mode: 0644]
arch/arm/boot/dts/exynos5440-trip-points.dtsi [new file with mode: 0644]
arch/arm/boot/dts/exynos5440.dtsi
arch/arm/boot/dts/imx6qdl-sabresd.dtsi
arch/arm/boot/dts/imx6sl-evk.dts
arch/arm/boot/dts/omap5-core-thermal.dtsi
arch/arm/boot/dts/omap5-gpu-thermal.dtsi
arch/arm/boot/dts/omap5.dtsi
arch/arm/boot/dts/omap54xx-clocks.dtsi
arch/arm/boot/dts/sama5d3.dtsi
arch/arm/boot/dts/sama5d4.dtsi
arch/arm/boot/dts/socfpga.dtsi
arch/arm/configs/at91_dt_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/omap2plus_defconfig
arch/arm/configs/sama5_defconfig
arch/arm/configs/sunxi_defconfig
arch/arm/configs/vexpress_defconfig
arch/arm/crypto/aesbs-core.S_shipped
arch/arm/crypto/bsaes-armv7.pl
arch/arm/include/asm/kvm_mmu.h
arch/arm/include/debug/at91.S
arch/arm/kvm/mmu.c
arch/arm/mach-at91/pm.c
arch/arm/mach-at91/pm.h
arch/arm/mach-at91/pm_slowclock.S
arch/arm/mach-exynos/platsmp.c
arch/arm/mach-exynos/pm_domains.c
arch/arm/mach-exynos/suspend.c
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod.h
arch/arm/mach-omap2/omap_hwmod_7xx_data.c
arch/arm/mach-omap2/pdata-quirks.c
arch/arm/mach-omap2/prm44xx.c
arch/arm/mach-socfpga/core.h
arch/arm/mach-socfpga/socfpga.c
arch/arm/mach-sti/board-dt.c
arch/arm64/include/asm/kvm_arm.h
arch/arm64/include/asm/kvm_mmu.h
arch/arm64/include/asm/tlb.h
arch/arm64/include/asm/tlbflush.h
arch/arm64/kernel/efi.c
arch/arm64/kernel/head.S
arch/arm64/kernel/process.c
arch/c6x/include/asm/pgtable.h
arch/microblaze/kernel/entry.S
arch/nios2/include/asm/ptrace.h
arch/nios2/include/asm/ucontext.h [deleted file]
arch/nios2/include/uapi/asm/Kbuild
arch/nios2/include/uapi/asm/elf.h
arch/nios2/include/uapi/asm/ptrace.h
arch/nios2/include/uapi/asm/sigcontext.h
arch/nios2/kernel/signal.c
arch/s390/kvm/kvm-s390.c
arch/x86/boot/compressed/aslr.c
arch/x86/boot/compressed/misc.c
arch/x86/boot/compressed/misc.h
arch/x86/crypto/aesni-intel_glue.c
arch/x86/include/asm/fpu-internal.h
arch/x86/include/asm/page_types.h
arch/x86/include/uapi/asm/bootparam.h
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/apic/apic_numachip.c
arch/x86/kernel/module.c
arch/x86/kernel/setup.c
arch/x86/kernel/traps.c
arch/x86/kernel/xsave.c
arch/x86/kvm/i8259.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/vdso/vdso32/sigreturn.S
arch/x86/xen/p2m.c
drivers/acpi/acpi_lpss.c
drivers/base/regmap/regcache-rbtree.c
drivers/base/regmap/regcache.c
drivers/base/regmap/regmap-irq.c
drivers/char/virtio_console.c
drivers/clk/clk-divider.c
drivers/clk/clk.c
drivers/clk/qcom/gcc-msm8960.c
drivers/clk/qcom/lcc-ipq806x.c
drivers/clk/qcom/lcc-msm8960.c
drivers/clk/ti/fapll.c
drivers/clocksource/time-efm32.c
drivers/clocksource/timer-sun5i.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_dp_mst_topology.c
drivers/gpu/drm/drm_mm.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_uncore.c
drivers/gpu/drm/radeon/radeon_fence.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-tivo.c
drivers/hid/usbhid/hid-quirks.c
drivers/hid/wacom_wac.c
drivers/i2c/i2c-core.c
drivers/iommu/Kconfig
drivers/iommu/exynos-iommu.c
drivers/iommu/io-pgtable-arm.c
drivers/iommu/omap-iommu.c
drivers/iommu/rockchip-iommu.c
drivers/irqchip/irq-armada-370-xp.c
drivers/irqchip/irq-gic-v3-its.c
drivers/irqchip/irq-gic-v3.c
drivers/irqchip/irq-gic.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/pxa3xx_nand.c
drivers/of/Kconfig
drivers/of/base.c
drivers/of/overlay.c
drivers/of/unittest.c
drivers/pci/host/pci-xgene.c
drivers/pci/pci-sysfs.c
drivers/regulator/core.c
drivers/regulator/tps65910-regulator.c
drivers/rpmsg/virtio_rpmsg_bus.c
drivers/rtc/rtc-s3c.c
drivers/scsi/libsas/sas_discover.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/legacy/inode.c
drivers/vfio/pci/vfio_pci_intrs.c
drivers/virtio/virtio_balloon.c
drivers/virtio/virtio_mmio.c
drivers/xen/events/events_base.c
drivers/xen/xen-pciback/conf_space.c
drivers/xen/xen-pciback/conf_space.h
drivers/xen/xen-pciback/conf_space_header.c
fs/locks.c
fs/nilfs2/segment.c
fs/notify/fanotify/fanotify.c
fs/ocfs2/ocfs2.h
fs/ocfs2/ocfs2_fs.h
fs/proc/task_mmu.c
include/dt-bindings/pinctrl/am33xx.h
include/dt-bindings/pinctrl/am43xx.h
include/kvm/arm_vgic.h
include/linux/clk.h
include/linux/irqchip/arm-gic-v3.h
include/linux/kasan.h
include/linux/module.h
include/linux/moduleloader.h
include/linux/of_platform.h
include/linux/uio.h
include/linux/vmalloc.h
include/soc/at91/at91sam9_ddrsdr.h
include/uapi/linux/virtio_blk.h
include/uapi/linux/virtio_scsi.h
include/xen/xenbus.h
kernel/events/core.c
kernel/livepatch/core.c
kernel/module.c
lib/Makefile
lib/iov_iter.c [moved from mm/iov_iter.c with 97% similarity]
mm/Makefile
mm/cma.c
mm/huge_memory.c
mm/hugetlb.c
mm/kasan/kasan.c
mm/memcontrol.c
mm/memory.c
mm/mlock.c
mm/nommu.c
mm/page_alloc.c
mm/vmalloc.c
net/9p/trans_virtio.c
sound/core/control.c
sound/firewire/dice/dice-interface.h
sound/firewire/dice/dice-proc.c
sound/firewire/iso-resources.c
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_proc.c
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_conexant.c
sound/soc/codecs/adav80x.c
sound/soc/codecs/ak4641.c
sound/soc/codecs/ak4671.c
sound/soc/codecs/cs4271.c
sound/soc/codecs/da732x.c
sound/soc/codecs/es8328.c
sound/soc/codecs/pcm1681.c
sound/soc/codecs/rt286.c
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/sn95031.c
sound/soc/codecs/tas5086.c
sound/soc/codecs/wm2000.c
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8903.c
sound/soc/codecs/wm8904.c
sound/soc/codecs/wm8955.c
sound/soc/codecs/wm8960.c
sound/soc/codecs/wm9712.c
sound/soc/codecs/wm9713.c
sound/soc/fsl/fsl_spdif.c
sound/soc/fsl/fsl_ssi.c
sound/soc/intel/sst-haswell-dsp.c
sound/soc/intel/sst-haswell-ipc.c
sound/soc/kirkwood/kirkwood-i2s.c
sound/soc/soc-core.c
sound/usb/quirks-table.h
tools/perf/util/annotate.c
tools/power/cpupower/Makefile
tools/testing/selftests/exec/execveat.c
virt/kvm/arm/vgic-v2.c
virt/kvm/arm/vgic-v3.c
virt/kvm/arm/vgic.c
virt/kvm/kvm_main.c

index f4445e5..1e09703 100644 (file)
@@ -22,6 +22,8 @@ Optional Properties:
        - pclkN, clkN: Pairs of parent of input clock and input clock to the
                devices in this power domain. Maximum of 4 pairs (N = 0 to 3)
                are supported currently.
+- power-domains: phandle pointing to the parent power domain, for more details
+                see Documentation/devicetree/bindings/power/power_domain.txt
 
 Node of a device using power domains must have a power-domains property
 defined with a phandle to respective power domain.
index d70ec35..8d27f6b 100644 (file)
@@ -13,6 +13,10 @@ Boards with the ST STiH407 SoC shall have the following properties:
 Required root node property:
 compatible = "st,stih407";
 
+Boards with the ST STiH410 SoC shall have the following properties:
+Required root node property:
+compatible = "st,stih410";
+
 Boards with the ST STiH418 SoC shall have the following properties:
 Required root node property:
 compatible = "st,stih418";
index 98c1667..0f8ed37 100644 (file)
@@ -19,6 +19,16 @@ Required properties:
    providing multiple PM domains (e.g. power controllers), but can be any value
    as specified by device tree binding documentation of particular provider.
 
+Optional properties:
+ - power-domains : A phandle and PM domain specifier as defined by bindings of
+                   the power controller specified by phandle.
+   Some power domains might be powered from another power domain (or have
+   other hardware specific dependencies). For representing such dependency
+   a standard PM domain consumer binding is used. When provided, all domains
+   created by the given provider should be subdomains of the domain
+   specified by this binding. More details about power domain specifier are
+   available in the next section.
+
 Example:
 
        power: power-controller@12340000 {
@@ -30,6 +40,25 @@ Example:
 The node above defines a power controller that is a PM domain provider and
 expects one cell as its phandle argument.
 
+Example 2:
+
+       parent: power-controller@12340000 {
+               compatible = "foo,power-controller";
+               reg = <0x12340000 0x1000>;
+               #power-domain-cells = <1>;
+       };
+
+       child: power-controller@12340000 {
+               compatible = "foo,power-controller";
+               reg = <0x12341000 0x1000>;
+               power-domains = <&parent 0>;
+               #power-domain-cells = <1>;
+       };
+
+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.
+
 ==PM domain consumers==
 
 Required properties:
diff --git a/Documentation/devicetree/bindings/serial/axis,etraxfs-uart.txt b/Documentation/devicetree/bindings/serial/axis,etraxfs-uart.txt
new file mode 100644 (file)
index 0000000..ebcbb62
--- /dev/null
@@ -0,0 +1,19 @@
+ETRAX FS UART
+
+Required properties:
+- compatible : "axis,etraxfs-uart"
+- reg: offset and length of the register set for the device.
+- interrupts: device interrupt
+
+Optional properties:
+- {dtr,dsr,ri,cd}-gpios: specify a GPIO for DTR/DSR/RI/CD
+  line respectively.
+
+Example:
+
+serial@b00260000 {
+       compatible = "axis,etraxfs-uart";
+       reg = <0xb0026000 0x1000>;
+       interrupts = <68>;
+       status = "disabled";
+};
index 56742bc..7d44eae 100644 (file)
@@ -12,6 +12,9 @@ I. For patch submitters
 
        devicetree@vger.kernel.org
 
+     and Cc: the DT maintainers. Use scripts/get_maintainer.pl to identify
+     all of the DT maintainers.
+
   3) The Documentation/ portion of the patch should come in the series before
      the code implementing the binding.
 
index 389ca13..fae26d0 100644 (file)
@@ -20,6 +20,7 @@ amlogic       Amlogic, Inc.
 ams    AMS AG
 amstaos        AMS-Taos Inc.
 apm    Applied Micro Circuits Corporation (APM)
+arasan Arasan Chip Systems
 arm    ARM Ltd.
 armadeus       ARMadeus Systems SARL
 asahi-kasei    Asahi Kasei Corp.
@@ -27,6 +28,7 @@ atmel Atmel Corporation
 auo    AU Optronics Corporation
 avago  Avago Technologies
 avic   Shanghai AVIC Optoelectronics Co., Ltd.
+axis   Axis Communications AB
 bosch  Bosch Sensortec GmbH
 brcm   Broadcom Corporation
 buffalo        Buffalo, Inc.
index f90e294..a4d8697 100644 (file)
@@ -26,6 +26,11 @@ Optional properties:
 - atmel,disable : Should be present if you want to disable the watchdog.
 - atmel,idle-halt : Should be present if you want to stop the watchdog when
        entering idle state.
+       CAUTION: This property should be used with care, it actually makes the
+       watchdog not counting when the CPU is in idle state, therefore the
+       watchdog reset time depends on mean CPU usage and will not reset at all
+       if the CPU stop working while it is in idle state, which is probably
+       not what you want.
 - atmel,dbg-halt : Should be present if you want to stop the watchdog when
        entering debug state.
 
index 80dddbb..9a76a40 100644 (file)
@@ -1030,6 +1030,16 @@ F:       arch/arm/mach-mxs/
 F:     arch/arm/boot/dts/imx*
 F:     arch/arm/configs/imx*_defconfig
 
+ARM/FREESCALE VYBRID ARM ARCHITECTURE
+M:     Shawn Guo <shawn.guo@linaro.org>
+M:     Sascha Hauer <kernel@pengutronix.de>
+R:     Stefan Agner <stefan@agner.ch>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
+F:     arch/arm/mach-imx/*vf610*
+F:     arch/arm/boot/dts/vf*
+
 ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1188,6 +1198,7 @@ ARM/Marvell Dove/MV78xx0/Orion SOC support
 M:     Jason Cooper <jason@lakedaemon.net>
 M:     Andrew Lunn <andrew@lunn.ch>
 M:     Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+M:     Gregory Clement <gregory.clement@free-electrons.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/mach-dove/
@@ -2107,7 +2118,6 @@ F:        drivers/net/ethernet/broadcom/bnx2x/
 
 BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITECTURE
 M:     Christian Daudt <bcm@fixthebug.org>
-M:     Matt Porter <mporter@linaro.org>
 M:     Florian Fainelli <f.fainelli@gmail.com>
 L:     bcm-kernel-feedback-list@broadcom.com
 T:     git git://github.com/broadcom/mach-bcm
index 1100ff3..e734965 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 0
 SUBLEVEL = 0
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
 NAME = Hurr durr I'ma sheep
 
 # *DOCUMENTATION*
index 7f99cd6..eb7bb51 100644 (file)
@@ -150,6 +150,7 @@ machine-$(CONFIG_ARCH_BERLIN)               += berlin
 machine-$(CONFIG_ARCH_CLPS711X)                += clps711x
 machine-$(CONFIG_ARCH_CNS3XXX)         += cns3xxx
 machine-$(CONFIG_ARCH_DAVINCI)         += davinci
+machine-$(CONFIG_ARCH_DIGICOLOR)       += digicolor
 machine-$(CONFIG_ARCH_DOVE)            += dove
 machine-$(CONFIG_ARCH_EBSA110)         += ebsa110
 machine-$(CONFIG_ARCH_EFM32)           += efm32
index 2c6248d..c3255e0 100644 (file)
        cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
        cd-inverted;
 };
+
+&aes {
+       status = "okay";
+};
+
+&sham {
+       status = "okay";
+};
index 83d40f7..6b84937 100644 (file)
 &mmc1 {
        vmmc-supply = <&ldo3_reg>;
 };
-
-&sham {
-       status = "okay";
-};
-
-&aes {
-       status = "okay";
-};
index 7266a00..5c5667a 100644 (file)
        dual_emac_res_vlan = <3>;
 };
 
+&phy_sel {
+       rmii-clock-ext;
+};
+
 &mac {
        pinctrl-names = "default", "sleep";
        pinctrl-0 = <&cpsw_default>;
index 712edce..071b56a 100644 (file)
@@ -99,7 +99,7 @@
        ehrpwm0_tbclk: ehrpwm0_tbclk@44e10664 {
                #clock-cells = <0>;
                compatible = "ti,gate-clock";
-               clocks = <&dpll_per_m2_ck>;
+               clocks = <&l4ls_gclk>;
                ti,bit-shift = <0>;
                reg = <0x0664>;
        };
        ehrpwm1_tbclk: ehrpwm1_tbclk@44e10664 {
                #clock-cells = <0>;
                compatible = "ti,gate-clock";
-               clocks = <&dpll_per_m2_ck>;
+               clocks = <&l4ls_gclk>;
                ti,bit-shift = <1>;
                reg = <0x0664>;
        };
        ehrpwm2_tbclk: ehrpwm2_tbclk@44e10664 {
                #clock-cells = <0>;
                compatible = "ti,gate-clock";
-               clocks = <&dpll_per_m2_ck>;
+               clocks = <&l4ls_gclk>;
                ti,bit-shift = <2>;
                reg = <0x0664>;
        };
index c7dc9da..cfb4968 100644 (file)
        ehrpwm0_tbclk: ehrpwm0_tbclk {
                #clock-cells = <0>;
                compatible = "ti,gate-clock";
-               clocks = <&dpll_per_m2_ck>;
+               clocks = <&l4ls_gclk>;
                ti,bit-shift = <0>;
                reg = <0x0664>;
        };
        ehrpwm1_tbclk: ehrpwm1_tbclk {
                #clock-cells = <0>;
                compatible = "ti,gate-clock";
-               clocks = <&dpll_per_m2_ck>;
+               clocks = <&l4ls_gclk>;
                ti,bit-shift = <1>;
                reg = <0x0664>;
        };
        ehrpwm2_tbclk: ehrpwm2_tbclk {
                #clock-cells = <0>;
                compatible = "ti,gate-clock";
-               clocks = <&dpll_per_m2_ck>;
+               clocks = <&l4ls_gclk>;
                ti,bit-shift = <2>;
                reg = <0x0664>;
        };
        ehrpwm3_tbclk: ehrpwm3_tbclk {
                #clock-cells = <0>;
                compatible = "ti,gate-clock";
-               clocks = <&dpll_per_m2_ck>;
+               clocks = <&l4ls_gclk>;
                ti,bit-shift = <4>;
                reg = <0x0664>;
        };
        ehrpwm4_tbclk: ehrpwm4_tbclk {
                #clock-cells = <0>;
                compatible = "ti,gate-clock";
-               clocks = <&dpll_per_m2_ck>;
+               clocks = <&l4ls_gclk>;
                ti,bit-shift = <5>;
                reg = <0x0664>;
        };
        ehrpwm5_tbclk: ehrpwm5_tbclk {
                #clock-cells = <0>;
                compatible = "ti,gate-clock";
-               clocks = <&dpll_per_m2_ck>;
+               clocks = <&l4ls_gclk>;
                ti,bit-shift = <6>;
                reg = <0x0664>;
        };
index fff0ee6..e7f0a4a 100644 (file)
 
                                        pinctrl_usart3_rts: usart3_rts-0 {
                                                atmel,pins =
-                                                       <AT91_PIOB 8 AT91_PERIPH_B AT91_PINCTRL_NONE>;  /* PC8 periph B */
+                                                       <AT91_PIOC 8 AT91_PERIPH_B AT91_PINCTRL_NONE>;
                                        };
 
                                        pinctrl_usart3_cts: usart3_cts-0 {
                                                atmel,pins =
-                                                       <AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PC10 periph B */
+                                                       <AT91_PIOC 10 AT91_PERIPH_B AT91_PINCTRL_NONE>;
                                        };
                                };
 
                        };
 
                        usb1: gadget@fffa4000 {
-                               compatible = "atmel,at91rm9200-udc";
+                               compatible = "atmel,at91sam9260-udc";
                                reg = <0xfffa4000 0x4000>;
                                interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>;
                                clocks = <&udc_clk>, <&udpck>;
                                atmel,watchdog-type = "hardware";
                                atmel,reset-type = "all";
                                atmel,dbg-halt;
-                               atmel,idle-halt;
                                status = "disabled";
                        };
 
index e247b0b..d55fdf2 100644 (file)
                        };
 
                        usb1: gadget@fffa4000 {
-                               compatible = "atmel,at91rm9200-udc";
+                               compatible = "atmel,at91sam9261-udc";
                                reg = <0xfffa4000 0x4000>;
                                interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>;
-                               clocks = <&usb>, <&udc_clk>, <&udpck>;
-                               clock-names = "usb_clk", "udc_clk", "udpck";
+                               clocks = <&udc_clk>, <&udpck>;
+                               clock-names = "pclk", "hclk";
+                               atmel,matrix = <&matrix>;
                                status = "disabled";
                        };
 
                        };
 
                        matrix: matrix@ffffee00 {
-                               compatible = "atmel,at91sam9260-bus-matrix";
+                               compatible = "atmel,at91sam9260-bus-matrix", "syscon";
                                reg = <0xffffee00 0x200>;
                        };
 
index 1f67bb4..fce301c 100644 (file)
@@ -69,7 +69,7 @@
 
        sram1: sram@00500000 {
                compatible = "mmio-sram";
-               reg = <0x00300000 0x4000>;
+               reg = <0x00500000 0x4000>;
        };
 
        ahb {
                        };
 
                        usb1: gadget@fff78000 {
-                               compatible = "atmel,at91rm9200-udc";
+                               compatible = "atmel,at91sam9263-udc";
                                reg = <0xfff78000 0x4000>;
                                interrupts = <24 IRQ_TYPE_LEVEL_HIGH 2>;
                                clocks = <&udc_clk>, <&udpck>;
                                atmel,watchdog-type = "hardware";
                                atmel,reset-type = "all";
                                atmel,dbg-halt;
-                               atmel,idle-halt;
                                status = "disabled";
                        };
 
index ee80aa9..488af63 100644 (file)
                                atmel,watchdog-type = "hardware";
                                atmel,reset-type = "all";
                                atmel,dbg-halt;
-                               atmel,idle-halt;
                                status = "disabled";
                        };
 
                        compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
                        reg = <0x00800000 0x100000>;
                        interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
-                       clocks = <&usb>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>;
+                       clocks = <&utmi>, <&uhphs_clk>, <&uhphs_clk>, <&uhpck>;
                        clock-names = "usb_clk", "ehci_clk", "hclk", "uhpck";
                        status = "disabled";
                };
index c2666a7..0c53a37 100644 (file)
                                atmel,watchdog-type = "hardware";
                                atmel,reset-type = "all";
                                atmel,dbg-halt;
-                               atmel,idle-halt;
                                status = "disabled";
                        };
 
index 818dabd..d221179 100644 (file)
                                reg = <0x00500000 0x80000
                                       0xf803c000 0x400>;
                                interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>;
-                               clocks = <&usb>, <&udphs_clk>;
+                               clocks = <&utmi>, <&udphs_clk>;
                                clock-names = "hclk", "pclk";
                                status = "disabled";
 
                                atmel,watchdog-type = "hardware";
                                atmel,reset-type = "all";
                                atmel,dbg-halt;
-                               atmel,idle-halt;
                                status = "disabled";
                        };
 
                        compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
                        reg = <0x00700000 0x100000>;
                        interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
-                       clocks = <&usb>, <&uhphs_clk>, <&uhpck>;
+                       clocks = <&utmi>, <&uhphs_clk>, <&uhpck>;
                        clock-names = "usb_clk", "ehci_clk", "uhpck";
                        status = "disabled";
                };
index 3290a96..7563d7c 100644 (file)
 
        dcan1_pins_default: dcan1_pins_default {
                pinctrl-single,pins = <
-                       0x3d0   (PIN_OUTPUT | MUX_MODE0) /* dcan1_tx */
-                       0x3d4   (MUX_MODE15)            /* dcan1_rx.off */
-                       0x418   (PULL_DIS | MUX_MODE1) /* wakeup0.dcan1_rx */
+                       0x3d0   (PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */
+                       0x418   (PULL_UP | MUX_MODE1) /* wakeup0.dcan1_rx */
                >;
        };
 
        dcan1_pins_sleep: dcan1_pins_sleep {
                pinctrl-single,pins = <
-                       0x3d0   (MUX_MODE15)    /* dcan1_tx.off */
-                       0x3d4   (MUX_MODE15)    /* dcan1_rx.off */
-                       0x418   (MUX_MODE15)    /* wakeup0.off */
+                       0x3d0   (MUX_MODE15 | PULL_UP)  /* dcan1_tx.off */
+                       0x418   (MUX_MODE15 | PULL_UP)  /* wakeup0.off */
                >;
        };
 };
index e0264d0..40ed539 100644 (file)
 
        dcan1_pins_default: dcan1_pins_default {
                pinctrl-single,pins = <
-                       0x3d0   (PIN_OUTPUT | MUX_MODE0) /* dcan1_tx */
-                       0x3d4   (MUX_MODE15)            /* dcan1_rx.off */
-                       0x418   (PULL_DIS | MUX_MODE1) /* wakeup0.dcan1_rx */
+                       0x3d0   (PIN_OUTPUT_PULLUP | MUX_MODE0) /* dcan1_tx */
+                       0x418   (PULL_UP | MUX_MODE1)   /* wakeup0.dcan1_rx */
                >;
        };
 
        dcan1_pins_sleep: dcan1_pins_sleep {
                pinctrl-single,pins = <
-                       0x3d0   (MUX_MODE15)    /* dcan1_tx.off */
-                       0x3d4   (MUX_MODE15)    /* dcan1_rx.off */
-                       0x418   (MUX_MODE15)    /* wakeup0.off */
+                       0x3d0   (MUX_MODE15 | PULL_UP)  /* dcan1_tx.off */
+                       0x418   (MUX_MODE15 | PULL_UP)  /* wakeup0.off */
                >;
        };
 
index 4bdcbd6..99b09a4 100644 (file)
                ti,invert-autoidle-bit;
        };
 
+       dpll_core_byp_mux: dpll_core_byp_mux {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+               ti,bit-shift = <23>;
+               reg = <0x012c>;
+       };
+
        dpll_core_ck: dpll_core_ck {
                #clock-cells = <0>;
                compatible = "ti,omap4-dpll-core-clock";
-               clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+               clocks = <&sys_clkin1>, <&dpll_core_byp_mux>;
                reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>;
        };
 
                clock-div = <1>;
        };
 
+       dpll_dsp_byp_mux: dpll_dsp_byp_mux {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>;
+               ti,bit-shift = <23>;
+               reg = <0x0240>;
+       };
+
        dpll_dsp_ck: dpll_dsp_ck {
                #clock-cells = <0>;
                compatible = "ti,omap4-dpll-clock";
-               clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>;
+               clocks = <&sys_clkin1>, <&dpll_dsp_byp_mux>;
                reg = <0x0234>, <0x0238>, <0x0240>, <0x023c>;
        };
 
                clock-div = <1>;
        };
 
+       dpll_iva_byp_mux: dpll_iva_byp_mux {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>;
+               ti,bit-shift = <23>;
+               reg = <0x01ac>;
+       };
+
        dpll_iva_ck: dpll_iva_ck {
                #clock-cells = <0>;
                compatible = "ti,omap4-dpll-clock";
-               clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>;
+               clocks = <&sys_clkin1>, <&dpll_iva_byp_mux>;
                reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>;
        };
 
                clock-div = <1>;
        };
 
+       dpll_gpu_byp_mux: dpll_gpu_byp_mux {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+               ti,bit-shift = <23>;
+               reg = <0x02e4>;
+       };
+
        dpll_gpu_ck: dpll_gpu_ck {
                #clock-cells = <0>;
                compatible = "ti,omap4-dpll-clock";
-               clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+               clocks = <&sys_clkin1>, <&dpll_gpu_byp_mux>;
                reg = <0x02d8>, <0x02dc>, <0x02e4>, <0x02e0>;
        };
 
                clock-div = <1>;
        };
 
+       dpll_ddr_byp_mux: dpll_ddr_byp_mux {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+               ti,bit-shift = <23>;
+               reg = <0x021c>;
+       };
+
        dpll_ddr_ck: dpll_ddr_ck {
                #clock-cells = <0>;
                compatible = "ti,omap4-dpll-clock";
-               clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+               clocks = <&sys_clkin1>, <&dpll_ddr_byp_mux>;
                reg = <0x0210>, <0x0214>, <0x021c>, <0x0218>;
        };
 
                ti,invert-autoidle-bit;
        };
 
+       dpll_gmac_byp_mux: dpll_gmac_byp_mux {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+               ti,bit-shift = <23>;
+               reg = <0x02b4>;
+       };
+
        dpll_gmac_ck: dpll_gmac_ck {
                #clock-cells = <0>;
                compatible = "ti,omap4-dpll-clock";
-               clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+               clocks = <&sys_clkin1>, <&dpll_gmac_byp_mux>;
                reg = <0x02a8>, <0x02ac>, <0x02b4>, <0x02b0>;
        };
 
                clock-div = <1>;
        };
 
+       dpll_eve_byp_mux: dpll_eve_byp_mux {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>;
+               ti,bit-shift = <23>;
+               reg = <0x0290>;
+       };
+
        dpll_eve_ck: dpll_eve_ck {
                #clock-cells = <0>;
                compatible = "ti,omap4-dpll-clock";
-               clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>;
+               clocks = <&sys_clkin1>, <&dpll_eve_byp_mux>;
                reg = <0x0284>, <0x0288>, <0x0290>, <0x028c>;
        };
 
                clock-div = <1>;
        };
 
+       dpll_per_byp_mux: dpll_per_byp_mux {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>;
+               ti,bit-shift = <23>;
+               reg = <0x014c>;
+       };
+
        dpll_per_ck: dpll_per_ck {
                #clock-cells = <0>;
                compatible = "ti,omap4-dpll-clock";
-               clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>;
+               clocks = <&sys_clkin1>, <&dpll_per_byp_mux>;
                reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>;
        };
 
                clock-div = <1>;
        };
 
+       dpll_usb_byp_mux: dpll_usb_byp_mux {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>;
+               ti,bit-shift = <23>;
+               reg = <0x018c>;
+       };
+
        dpll_usb_ck: dpll_usb_ck {
                #clock-cells = <0>;
                compatible = "ti,omap4-dpll-j-type-clock";
-               clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>;
+               clocks = <&sys_clkin1>, <&dpll_usb_byp_mux>;
                reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>;
        };
 
index 277b48b..ac6b0ae 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include "skeleton.dtsi"
+#include "exynos4-cpu-thermal.dtsi"
 #include <dt-bindings/clock/exynos3250.h>
 
 / {
                        interrupts = <0 216 0>;
                        clocks = <&cmu CLK_TMU_APBIF>;
                        clock-names = "tmu_apbif";
+                       #include "exynos4412-tmu-sensor-conf.dtsi"
                        status = "disabled";
                };
 
diff --git a/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi b/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi
new file mode 100644 (file)
index 0000000..735cb2f
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Device tree sources for Exynos4 thermal zone
+ *
+ * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.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
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+thermal-zones {
+       cpu_thermal: cpu-thermal {
+               thermal-sensors = <&tmu 0>;
+               polling-delay-passive = <0>;
+               polling-delay = <0>;
+               trips {
+                       cpu_alert0: cpu-alert-0 {
+                               temperature = <70000>; /* millicelsius */
+                               hysteresis = <10000>; /* millicelsius */
+                               type = "active";
+                       };
+                       cpu_alert1: cpu-alert-1 {
+                               temperature = <95000>; /* millicelsius */
+                               hysteresis = <10000>; /* millicelsius */
+                               type = "active";
+                       };
+                       cpu_alert2: cpu-alert-2 {
+                               temperature = <110000>; /* millicelsius */
+                               hysteresis = <10000>; /* millicelsius */
+                               type = "active";
+                       };
+                       cpu_crit0: cpu-crit-0 {
+                               temperature = <120000>; /* millicelsius */
+                               hysteresis = <0>; /* millicelsius */
+                               type = "critical";
+                       };
+               };
+               cooling-maps {
+                       map0 {
+                               trip = <&cpu_alert0>;
+                       };
+                       map1 {
+                               trip = <&cpu_alert1>;
+                       };
+               };
+       };
+};
+};
index 76173ca..77ea547 100644 (file)
@@ -38,6 +38,7 @@
                i2c5 = &i2c_5;
                i2c6 = &i2c_6;
                i2c7 = &i2c_7;
+               i2c8 = &i2c_8;
                csis0 = &csis_0;
                csis1 = &csis_1;
                fimc0 = &fimc_0;
                compatible = "samsung,exynos4210-pd";
                reg = <0x10023C20 0x20>;
                #power-domain-cells = <0>;
+               power-domains = <&pd_lcd0>;
        };
 
        pd_cam: cam-power-domain@10023C00 {
                status = "disabled";
        };
 
+       i2c_8: i2c@138E0000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "samsung,s3c2440-hdmiphy-i2c";
+               reg = <0x138E0000 0x100>;
+               interrupts = <0 93 0>;
+               clocks = <&clock CLK_I2C_HDMI>;
+               clock-names = "i2c";
+               status = "disabled";
+
+               hdmi_i2c_phy: hdmiphy@38 {
+                       compatible = "exynos4210-hdmiphy";
+                       reg = <0x38>;
+               };
+       };
+
        spi_0: spi@13920000 {
                compatible = "samsung,exynos4210-spi";
                reg = <0x13920000 0x100>;
                status = "disabled";
        };
 
+       tmu: tmu@100C0000 {
+               #include "exynos4412-tmu-sensor-conf.dtsi"
+       };
+
+       hdmi: hdmi@12D00000 {
+               compatible = "samsung,exynos4210-hdmi";
+               reg = <0x12D00000 0x70000>;
+               interrupts = <0 92 0>;
+               clock-names = "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy",
+                       "mout_hdmi";
+               clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>,
+                       <&clock CLK_SCLK_PIXEL>, <&clock CLK_SCLK_HDMIPHY>,
+                       <&clock CLK_MOUT_HDMI>;
+               phy = <&hdmi_i2c_phy>;
+               power-domains = <&pd_tv>;
+               samsung,syscon-phandle = <&pmu_system_controller>;
+               status = "disabled";
+       };
+
+       mixer: mixer@12C10000 {
+               compatible = "samsung,exynos4210-mixer";
+               interrupts = <0 91 0>;
+               reg = <0x12C10000 0x2100>, <0x12c00000 0x300>;
+               power-domains = <&pd_tv>;
+               status = "disabled";
+       };
+
        ppmu_dmc0: ppmu_dmc0@106a0000 {
                compatible = "samsung,exynos-ppmu";
                reg = <0x106a0000 0x2000>;
index 3d6652a..32c5fd8 100644 (file)
                status = "okay";
        };
 
+       tmu@100C0000 {
+               status = "okay";
+       };
+
+       thermal-zones {
+               cpu_thermal: cpu-thermal {
+                       cooling-maps {
+                               map0 {
+                                    /* Corresponds to 800MHz at freq_table */
+                                    cooling-device = <&cpu0 2 2>;
+                               };
+                               map1 {
+                                    /* Corresponds to 200MHz at freq_table */
+                                    cooling-device = <&cpu0 4 4>;
+                              };
+                      };
+               };
+       };
+
        camera {
                pinctrl-names = "default";
                pinctrl-0 = <>;
index b57e6b8..d4f2b11 100644 (file)
                        assigned-clock-rates = <0>, <160000000>;
                };
        };
+
+       hdmi_en: voltage-regulator-hdmi-5v {
+               compatible = "regulator-fixed";
+               regulator-name = "HDMI_5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpe0 1 0>;
+               enable-active-high;
+       };
+
+       hdmi_ddc: i2c-ddc {
+               compatible = "i2c-gpio";
+               gpios = <&gpe4 2 0 &gpe4 3 0>;
+               i2c-gpio,delay-us = <100>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               pinctrl-0 = <&i2c_ddc_bus>;
+               pinctrl-names = "default";
+               status = "okay";
+       };
+
+       mixer@12C10000 {
+               status = "okay";
+       };
+
+       hdmi@12D00000 {
+               hpd-gpio = <&gpx3 7 0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&hdmi_hpd>;
+               hdmi-en-supply = <&hdmi_en>;
+               vdd-supply = <&ldo3_reg>;
+               vdd_osc-supply = <&ldo4_reg>;
+               vdd_pll-supply = <&ldo3_reg>;
+               ddc = <&hdmi_ddc>;
+               status = "okay";
+       };
+
+       i2c@138E0000 {
+               status = "okay";
+       };
+};
+
+&pinctrl_1 {
+       hdmi_hpd: hdmi-hpd {
+               samsung,pins = "gpx3-7";
+               samsung,pin-pud = <0>;
+       };
+};
+
+&pinctrl_0 {
+       i2c_ddc_bus: i2c-ddc-bus {
+               samsung,pins = "gpe4-2", "gpe4-3";
+               samsung,pin-function = <2>;
+               samsung,pin-pud = <3>;
+               samsung,pin-drv = <0>;
+       };
 };
 
 &mdma1 {
index 67c832c..be89f83 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "exynos4.dtsi"
 #include "exynos4210-pinctrl.dtsi"
+#include "exynos4-cpu-thermal.dtsi"
 
 / {
        compatible = "samsung,exynos4210", "samsung,exynos4";
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu@900 {
+               cpu0: cpu@900 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0x900>;
+                       cooling-min-level = <4>;
+                       cooling-max-level = <2>;
+                       #cooling-cells = <2>; /* min followed by max */
                };
 
                cpu@901 {
                reg = <0x03860000 0x1000>;
        };
 
-       tmu@100C0000 {
+       tmu: tmu@100C0000 {
                compatible = "samsung,exynos4210-tmu";
                interrupt-parent = <&combiner>;
                reg = <0x100C0000 0x100>;
                interrupts = <2 4>;
                clocks = <&clock CLK_TMU_APBIF>;
                clock-names = "tmu_apbif";
+               samsung,tmu_gain = <15>;
+               samsung,tmu_reference_voltage = <7>;
                status = "disabled";
        };
 
+       thermal-zones {
+               cpu_thermal: cpu-thermal {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&tmu 0>;
+
+                       trips {
+                             cpu_alert0: cpu-alert-0 {
+                                     temperature = <85000>; /* millicelsius */
+                             };
+                             cpu_alert1: cpu-alert-1 {
+                                     temperature = <100000>; /* millicelsius */
+                             };
+                             cpu_alert2: cpu-alert-2 {
+                                     temperature = <110000>; /* millicelsius */
+                             };
+                       };
+               };
+       };
+
        g2d@12800000 {
                compatible = "samsung,s5pv210-g2d";
                reg = <0x12800000 0x1000>;
                };
        };
 
+       mixer: mixer@12C10000 {
+               clock-names = "mixer", "hdmi", "sclk_hdmi", "vp", "mout_mixer",
+                       "sclk_mixer";
+               clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
+                       <&clock CLK_SCLK_HDMI>, <&clock CLK_VP>,
+                       <&clock CLK_MOUT_MIXER>, <&clock CLK_SCLK_MIXER>;
+       };
+
        ppmu_lcd1: ppmu_lcd1@12240000 {
                compatible = "samsung,exynos-ppmu";
                reg = <0x12240000 0x2000>;
index dd0a43e..5be0328 100644 (file)
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu@A00 {
+               cpu0: cpu@A00 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0xA00>;
+                       cooling-min-level = <13>;
+                       cooling-max-level = <7>;
+                       #cooling-cells = <2>; /* min followed by max */
                };
 
                cpu@A01 {
index de80b5b..adb4f6a 100644 (file)
                                        regulator-always-on;
                                };
 
+                               ldo8_reg: ldo@8 {
+                                       regulator-compatible = "LDO8";
+                                       regulator-name = "VDD10_HDMI_1.0V";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                               };
+
+                               ldo10_reg: ldo@10 {
+                                       regulator-compatible = "LDO10";
+                                       regulator-name = "VDDQ_MIPIHSI_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
                                ldo11_reg: LDO11 {
                                        regulator-name = "VDD18_ABB1_1.8V";
                                        regulator-min-microvolt = <1800000>;
        ehci: ehci@12580000 {
                status = "okay";
        };
+
+       tmu@100C0000 {
+               vtmu-supply = <&ldo10_reg>;
+               status = "okay";
+       };
+
+       thermal-zones {
+               cpu_thermal: cpu-thermal {
+                       cooling-maps {
+                               map0 {
+                                    /* Corresponds to 800MHz at freq_table */
+                                    cooling-device = <&cpu0 7 7>;
+                               };
+                               map1 {
+                                    /* Corresponds to 200MHz at freq_table */
+                                    cooling-device = <&cpu0 13 13>;
+                              };
+                      };
+               };
+       };
+
+       mixer: mixer@12C10000 {
+               status = "okay";
+       };
+
+       hdmi@12D00000 {
+               hpd-gpio = <&gpx3 7 0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&hdmi_hpd>;
+               vdd-supply = <&ldo8_reg>;
+               vdd_osc-supply = <&ldo10_reg>;
+               vdd_pll-supply = <&ldo8_reg>;
+               ddc = <&hdmi_ddc>;
+               status = "okay";
+       };
+
+       hdmi_ddc: i2c@13880000 {
+               status = "okay";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c2_bus>;
+       };
+
+       i2c@138E0000 {
+               status = "okay";
+       };
 };
 
 &pinctrl_1 {
                samsung,pin-pud = <0>;
                samsung,pin-drv = <0>;
        };
+
+       hdmi_hpd: hdmi-hpd {
+               samsung,pins = "gpx3-7";
+               samsung,pin-pud = <1>;
+       };
 };
diff --git a/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi b/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
new file mode 100644 (file)
index 0000000..e3f7934
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Device tree sources for Exynos4412 TMU sensor configuration
+ *
+ * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.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
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/thermal/thermal_exynos.h>
+
+#thermal-sensor-cells = <0>;
+samsung,tmu_gain = <8>;
+samsung,tmu_reference_voltage = <16>;
+samsung,tmu_noise_cancel_mode = <4>;
+samsung,tmu_efuse_value = <55>;
+samsung,tmu_min_efuse_value = <40>;
+samsung,tmu_max_efuse_value = <100>;
+samsung,tmu_first_point_trim = <25>;
+samsung,tmu_second_point_trim = <85>;
+samsung,tmu_default_temp_offset = <50>;
+samsung,tmu_cal_type = <TYPE_ONE_POINT_TRIMMING>;
index 21f7480..173ffa4 100644 (file)
                pulldown-ohm = <100000>; /* 100K */
                io-channels = <&adc 2>;  /* Battery temperature */
        };
+
+       thermal-zones {
+               cpu_thermal: cpu-thermal {
+                       cooling-maps {
+                               map0 {
+                                    /* Corresponds to 800MHz at freq_table */
+                                    cooling-device = <&cpu0 7 7>;
+                               };
+                               map1 {
+                                    /* Corresponds to 200MHz at freq_table */
+                                    cooling-device = <&cpu0 13 13>;
+                              };
+                      };
+               };
+       };
 };
 
 &pmu_system_controller {
index 0f6ec93..68ad43b 100644 (file)
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu@A00 {
+               cpu0: cpu@A00 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0xA00>;
+                       cooling-min-level = <13>;
+                       cooling-max-level = <7>;
+                       #cooling-cells = <2>; /* min followed by max */
                };
 
                cpu@A01 {
index f5e0ae7..6a6abe1 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "exynos4.dtsi"
 #include "exynos4x12-pinctrl.dtsi"
+#include "exynos4-cpu-thermal.dtsi"
 
 / {
        aliases {
                clock-names = "tmu_apbif";
                status = "disabled";
        };
+
+       hdmi: hdmi@12D00000 {
+               compatible = "samsung,exynos4212-hdmi";
+       };
+
+       mixer: mixer@12C10000 {
+               compatible = "samsung,exynos4212-mixer";
+               clock-names = "mixer", "hdmi", "sclk_hdmi", "vp";
+               clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
+                        <&clock CLK_SCLK_HDMI>, <&clock CLK_VP>;
+       };
 };
index 9bb1b0b..adbde1a 100644 (file)
@@ -20,7 +20,7 @@
 #include <dt-bindings/clock/exynos5250.h>
 #include "exynos5.dtsi"
 #include "exynos5250-pinctrl.dtsi"
-
+#include "exynos4-cpu-thermal.dtsi"
 #include <dt-bindings/clock/exynos-audss-clk.h>
 
 / {
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu@0 {
+               cpu0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a15";
                        reg = <0>;
                        clock-frequency = <1700000000>;
+                       cooling-min-level = <15>;
+                       cooling-max-level = <9>;
+                       #cooling-cells = <2>; /* min followed by max */
                };
                cpu@1 {
                        device_type = "cpu";
                #power-domain-cells = <0>;
        };
 
+       pd_disp1: disp1-power-domain@100440A0 {
+               compatible = "samsung,exynos4210-pd";
+               reg = <0x100440A0 0x20>;
+               #power-domain-cells = <0>;
+       };
+
        clock: clock-controller@10010000 {
                compatible = "samsung,exynos5250-clock";
                reg = <0x10010000 0x30000>;
                status = "disabled";
        };
 
-       tmu@10060000 {
+       tmu: tmu@10060000 {
                compatible = "samsung,exynos5250-tmu";
                reg = <0x10060000 0x100>;
                interrupts = <0 65 0>;
                clocks = <&clock CLK_TMU>;
                clock-names = "tmu_apbif";
+               #include "exynos4412-tmu-sensor-conf.dtsi"
+       };
+
+       thermal-zones {
+               cpu_thermal: cpu-thermal {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&tmu 0>;
+
+                       cooling-maps {
+                               map0 {
+                                    /* Corresponds to 800MHz at freq_table */
+                                    cooling-device = <&cpu0 9 9>;
+                               };
+                               map1 {
+                                    /* Corresponds to 200MHz at freq_table */
+                                    cooling-device = <&cpu0 15 15>;
+                              };
+                      };
+               };
        };
 
        serial@12C00000 {
        hdmi: hdmi {
                compatible = "samsung,exynos4212-hdmi";
                reg = <0x14530000 0x70000>;
+               power-domains = <&pd_disp1>;
                interrupts = <0 95 0>;
                clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>,
                         <&clock CLK_SCLK_PIXEL>, <&clock CLK_SCLK_HDMIPHY>,
        mixer {
                compatible = "samsung,exynos5250-mixer";
                reg = <0x14450000 0x10000>;
+               power-domains = <&pd_disp1>;
                interrupts = <0 94 0>;
-               clocks = <&clock CLK_MIXER>, <&clock CLK_SCLK_HDMI>;
-               clock-names = "mixer", "sclk_hdmi";
+               clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
+                        <&clock CLK_SCLK_HDMI>;
+               clock-names = "mixer", "hdmi", "sclk_hdmi";
        };
 
        dp_phy: video-phy@10040720 {
        };
 
        dp: dp-controller@145B0000 {
+               power-domains = <&pd_disp1>;
                clocks = <&clock CLK_DP>;
                clock-names = "dp";
                phys = <&dp_phy>;
        };
 
        fimd: fimd@14400000 {
+               power-domains = <&pd_disp1>;
                clocks = <&clock CLK_SCLK_FIMD1>, <&clock CLK_FIMD1>;
                clock-names = "sclk_fimd", "fimd";
        };
diff --git a/arch/arm/boot/dts/exynos5420-trip-points.dtsi b/arch/arm/boot/dts/exynos5420-trip-points.dtsi
new file mode 100644 (file)
index 0000000..5d31fc1
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Device tree sources for default Exynos5420 thermal zone definition
+ *
+ * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.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
+ * published by the Free Software Foundation.
+ *
+ */
+
+polling-delay-passive = <0>;
+polling-delay = <0>;
+trips {
+       cpu-alert-0 {
+               temperature = <85000>; /* millicelsius */
+               hysteresis = <10000>; /* millicelsius */
+               type = "active";
+       };
+       cpu-alert-1 {
+               temperature = <103000>; /* millicelsius */
+               hysteresis = <10000>; /* millicelsius */
+               type = "active";
+       };
+       cpu-alert-2 {
+               temperature = <110000>; /* millicelsius */
+               hysteresis = <10000>; /* millicelsius */
+               type = "active";
+       };
+       cpu-crit-0 {
+               temperature = <1200000>; /* millicelsius */
+               hysteresis = <0>; /* millicelsius */
+               type = "critical";
+       };
+};
index 9dc2e97..c0e98cf 100644 (file)
                compatible = "samsung,exynos5420-mixer";
                reg = <0x14450000 0x10000>;
                interrupts = <0 94 0>;
-               clocks = <&clock CLK_MIXER>, <&clock CLK_SCLK_HDMI>;
-               clock-names = "mixer", "sclk_hdmi";
+               clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
+                        <&clock CLK_SCLK_HDMI>;
+               clock-names = "mixer", "hdmi", "sclk_hdmi";
                power-domains = <&disp_pd>;
        };
 
                interrupts = <0 65 0>;
                clocks = <&clock CLK_TMU>;
                clock-names = "tmu_apbif";
+               #include "exynos4412-tmu-sensor-conf.dtsi"
        };
 
        tmu_cpu1: tmu@10064000 {
                interrupts = <0 183 0>;
                clocks = <&clock CLK_TMU>;
                clock-names = "tmu_apbif";
+               #include "exynos4412-tmu-sensor-conf.dtsi"
        };
 
        tmu_cpu2: tmu@10068000 {
                interrupts = <0 184 0>;
                clocks = <&clock CLK_TMU>, <&clock CLK_TMU>;
                clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+               #include "exynos4412-tmu-sensor-conf.dtsi"
        };
 
        tmu_cpu3: tmu@1006c000 {
                interrupts = <0 185 0>;
                clocks = <&clock CLK_TMU>, <&clock CLK_TMU_GPU>;
                clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+               #include "exynos4412-tmu-sensor-conf.dtsi"
        };
 
        tmu_gpu: tmu@100a0000 {
                interrupts = <0 215 0>;
                clocks = <&clock CLK_TMU_GPU>, <&clock CLK_TMU>;
                clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+               #include "exynos4412-tmu-sensor-conf.dtsi"
+       };
+
+       thermal-zones {
+               cpu0_thermal: cpu0-thermal {
+                       thermal-sensors = <&tmu_cpu0>;
+                       #include "exynos5420-trip-points.dtsi"
+               };
+               cpu1_thermal: cpu1-thermal {
+                      thermal-sensors = <&tmu_cpu1>;
+                      #include "exynos5420-trip-points.dtsi"
+               };
+               cpu2_thermal: cpu2-thermal {
+                      thermal-sensors = <&tmu_cpu2>;
+                      #include "exynos5420-trip-points.dtsi"
+               };
+               cpu3_thermal: cpu3-thermal {
+                      thermal-sensors = <&tmu_cpu3>;
+                      #include "exynos5420-trip-points.dtsi"
+               };
+               gpu_thermal: gpu-thermal {
+                      thermal-sensors = <&tmu_gpu>;
+                      #include "exynos5420-trip-points.dtsi"
+               };
        };
 
         watchdog: watchdog@101D0000 {
diff --git a/arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi b/arch/arm/boot/dts/exynos5440-tmu-sensor-conf.dtsi
new file mode 100644 (file)
index 0000000..7b2fba0
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Device tree sources for Exynos5440 TMU sensor configuration
+ *
+ * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.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
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/thermal/thermal_exynos.h>
+
+#thermal-sensor-cells = <0>;
+samsung,tmu_gain = <5>;
+samsung,tmu_reference_voltage = <16>;
+samsung,tmu_noise_cancel_mode = <4>;
+samsung,tmu_efuse_value = <0x5d2d>;
+samsung,tmu_min_efuse_value = <16>;
+samsung,tmu_max_efuse_value = <76>;
+samsung,tmu_first_point_trim = <25>;
+samsung,tmu_second_point_trim = <70>;
+samsung,tmu_default_temp_offset = <25>;
+samsung,tmu_cal_type = <TYPE_ONE_POINT_TRIMMING>;
diff --git a/arch/arm/boot/dts/exynos5440-trip-points.dtsi b/arch/arm/boot/dts/exynos5440-trip-points.dtsi
new file mode 100644 (file)
index 0000000..48adfa8
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Device tree sources for default Exynos5440 thermal zone definition
+ *
+ * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.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
+ * published by the Free Software Foundation.
+ *
+ */
+
+polling-delay-passive = <0>;
+polling-delay = <0>;
+trips {
+       cpu-alert-0 {
+               temperature = <100000>; /* millicelsius */
+               hysteresis = <0>; /* millicelsius */
+               type = "active";
+       };
+       cpu-crit-0 {
+               temperature = <1050000>; /* millicelsius */
+               hysteresis = <0>; /* millicelsius */
+               type = "critical";
+       };
+};
index 8f3373c..59d9416 100644 (file)
                interrupts = <0 58 0>;
                clocks = <&clock CLK_B_125>;
                clock-names = "tmu_apbif";
+               #include "exynos5440-tmu-sensor-conf.dtsi"
        };
 
        tmuctrl_1: tmuctrl@16011C {
                interrupts = <0 58 0>;
                clocks = <&clock CLK_B_125>;
                clock-names = "tmu_apbif";
+               #include "exynos5440-tmu-sensor-conf.dtsi"
        };
 
        tmuctrl_2: tmuctrl@160120 {
                interrupts = <0 58 0>;
                clocks = <&clock CLK_B_125>;
                clock-names = "tmu_apbif";
+               #include "exynos5440-tmu-sensor-conf.dtsi"
+       };
+
+       thermal-zones {
+               cpu0_thermal: cpu0-thermal {
+                       thermal-sensors = <&tmuctrl_0>;
+                       #include "exynos5440-trip-points.dtsi"
+               };
+               cpu1_thermal: cpu1-thermal {
+                      thermal-sensors = <&tmuctrl_1>;
+                      #include "exynos5440-trip-points.dtsi"
+               };
+               cpu2_thermal: cpu2-thermal {
+                      thermal-sensors = <&tmuctrl_2>;
+                      #include "exynos5440-trip-points.dtsi"
+               };
        };
 
        sata@210000 {
index f1cd214..a626e6d 100644 (file)
@@ -35,6 +35,7 @@
                        regulator-max-microvolt = <5000000>;
                        gpio = <&gpio3 22 0>;
                        enable-active-high;
+                       vin-supply = <&swbst_reg>;
                };
 
                reg_usb_h1_vbus: regulator@1 {
@@ -45,6 +46,7 @@
                        regulator-max-microvolt = <5000000>;
                        gpio = <&gpio1 29 0>;
                        enable-active-high;
+                       vin-supply = <&swbst_reg>;
                };
 
                reg_audio: regulator@2 {
index fda4932..945887d 100644 (file)
@@ -52,6 +52,7 @@
                        regulator-max-microvolt = <5000000>;
                        gpio = <&gpio4 0 0>;
                        enable-active-high;
+                       vin-supply = <&swbst_reg>;
                };
 
                reg_usb_otg2_vbus: regulator@1 {
@@ -62,6 +63,7 @@
                        regulator-max-microvolt = <5000000>;
                        gpio = <&gpio4 2 0>;
                        enable-active-high;
+                       vin-supply = <&swbst_reg>;
                };
 
                reg_aud3v: regulator@2 {
index 19212ac..de8a3d4 100644 (file)
@@ -13,7 +13,7 @@
 
 core_thermal: core_thermal {
        polling-delay-passive = <250>; /* milliseconds */
-       polling-delay = <1000>; /* milliseconds */
+       polling-delay = <500>; /* milliseconds */
 
                        /* sensor       ID */
        thermal-sensors = <&bandgap     2>;
index 1b87aca..bc3090f 100644 (file)
@@ -13,7 +13,7 @@
 
 gpu_thermal: gpu_thermal {
        polling-delay-passive = <250>; /* milliseconds */
-       polling-delay = <1000>; /* milliseconds */
+       polling-delay = <500>; /* milliseconds */
 
                        /* sensor       ID */
        thermal-sensors = <&bandgap     1>;
index ddff674..4a485b6 100644 (file)
        };
 };
 
+&cpu_thermal {
+       polling-delay = <500>; /* milliseconds */
+};
+
 /include/ "omap54xx-clocks.dtsi"
index 58c2746..83b425f 100644 (file)
                ti,index-starts-at-one;
        };
 
+       dpll_core_byp_mux: dpll_core_byp_mux {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sys_clkin>, <&dpll_abe_m3x2_ck>;
+               ti,bit-shift = <23>;
+               reg = <0x012c>;
+       };
+
        dpll_core_ck: dpll_core_ck {
                #clock-cells = <0>;
                compatible = "ti,omap4-dpll-core-clock";
-               clocks = <&sys_clkin>, <&dpll_abe_m3x2_ck>;
+               clocks = <&sys_clkin>, <&dpll_core_byp_mux>;
                reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>;
        };
 
                clock-div = <1>;
        };
 
+       dpll_iva_byp_mux: dpll_iva_byp_mux {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sys_clkin>, <&iva_dpll_hs_clk_div>;
+               ti,bit-shift = <23>;
+               reg = <0x01ac>;
+       };
+
        dpll_iva_ck: dpll_iva_ck {
                #clock-cells = <0>;
                compatible = "ti,omap4-dpll-clock";
-               clocks = <&sys_clkin>, <&iva_dpll_hs_clk_div>;
+               clocks = <&sys_clkin>, <&dpll_iva_byp_mux>;
                reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>;
        };
 
        };
 };
 &cm_core_clocks {
+
+       dpll_per_byp_mux: dpll_per_byp_mux {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sys_clkin>, <&per_dpll_hs_clk_div>;
+               ti,bit-shift = <23>;
+               reg = <0x014c>;
+       };
+
        dpll_per_ck: dpll_per_ck {
                #clock-cells = <0>;
                compatible = "ti,omap4-dpll-clock";
-               clocks = <&sys_clkin>, <&per_dpll_hs_clk_div>;
+               clocks = <&sys_clkin>, <&dpll_per_byp_mux>;
                reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>;
        };
 
                ti,index-starts-at-one;
        };
 
+       dpll_usb_byp_mux: dpll_usb_byp_mux {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&sys_clkin>, <&usb_dpll_hs_clk_div>;
+               ti,bit-shift = <23>;
+               reg = <0x018c>;
+       };
+
        dpll_usb_ck: dpll_usb_ck {
                #clock-cells = <0>;
                compatible = "ti,omap4-dpll-j-type-clock";
-               clocks = <&sys_clkin>, <&usb_dpll_hs_clk_div>;
+               clocks = <&sys_clkin>, <&dpll_usb_byp_mux>;
                reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>;
        };
 
index 261311b..367af53 100644 (file)
                                atmel,watchdog-type = "hardware";
                                atmel,reset-type = "all";
                                atmel,dbg-halt;
-                               atmel,idle-halt;
                                status = "disabled";
                        };
 
                        compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
                        reg = <0x00700000 0x100000>;
                        interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>;
-                       clocks = <&usb>, <&uhphs_clk>, <&uhpck>;
+                       clocks = <&utmi>, <&uhphs_clk>, <&uhpck>;
                        clock-names = "usb_clk", "ehci_clk", "uhpck";
                        status = "disabled";
                };
index d986b41..4303874 100644 (file)
@@ -66,6 +66,7 @@
                gpio4 = &pioE;
                tcb0 = &tcb0;
                tcb1 = &tcb1;
+               i2c0 = &i2c0;
                i2c2 = &i2c2;
        };
        cpus {
                        compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
                        reg = <0x00600000 0x100000>;
                        interrupts = <46 IRQ_TYPE_LEVEL_HIGH 2>;
-                       clocks = <&usb>, <&uhphs_clk>, <&uhpck>;
+                       clocks = <&utmi>, <&uhphs_clk>, <&uhpck>;
                        clock-names = "usb_clk", "ehci_clk", "uhpck";
                        status = "disabled";
                };
 
                                        lcdck: lcdck {
                                                #clock-cells = <0>;
-                                               reg = <4>;
-                                               clocks = <&smd>;
+                                               reg = <3>;
+                                               clocks = <&mck>;
                                        };
 
                                        smdck: smdck {
                                                reg = <50>;
                                        };
 
-                                       lcd_clk: lcd_clk {
+                                       lcdc_clk: lcdc_clk {
                                                #clock-cells = <0>;
                                                reg = <51>;
                                        };
index 252c3d1..9d87609 100644 (file)
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&l4_sp_clk>;
+                       dmas = <&pdma 28>,
+                              <&pdma 29>;
+                       dma-names = "tx", "rx";
                };
 
                uart1: serial1@ffc03000 {
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        clocks = <&l4_sp_clk>;
+                       dmas = <&pdma 30>,
+                              <&pdma 31>;
+                       dma-names = "tx", "rx";
                };
 
                rst: rstmgr@ffd05000 {
index f2670f6..811e72b 100644 (file)
@@ -70,6 +70,7 @@ CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
+CONFIG_ARM_AT91_ETHER=y
 CONFIG_MACB=y
 # CONFIG_NET_VENDOR_BROADCOM is not set
 CONFIG_DM9000=y
index b7e6b6f..06075b6 100644 (file)
@@ -99,7 +99,7 @@ CONFIG_PCI_RCAR_GEN2=y
 CONFIG_PCI_RCAR_GEN2_PCIE=y
 CONFIG_PCIEPORTBUS=y
 CONFIG_SMP=y
-CONFIG_NR_CPUS=8
+CONFIG_NR_CPUS=16
 CONFIG_HIGHPTE=y
 CONFIG_CMA=y
 CONFIG_ARM_APPENDED_DTB=y
index a097cff..8e10859 100644 (file)
@@ -377,6 +377,7 @@ CONFIG_PWM_TWL=m
 CONFIG_PWM_TWL_LED=m
 CONFIG_OMAP_USB2=m
 CONFIG_TI_PIPE3=y
+CONFIG_TWL4030_USB=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
index 41d856e..510c747 100644 (file)
@@ -3,8 +3,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_IRQ_DOMAIN_DEBUG=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EMBEDDED=y
 CONFIG_SLAB=y
index 38840a8..8f6a570 100644 (file)
@@ -4,6 +4,7 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_PERF_EVENTS=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_SMP=y
+CONFIG_NR_CPUS=8
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_HIGHPTE=y
index f489fda..37fe607 100644 (file)
@@ -118,8 +118,8 @@ CONFIG_HID_ZEROPLUS=y
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_MON=y
-CONFIG_USB_ISP1760_HCD=y
 CONFIG_USB_STORAGE=y
+CONFIG_USB_ISP1760=y
 CONFIG_MMC=y
 CONFIG_MMC_ARMMMCI=y
 CONFIG_NEW_LEDS=y
index 71e5fc7..1d1800f 100644 (file)
 # define VFP_ABI_FRAME 0
 # define BSAES_ASM_EXTENDED_KEY
 # define XTS_CHAIN_TWEAK
-# define __ARM_ARCH__  7
+# define __ARM_ARCH__ __LINUX_ARM_ARCH__
+# define __ARM_MAX_ARCH__ 7
 #endif
 
 #ifdef __thumb__
 # define adrl adr
 #endif
 
-#if __ARM_ARCH__>=7
+#if __ARM_MAX_ARCH__>=7
+.arch  armv7-a
+.fpu   neon
+
 .text
 .syntax        unified         @ ARMv7-capable assembler is expected to handle this
 #ifdef __thumb2__
@@ -74,8 +78,6 @@
 .code   32
 #endif
 
-.fpu   neon
-
 .type  _bsaes_decrypt8,%function
 .align 4
 _bsaes_decrypt8:
@@ -2095,9 +2097,11 @@ bsaes_xts_decrypt:
        vld1.8  {q8}, [r0]                      @ initial tweak
        adr     r2, .Lxts_magic
 
+#ifndef        XTS_CHAIN_TWEAK
        tst     r9, #0xf                        @ if not multiple of 16
        it      ne                              @ Thumb2 thing, sanity check in ARM
        subne   r9, #0x10                       @ subtract another 16 bytes
+#endif
        subs    r9, #0x80
 
        blo     .Lxts_dec_short
index be068db..a4d3856 100644 (file)
@@ -701,14 +701,18 @@ $code.=<<___;
 # define VFP_ABI_FRAME 0
 # define BSAES_ASM_EXTENDED_KEY
 # define XTS_CHAIN_TWEAK
-# define __ARM_ARCH__  7
+# define __ARM_ARCH__ __LINUX_ARM_ARCH__
+# define __ARM_MAX_ARCH__ 7
 #endif
 
 #ifdef __thumb__
 # define adrl adr
 #endif
 
-#if __ARM_ARCH__>=7
+#if __ARM_MAX_ARCH__>=7
+.arch  armv7-a
+.fpu   neon
+
 .text
 .syntax        unified         @ ARMv7-capable assembler is expected to handle this
 #ifdef __thumb2__
@@ -717,8 +721,6 @@ $code.=<<___;
 .code   32
 #endif
 
-.fpu   neon
-
 .type  _bsaes_decrypt8,%function
 .align 4
 _bsaes_decrypt8:
@@ -2076,9 +2078,11 @@ bsaes_xts_decrypt:
        vld1.8  {@XMM[8]}, [r0]                 @ initial tweak
        adr     $magic, .Lxts_magic
 
+#ifndef        XTS_CHAIN_TWEAK
        tst     $len, #0xf                      @ if not multiple of 16
        it      ne                              @ Thumb2 thing, sanity check in ARM
        subne   $len, #0x10                     @ subtract another 16 bytes
+#endif
        subs    $len, #0x80
 
        blo     .Lxts_dec_short
index bf0fe99..4cf48c3 100644 (file)
@@ -149,29 +149,28 @@ static inline bool kvm_s2pmd_readonly(pmd_t *pmd)
        (__boundary - 1 < (end) - 1)? __boundary: (end);                \
 })
 
+#define kvm_pgd_index(addr)                    pgd_index(addr)
+
 static inline bool kvm_page_empty(void *ptr)
 {
        struct page *ptr_page = virt_to_page(ptr);
        return page_count(ptr_page) == 1;
 }
 
-
 #define kvm_pte_table_empty(kvm, ptep) kvm_page_empty(ptep)
 #define kvm_pmd_table_empty(kvm, pmdp) kvm_page_empty(pmdp)
 #define kvm_pud_table_empty(kvm, pudp) (0)
 
 #define KVM_PREALLOC_LEVEL     0
 
-static inline int kvm_prealloc_hwpgd(struct kvm *kvm, pgd_t *pgd)
+static inline void *kvm_get_hwpgd(struct kvm *kvm)
 {
-       return 0;
+       return kvm->arch.pgd;
 }
 
-static inline void kvm_free_hwpgd(struct kvm *kvm) { }
-
-static inline void *kvm_get_hwpgd(struct kvm *kvm)
+static inline unsigned int kvm_get_hwpgd_size(void)
 {
-       return kvm->arch.pgd;
+       return PTRS_PER_S2_PGD * sizeof(pgd_t);
 }
 
 struct kvm;
index 80a6501..c3c45e6 100644 (file)
 #define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */
 #endif
 
-/* Keep in sync with mach-at91/include/mach/hardware.h */
+#ifdef CONFIG_MMU
 #define AT91_IO_P2V(x) ((x) - 0x01000000)
+#else
+#define AT91_IO_P2V(x) (x)
+#endif
 
 #define AT91_DBGU_SR           (0x14)  /* Status Register */
 #define AT91_DBGU_THR          (0x1c)  /* Transmitter Holding Register */
index 3e6859b..5656d79 100644 (file)
@@ -290,7 +290,7 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp,
        phys_addr_t addr = start, end = start + size;
        phys_addr_t next;
 
-       pgd = pgdp + pgd_index(addr);
+       pgd = pgdp + kvm_pgd_index(addr);
        do {
                next = kvm_pgd_addr_end(addr, end);
                if (!pgd_none(*pgd))
@@ -355,7 +355,7 @@ static void stage2_flush_memslot(struct kvm *kvm,
        phys_addr_t next;
        pgd_t *pgd;
 
-       pgd = kvm->arch.pgd + pgd_index(addr);
+       pgd = kvm->arch.pgd + kvm_pgd_index(addr);
        do {
                next = kvm_pgd_addr_end(addr, end);
                stage2_flush_puds(kvm, pgd, addr, next);
@@ -632,6 +632,20 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t phys_addr)
                                     __phys_to_pfn(phys_addr), PAGE_HYP_DEVICE);
 }
 
+/* Free the HW pgd, one page at a time */
+static void kvm_free_hwpgd(void *hwpgd)
+{
+       free_pages_exact(hwpgd, kvm_get_hwpgd_size());
+}
+
+/* Allocate the HW PGD, making sure that each page gets its own refcount */
+static void *kvm_alloc_hwpgd(void)
+{
+       unsigned int size = kvm_get_hwpgd_size();
+
+       return alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
+}
+
 /**
  * kvm_alloc_stage2_pgd - allocate level-1 table for stage-2 translation.
  * @kvm:       The KVM struct pointer for the VM.
@@ -645,15 +659,31 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t phys_addr)
  */
 int kvm_alloc_stage2_pgd(struct kvm *kvm)
 {
-       int ret;
        pgd_t *pgd;
+       void *hwpgd;
 
        if (kvm->arch.pgd != NULL) {
                kvm_err("kvm_arch already initialized?\n");
                return -EINVAL;
        }
 
+       hwpgd = kvm_alloc_hwpgd();
+       if (!hwpgd)
+               return -ENOMEM;
+
+       /* When the kernel uses more levels of page tables than the
+        * guest, we allocate a fake PGD and pre-populate it to point
+        * to the next-level page table, which will be the real
+        * initial page table pointed to by the VTTBR.
+        *
+        * When KVM_PREALLOC_LEVEL==2, we allocate a single page for
+        * the PMD and the kernel will use folded pud.
+        * When KVM_PREALLOC_LEVEL==1, we allocate 2 consecutive PUD
+        * pages.
+        */
        if (KVM_PREALLOC_LEVEL > 0) {
+               int i;
+
                /*
                 * Allocate fake pgd for the page table manipulation macros to
                 * work.  This is not used by the hardware and we have no
@@ -661,30 +691,32 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm)
                 */
                pgd = (pgd_t *)kmalloc(PTRS_PER_S2_PGD * sizeof(pgd_t),
                                       GFP_KERNEL | __GFP_ZERO);
+
+               if (!pgd) {
+                       kvm_free_hwpgd(hwpgd);
+                       return -ENOMEM;
+               }
+
+               /* Plug the HW PGD into the fake one. */
+               for (i = 0; i < PTRS_PER_S2_PGD; i++) {
+                       if (KVM_PREALLOC_LEVEL == 1)
+                               pgd_populate(NULL, pgd + i,
+                                            (pud_t *)hwpgd + i * PTRS_PER_PUD);
+                       else if (KVM_PREALLOC_LEVEL == 2)
+                               pud_populate(NULL, pud_offset(pgd, 0) + i,
+                                            (pmd_t *)hwpgd + i * PTRS_PER_PMD);
+               }
        } else {
                /*
                 * Allocate actual first-level Stage-2 page table used by the
                 * hardware for Stage-2 page table walks.
                 */
-               pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, S2_PGD_ORDER);
+               pgd = (pgd_t *)hwpgd;
        }
 
-       if (!pgd)
-               return -ENOMEM;
-
-       ret = kvm_prealloc_hwpgd(kvm, pgd);
-       if (ret)
-               goto out_err;
-
        kvm_clean_pgd(pgd);
        kvm->arch.pgd = pgd;
        return 0;
-out_err:
-       if (KVM_PREALLOC_LEVEL > 0)
-               kfree(pgd);
-       else
-               free_pages((unsigned long)pgd, S2_PGD_ORDER);
-       return ret;
 }
 
 /**
@@ -785,11 +817,10 @@ void kvm_free_stage2_pgd(struct kvm *kvm)
                return;
 
        unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE);
-       kvm_free_hwpgd(kvm);
+       kvm_free_hwpgd(kvm_get_hwpgd(kvm));
        if (KVM_PREALLOC_LEVEL > 0)
                kfree(kvm->arch.pgd);
-       else
-               free_pages((unsigned long)kvm->arch.pgd, S2_PGD_ORDER);
+
        kvm->arch.pgd = NULL;
 }
 
@@ -799,7 +830,7 @@ static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache
        pgd_t *pgd;
        pud_t *pud;
 
-       pgd = kvm->arch.pgd + pgd_index(addr);
+       pgd = kvm->arch.pgd + kvm_pgd_index(addr);
        if (WARN_ON(pgd_none(*pgd))) {
                if (!cache)
                        return NULL;
@@ -1089,7 +1120,7 @@ static void stage2_wp_range(struct kvm *kvm, phys_addr_t addr, phys_addr_t end)
        pgd_t *pgd;
        phys_addr_t next;
 
-       pgd = kvm->arch.pgd + pgd_index(addr);
+       pgd = kvm->arch.pgd + kvm_pgd_index(addr);
        do {
                /*
                 * Release kvm_mmu_lock periodically if the memory region is
index 5e34fb1..aa4116e 100644 (file)
@@ -270,37 +270,35 @@ static void __init at91_pm_sram_init(void)
        phys_addr_t sram_pbase;
        unsigned long sram_base;
        struct device_node *node;
-       struct platform_device *pdev;
+       struct platform_device *pdev = NULL;
 
-       node = of_find_compatible_node(NULL, NULL, "mmio-sram");
-       if (!node) {
-               pr_warn("%s: failed to find sram node!\n", __func__);
-               return;
+       for_each_compatible_node(node, NULL, "mmio-sram") {
+               pdev = of_find_device_by_node(node);
+               if (pdev) {
+                       of_node_put(node);
+                       break;
+               }
        }
 
-       pdev = of_find_device_by_node(node);
        if (!pdev) {
                pr_warn("%s: failed to find sram device!\n", __func__);
-               goto put_node;
+               return;
        }
 
        sram_pool = dev_get_gen_pool(&pdev->dev);
        if (!sram_pool) {
                pr_warn("%s: sram pool unavailable!\n", __func__);
-               goto put_node;
+               return;
        }
 
        sram_base = gen_pool_alloc(sram_pool, at91_slow_clock_sz);
        if (!sram_base) {
                pr_warn("%s: unable to alloc ocram!\n", __func__);
-               goto put_node;
+               return;
        }
 
        sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base);
        slow_clock = __arm_ioremap_exec(sram_pbase, at91_slow_clock_sz, false);
-
-put_node:
-       of_node_put(node);
 }
 #endif
 
index d2c8996..86c0aa8 100644 (file)
@@ -44,7 +44,7 @@ static inline void at91rm9200_standby(void)
                "    mcr    p15, 0, %0, c7, c0, 4\n\t"
                "    str    %5, [%1, %2]"
                :
-               : "r" (0), "r" (AT91_BASE_SYS), "r" (AT91RM9200_SDRAMC_LPR),
+               : "r" (0), "r" (at91_ramc_base[0]), "r" (AT91RM9200_SDRAMC_LPR),
                  "r" (1), "r" (AT91RM9200_SDRAMC_SRR),
                  "r" (lpr));
 }
index 556151e..931f0e3 100644 (file)
  */
 #undef SLOWDOWN_MASTER_CLOCK
 
-#define MCKRDY_TIMEOUT         1000
-#define MOSCRDY_TIMEOUT        1000
-#define PLLALOCK_TIMEOUT       1000
-#define PLLBLOCK_TIMEOUT       1000
-
 pmc    .req    r0
 sdramc .req    r1
 ramc1  .req    r2
@@ -41,60 +36,42 @@ tmp2        .req    r5
  * Wait until master clock is ready (after switching master clock source)
  */
        .macro wait_mckrdy
-       mov     tmp2, #MCKRDY_TIMEOUT
-1:     sub     tmp2, tmp2, #1
-       cmp     tmp2, #0
-       beq     2f
-       ldr     tmp1, [pmc, #AT91_PMC_SR]
+1:     ldr     tmp1, [pmc, #AT91_PMC_SR]
        tst     tmp1, #AT91_PMC_MCKRDY
        beq     1b
-2:
        .endm
 
 /*
  * Wait until master oscillator has stabilized.
  */
        .macro wait_moscrdy
-       mov     tmp2, #MOSCRDY_TIMEOUT
-1:     sub     tmp2, tmp2, #1
-       cmp     tmp2, #0
-       beq     2f
-       ldr     tmp1, [pmc, #AT91_PMC_SR]
+1:     ldr     tmp1, [pmc, #AT91_PMC_SR]
        tst     tmp1, #AT91_PMC_MOSCS
        beq     1b
-2:
        .endm
 
 /*
  * Wait until PLLA has locked.
  */
        .macro wait_pllalock
-       mov     tmp2, #PLLALOCK_TIMEOUT
-1:     sub     tmp2, tmp2, #1
-       cmp     tmp2, #0
-       beq     2f
-       ldr     tmp1, [pmc, #AT91_PMC_SR]
+1:     ldr     tmp1, [pmc, #AT91_PMC_SR]
        tst     tmp1, #AT91_PMC_LOCKA
        beq     1b
-2:
        .endm
 
 /*
  * Wait until PLLB has locked.
  */
        .macro wait_pllblock
-       mov     tmp2, #PLLBLOCK_TIMEOUT
-1:     sub     tmp2, tmp2, #1
-       cmp     tmp2, #0
-       beq     2f
-       ldr     tmp1, [pmc, #AT91_PMC_SR]
+1:     ldr     tmp1, [pmc, #AT91_PMC_SR]
        tst     tmp1, #AT91_PMC_LOCKB
        beq     1b
-2:
        .endm
 
        .text
 
+       .arm
+
 /* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
  *                     void __iomem *ramc1, int memctrl)
  */
@@ -134,6 +111,16 @@ ddr_sr_enable:
        cmp     memctrl, #AT91_MEMCTRL_DDRSDR
        bne     sdr_sr_enable
 
+       /* LPDDR1 --> force DDR2 mode during self-refresh */
+       ldr     tmp1, [sdramc, #AT91_DDRSDRC_MDR]
+       str     tmp1, .saved_sam9_mdr
+       bic     tmp1, tmp1, #~AT91_DDRSDRC_MD
+       cmp     tmp1, #AT91_DDRSDRC_MD_LOW_POWER_DDR
+       ldreq   tmp1, [sdramc, #AT91_DDRSDRC_MDR]
+       biceq   tmp1, tmp1, #AT91_DDRSDRC_MD
+       orreq   tmp1, tmp1, #AT91_DDRSDRC_MD_DDR2
+       streq   tmp1, [sdramc, #AT91_DDRSDRC_MDR]
+
        /* prepare for DDRAM self-refresh mode */
        ldr     tmp1, [sdramc, #AT91_DDRSDRC_LPR]
        str     tmp1, .saved_sam9_lpr
@@ -142,14 +129,26 @@ ddr_sr_enable:
 
        /* figure out if we use the second ram controller */
        cmp     ramc1, #0
-       ldrne   tmp2, [ramc1, #AT91_DDRSDRC_LPR]
-       strne   tmp2, .saved_sam9_lpr1
-       bicne   tmp2, #AT91_DDRSDRC_LPCB
-       orrne   tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+       beq     ddr_no_2nd_ctrl
+
+       ldr     tmp2, [ramc1, #AT91_DDRSDRC_MDR]
+       str     tmp2, .saved_sam9_mdr1
+       bic     tmp2, tmp2, #~AT91_DDRSDRC_MD
+       cmp     tmp2, #AT91_DDRSDRC_MD_LOW_POWER_DDR
+       ldreq   tmp2, [ramc1, #AT91_DDRSDRC_MDR]
+       biceq   tmp2, tmp2, #AT91_DDRSDRC_MD
+       orreq   tmp2, tmp2, #AT91_DDRSDRC_MD_DDR2
+       streq   tmp2, [ramc1, #AT91_DDRSDRC_MDR]
+
+       ldr     tmp2, [ramc1, #AT91_DDRSDRC_LPR]
+       str     tmp2, .saved_sam9_lpr1
+       bic     tmp2, #AT91_DDRSDRC_LPCB
+       orr     tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
 
        /* Enable DDRAM self-refresh mode */
+       str     tmp2, [ramc1, #AT91_DDRSDRC_LPR]
+ddr_no_2nd_ctrl:
        str     tmp1, [sdramc, #AT91_DDRSDRC_LPR]
-       strne   tmp2, [ramc1, #AT91_DDRSDRC_LPR]
 
        b       sdr_sr_done
 
@@ -208,6 +207,7 @@ sdr_sr_done:
        /* Turn off the main oscillator */
        ldr     tmp1, [pmc, #AT91_CKGR_MOR]
        bic     tmp1, tmp1, #AT91_PMC_MOSCEN
+       orr     tmp1, tmp1, #AT91_PMC_KEY
        str     tmp1, [pmc, #AT91_CKGR_MOR]
 
        /* Wait for interrupt */
@@ -216,6 +216,7 @@ sdr_sr_done:
        /* Turn on the main oscillator */
        ldr     tmp1, [pmc, #AT91_CKGR_MOR]
        orr     tmp1, tmp1, #AT91_PMC_MOSCEN
+       orr     tmp1, tmp1, #AT91_PMC_KEY
        str     tmp1, [pmc, #AT91_CKGR_MOR]
 
        wait_moscrdy
@@ -280,12 +281,17 @@ sdr_sr_done:
         */
        cmp     memctrl, #AT91_MEMCTRL_DDRSDR
        bne     sdr_en_restore
+       /* Restore MDR in case of LPDDR1 */
+       ldr     tmp1, .saved_sam9_mdr
+       str     tmp1, [sdramc, #AT91_DDRSDRC_MDR]
        /* Restore LPR on AT91 with DDRAM */
        ldr     tmp1, .saved_sam9_lpr
        str     tmp1, [sdramc, #AT91_DDRSDRC_LPR]
 
        /* if we use the second ram controller */
        cmp     ramc1, #0
+       ldrne   tmp2, .saved_sam9_mdr1
+       strne   tmp2, [ramc1, #AT91_DDRSDRC_MDR]
        ldrne   tmp2, .saved_sam9_lpr1
        strne   tmp2, [ramc1, #AT91_DDRSDRC_LPR]
 
@@ -319,5 +325,11 @@ ram_restored:
 .saved_sam9_lpr1:
        .word 0
 
+.saved_sam9_mdr:
+       .word 0
+
+.saved_sam9_mdr1:
+       .word 0
+
 ENTRY(at91_slow_clock_sz)
        .word .-at91_slow_clock
index 3f32c47..d2e9f12 100644 (file)
@@ -126,8 +126,7 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
  */
 void exynos_cpu_power_down(int cpu)
 {
-       if (cpu == 0 && (of_machine_is_compatible("samsung,exynos5420") ||
-               of_machine_is_compatible("samsung,exynos5800"))) {
+       if (cpu == 0 && (soc_is_exynos5420() || soc_is_exynos5800())) {
                /*
                 * Bypass power down for CPU0 during suspend. Check for
                 * the SYS_PWR_REG value to decide if we are suspending
index 20f2671..37266a8 100644 (file)
@@ -161,6 +161,34 @@ no_clk:
                of_genpd_add_provider_simple(np, &pd->pd);
        }
 
+       /* Assign the child power domains to their parents */
+       for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
+               struct generic_pm_domain *child_domain, *parent_domain;
+               struct of_phandle_args args;
+
+               args.np = np;
+               args.args_count = 0;
+               child_domain = of_genpd_get_from_provider(&args);
+               if (!child_domain)
+                       continue;
+
+               if (of_parse_phandle_with_args(np, "power-domains",
+                                        "#power-domain-cells", 0, &args) != 0)
+                       continue;
+
+               parent_domain = of_genpd_get_from_provider(&args);
+               if (!parent_domain)
+                       continue;
+
+               if (pm_genpd_add_subdomain(parent_domain, child_domain))
+                       pr_warn("%s failed to add subdomain: %s\n",
+                               parent_domain->name, child_domain->name);
+               else
+                       pr_info("%s has as child subdomain: %s.\n",
+                               parent_domain->name, child_domain->name);
+               of_node_put(np);
+       }
+
        return 0;
 }
 arch_initcall(exynos4_pm_init_power_domain);
index 52e2b1a..318d127 100644 (file)
@@ -87,8 +87,8 @@ static unsigned int exynos_pmu_spare3;
 static u32 exynos_irqwake_intmask = 0xffffffff;
 
 static const struct exynos_wkup_irq exynos3250_wkup_irq[] = {
-       { 73, BIT(1) }, /* RTC alarm */
-       { 74, BIT(2) }, /* RTC tick */
+       { 105, BIT(1) }, /* RTC alarm */
+       { 106, BIT(2) }, /* RTC tick */
        { /* sentinel */ },
 };
 
index 4ad6e47..9de3412 100644 (file)
@@ -211,8 +211,9 @@ static void __init imx6q_1588_init(void)
         * set bit IOMUXC_GPR1[21].  Or the PTP clock must be from pad
         * (external OSC), and we need to clear the bit.
         */
-       clksel = ptp_clk == enet_ref ? IMX6Q_GPR1_ENET_CLK_SEL_ANATOP :
-                                      IMX6Q_GPR1_ENET_CLK_SEL_PAD;
+       clksel = clk_is_match(ptp_clk, enet_ref) ?
+                               IMX6Q_GPR1_ENET_CLK_SEL_ANATOP :
+                               IMX6Q_GPR1_ENET_CLK_SEL_PAD;
        gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
        if (!IS_ERR(gpr))
                regmap_update_bits(gpr, IOMUXC_GPR1,
index 92afb72..355b089 100644 (file)
@@ -1692,16 +1692,15 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
        if (ret == -EBUSY)
                pr_warn("omap_hwmod: %s: failed to hardreset\n", oh->name);
 
-       if (!ret) {
+       if (oh->clkdm) {
                /*
                 * Set the clockdomain to HW_AUTO, assuming that the
                 * previous state was HW_AUTO.
                 */
-               if (oh->clkdm && hwsup)
+               if (hwsup)
                        clkdm_allow_idle(oh->clkdm);
-       } else {
-               if (oh->clkdm)
-                       clkdm_hwmod_disable(oh->clkdm, oh);
+
+               clkdm_hwmod_disable(oh->clkdm, oh);
        }
 
        return ret;
@@ -2698,6 +2697,7 @@ static int __init _register(struct omap_hwmod *oh)
        INIT_LIST_HEAD(&oh->master_ports);
        INIT_LIST_HEAD(&oh->slave_ports);
        spin_lock_init(&oh->_lock);
+       lockdep_set_class(&oh->_lock, &oh->hwmod_key);
 
        oh->_state = _HWMOD_STATE_REGISTERED;
 
index 9d4bec6..9611c91 100644 (file)
@@ -674,6 +674,7 @@ struct omap_hwmod {
        u32                             _sysc_cache;
        void __iomem                    *_mpu_rt_va;
        spinlock_t                      _lock;
+       struct lock_class_key           hwmod_key; /* unique lock class */
        struct list_head                node;
        struct omap_hwmod_ocp_if        *_mpu_port;
        unsigned int                    (*xlate_irq)(unsigned int);
index e8692e7..16fe7a1 100644 (file)
@@ -1466,55 +1466,18 @@ static struct omap_hwmod dra7xx_ocp2scp3_hwmod = {
  *
  */
 
-static struct omap_hwmod_class dra7xx_pcie_hwmod_class = {
+static struct omap_hwmod_class dra7xx_pciess_hwmod_class = {
        .name   = "pcie",
 };
 
 /* pcie1 */
-static struct omap_hwmod dra7xx_pcie1_hwmod = {
+static struct omap_hwmod dra7xx_pciess1_hwmod = {
        .name           = "pcie1",
-       .class          = &dra7xx_pcie_hwmod_class,
+       .class          = &dra7xx_pciess_hwmod_class,
        .clkdm_name     = "pcie_clkdm",
        .main_clk       = "l4_root_clk_div",
        .prcm = {
                .omap4 = {
-                       .clkctrl_offs   = DRA7XX_CM_PCIE_CLKSTCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* pcie2 */
-static struct omap_hwmod dra7xx_pcie2_hwmod = {
-       .name           = "pcie2",
-       .class          = &dra7xx_pcie_hwmod_class,
-       .clkdm_name     = "pcie_clkdm",
-       .main_clk       = "l4_root_clk_div",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_PCIE_CLKSTCTRL_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'PCIE PHY' class
- *
- */
-
-static struct omap_hwmod_class dra7xx_pcie_phy_hwmod_class = {
-       .name   = "pcie-phy",
-};
-
-/* pcie1 phy */
-static struct omap_hwmod dra7xx_pcie1_phy_hwmod = {
-       .name           = "pcie1-phy",
-       .class          = &dra7xx_pcie_phy_hwmod_class,
-       .clkdm_name     = "l3init_clkdm",
-       .main_clk       = "l4_root_clk_div",
-       .prcm = {
-               .omap4 = {
                        .clkctrl_offs = DRA7XX_CM_L3INIT_PCIESS1_CLKCTRL_OFFSET,
                        .context_offs = DRA7XX_RM_L3INIT_PCIESS1_CONTEXT_OFFSET,
                        .modulemode   = MODULEMODE_SWCTRL,
@@ -1522,11 +1485,11 @@ static struct omap_hwmod dra7xx_pcie1_phy_hwmod = {
        },
 };
 
-/* pcie2 phy */
-static struct omap_hwmod dra7xx_pcie2_phy_hwmod = {
-       .name           = "pcie2-phy",
-       .class          = &dra7xx_pcie_phy_hwmod_class,
-       .clkdm_name     = "l3init_clkdm",
+/* pcie2 */
+static struct omap_hwmod dra7xx_pciess2_hwmod = {
+       .name           = "pcie2",
+       .class          = &dra7xx_pciess_hwmod_class,
+       .clkdm_name     = "pcie_clkdm",
        .main_clk       = "l4_root_clk_div",
        .prcm = {
                .omap4 = {
@@ -2877,50 +2840,34 @@ static struct omap_hwmod_ocp_if dra7xx_l4_cfg__ocp2scp3 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l3_main_1 -> pcie1 */
-static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pcie1 = {
+/* l3_main_1 -> pciess1 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pciess1 = {
        .master         = &dra7xx_l3_main_1_hwmod,
-       .slave          = &dra7xx_pcie1_hwmod,
+       .slave          = &dra7xx_pciess1_hwmod,
        .clk            = "l3_iclk_div",
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_cfg -> pcie1 */
-static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pcie1 = {
+/* l4_cfg -> pciess1 */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pciess1 = {
        .master         = &dra7xx_l4_cfg_hwmod,
-       .slave          = &dra7xx_pcie1_hwmod,
+       .slave          = &dra7xx_pciess1_hwmod,
        .clk            = "l4_root_clk_div",
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l3_main_1 -> pcie2 */
-static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pcie2 = {
+/* l3_main_1 -> pciess2 */
+static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pciess2 = {
        .master         = &dra7xx_l3_main_1_hwmod,
-       .slave          = &dra7xx_pcie2_hwmod,
+       .slave          = &dra7xx_pciess2_hwmod,
        .clk            = "l3_iclk_div",
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_cfg -> pcie2 */
-static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pcie2 = {
-       .master         = &dra7xx_l4_cfg_hwmod,
-       .slave          = &dra7xx_pcie2_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> pcie1 phy */
-static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pcie1_phy = {
-       .master         = &dra7xx_l4_cfg_hwmod,
-       .slave          = &dra7xx_pcie1_phy_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> pcie2 phy */
-static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pcie2_phy = {
+/* l4_cfg -> pciess2 */
+static struct omap_hwmod_ocp_if dra7xx_l4_cfg__pciess2 = {
        .master         = &dra7xx_l4_cfg_hwmod,
-       .slave          = &dra7xx_pcie2_phy_hwmod,
+       .slave          = &dra7xx_pciess2_hwmod,
        .clk            = "l4_root_clk_div",
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
@@ -3327,12 +3274,10 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
        &dra7xx_l4_cfg__mpu,
        &dra7xx_l4_cfg__ocp2scp1,
        &dra7xx_l4_cfg__ocp2scp3,
-       &dra7xx_l3_main_1__pcie1,
-       &dra7xx_l4_cfg__pcie1,
-       &dra7xx_l3_main_1__pcie2,
-       &dra7xx_l4_cfg__pcie2,
-       &dra7xx_l4_cfg__pcie1_phy,
-       &dra7xx_l4_cfg__pcie2_phy,
+       &dra7xx_l3_main_1__pciess1,
+       &dra7xx_l4_cfg__pciess1,
+       &dra7xx_l3_main_1__pciess2,
+       &dra7xx_l4_cfg__pciess2,
        &dra7xx_l3_main_1__qspi,
        &dra7xx_l4_per3__rtcss,
        &dra7xx_l4_cfg__sata,
index 190fa43..e642b07 100644 (file)
@@ -173,6 +173,7 @@ static void __init omap3_igep0030_rev_g_legacy_init(void)
 
 static void __init omap3_evm_legacy_init(void)
 {
+       hsmmc2_internal_input_clk();
        legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 149);
 }
 
index a08a617..d6d6bc3 100644 (file)
@@ -252,10 +252,10 @@ static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask)
 {
        saved_mask[0] =
                omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
-                                       OMAP4_PRM_IRQSTATUS_MPU_OFFSET);
+                                       OMAP4_PRM_IRQENABLE_MPU_OFFSET);
        saved_mask[1] =
                omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
-                                       OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET);
+                                       OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
 
        omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST,
                                 OMAP4_PRM_IRQENABLE_MPU_OFFSET);
index 483cb46..a0f3b1c 100644 (file)
@@ -45,6 +45,6 @@ extern char secondary_trampoline, secondary_trampoline_end;
 
 extern unsigned long socfpga_cpu1start_addr;
 
-#define SOCFPGA_SCU_VIRT_BASE   0xfffec000
+#define SOCFPGA_SCU_VIRT_BASE   0xfee00000
 
 #endif
index 383d61e..f5e597c 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <asm/cacheflush.h>
 
 #include "core.h"
 
@@ -73,6 +74,10 @@ void __init socfpga_sysmgr_init(void)
                        (u32 *) &socfpga_cpu1start_addr))
                pr_err("SMP: Need cpu1-start-addr in device tree.\n");
 
+       /* Ensure that socfpga_cpu1start_addr is visible to other CPUs */
+       smp_wmb();
+       sync_cache_w(&socfpga_cpu1start_addr);
+
        sys_manager_base_addr = of_iomap(np, 0);
 
        np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr");
index b067390..b373aca 100644 (file)
@@ -18,6 +18,7 @@ static const char *stih41x_dt_match[] __initdata = {
        "st,stih415",
        "st,stih416",
        "st,stih407",
+       "st,stih410",
        "st,stih418",
        NULL
 };
index 94674eb..54bb4ba 100644 (file)
  * 40 bits wide (T0SZ = 24).  Systems with a PARange smaller than 40 bits are
  * not known to exist and will break with this configuration.
  *
+ * VTCR_EL2.PS is extracted from ID_AA64MMFR0_EL1.PARange at boot time
+ * (see hyp-init.S).
+ *
  * Note that when using 4K pages, we concatenate two first level page tables
  * together.
  *
 #ifdef CONFIG_ARM64_64K_PAGES
 /*
  * Stage2 translation configuration:
- * 40bits output (PS = 2)
  * 40bits input  (T0SZ = 24)
  * 64kB pages (TG0 = 1)
  * 2 level page tables (SL = 1)
 #else
 /*
  * Stage2 translation configuration:
- * 40bits output (PS = 2)
  * 40bits input  (T0SZ = 24)
  * 4kB pages (TG0 = 0)
  * 3 level page tables (SL = 1)
index 6458b53..bbfb600 100644 (file)
@@ -158,6 +158,8 @@ static inline bool kvm_s2pmd_readonly(pmd_t *pmd)
 #define PTRS_PER_S2_PGD                (1 << PTRS_PER_S2_PGD_SHIFT)
 #define S2_PGD_ORDER           get_order(PTRS_PER_S2_PGD * sizeof(pgd_t))
 
+#define kvm_pgd_index(addr)    (((addr) >> PGDIR_SHIFT) & (PTRS_PER_S2_PGD - 1))
+
 /*
  * If we are concatenating first level stage-2 page tables, we would have less
  * than or equal to 16 pointers in the fake PGD, because that's what the
@@ -171,43 +173,6 @@ static inline bool kvm_s2pmd_readonly(pmd_t *pmd)
 #define KVM_PREALLOC_LEVEL     (0)
 #endif
 
-/**
- * kvm_prealloc_hwpgd - allocate inital table for VTTBR
- * @kvm:       The KVM struct pointer for the VM.
- * @pgd:       The kernel pseudo pgd
- *
- * When the kernel uses more levels of page tables than the guest, we allocate
- * a fake PGD and pre-populate it to point to the next-level page table, which
- * will be the real initial page table pointed to by the VTTBR.
- *
- * When KVM_PREALLOC_LEVEL==2, we allocate a single page for the PMD and
- * the kernel will use folded pud.  When KVM_PREALLOC_LEVEL==1, we
- * allocate 2 consecutive PUD pages.
- */
-static inline int kvm_prealloc_hwpgd(struct kvm *kvm, pgd_t *pgd)
-{
-       unsigned int i;
-       unsigned long hwpgd;
-
-       if (KVM_PREALLOC_LEVEL == 0)
-               return 0;
-
-       hwpgd = __get_free_pages(GFP_KERNEL | __GFP_ZERO, PTRS_PER_S2_PGD_SHIFT);
-       if (!hwpgd)
-               return -ENOMEM;
-
-       for (i = 0; i < PTRS_PER_S2_PGD; i++) {
-               if (KVM_PREALLOC_LEVEL == 1)
-                       pgd_populate(NULL, pgd + i,
-                                    (pud_t *)hwpgd + i * PTRS_PER_PUD);
-               else if (KVM_PREALLOC_LEVEL == 2)
-                       pud_populate(NULL, pud_offset(pgd, 0) + i,
-                                    (pmd_t *)hwpgd + i * PTRS_PER_PMD);
-       }
-
-       return 0;
-}
-
 static inline void *kvm_get_hwpgd(struct kvm *kvm)
 {
        pgd_t *pgd = kvm->arch.pgd;
@@ -224,12 +189,11 @@ static inline void *kvm_get_hwpgd(struct kvm *kvm)
        return pmd_offset(pud, 0);
 }
 
-static inline void kvm_free_hwpgd(struct kvm *kvm)
+static inline unsigned int kvm_get_hwpgd_size(void)
 {
-       if (KVM_PREALLOC_LEVEL > 0) {
-               unsigned long hwpgd = (unsigned long)kvm_get_hwpgd(kvm);
-               free_pages(hwpgd, PTRS_PER_S2_PGD_SHIFT);
-       }
+       if (KVM_PREALLOC_LEVEL > 0)
+               return PTRS_PER_S2_PGD * PAGE_SIZE;
+       return PTRS_PER_S2_PGD * sizeof(pgd_t);
 }
 
 static inline bool kvm_page_empty(void *ptr)
index c028fe3..53d9c35 100644 (file)
@@ -48,6 +48,7 @@ static inline void tlb_flush(struct mmu_gather *tlb)
 static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
                                  unsigned long addr)
 {
+       __flush_tlb_pgtable(tlb->mm, addr);
        pgtable_page_dtor(pte);
        tlb_remove_entry(tlb, pte);
 }
@@ -56,6 +57,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
 static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
                                  unsigned long addr)
 {
+       __flush_tlb_pgtable(tlb->mm, addr);
        tlb_remove_entry(tlb, virt_to_page(pmdp));
 }
 #endif
@@ -64,6 +66,7 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
 static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp,
                                  unsigned long addr)
 {
+       __flush_tlb_pgtable(tlb->mm, addr);
        tlb_remove_entry(tlb, virt_to_page(pudp));
 }
 #endif
index 4abe9b9..c3bb05b 100644 (file)
@@ -144,6 +144,19 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
 }
 
 /*
+ * Used to invalidate the TLB (walk caches) corresponding to intermediate page
+ * table levels (pgd/pud/pmd).
+ */
+static inline void __flush_tlb_pgtable(struct mm_struct *mm,
+                                      unsigned long uaddr)
+{
+       unsigned long addr = uaddr >> 12 | ((unsigned long)ASID(mm) << 48);
+
+       dsb(ishst);
+       asm("tlbi       vae1is, %0" : : "r" (addr));
+       dsb(ish);
+}
+/*
  * On AArch64, the cache coherency is handled via the set_pte_at() function.
  */
 static inline void update_mmu_cache(struct vm_area_struct *vma,
index b42c7b4..2b8d701 100644 (file)
@@ -354,3 +354,12 @@ void efi_virtmap_unload(void)
        efi_set_pgd(current->active_mm);
        preempt_enable();
 }
+
+/*
+ * UpdateCapsule() depends on the system being shutdown via
+ * ResetSystem().
+ */
+bool efi_poweroff_required(void)
+{
+       return efi_enabled(EFI_RUNTIME_SERVICES);
+}
index 8ce88e0..07f9305 100644 (file)
@@ -585,8 +585,8 @@ ENDPROC(set_cpu_boot_mode_flag)
  * zeroing of .bss would clobber it.
  */
        .pushsection    .data..cacheline_aligned
-ENTRY(__boot_cpu_mode)
        .align  L1_CACHE_SHIFT
+ENTRY(__boot_cpu_mode)
        .long   BOOT_CPU_MODE_EL2
        .long   0
        .popsection
index fde9923..c6b1f3b 100644 (file)
@@ -21,6 +21,7 @@
 #include <stdarg.h>
 
 #include <linux/compat.h>
+#include <linux/efi.h>
 #include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -150,6 +151,13 @@ void machine_restart(char *cmd)
        local_irq_disable();
        smp_send_stop();
 
+       /*
+        * UpdateCapsule() depends on the system being reset via
+        * ResetSystem().
+        */
+       if (efi_enabled(EFI_RUNTIME_SERVICES))
+               efi_reboot(reboot_mode, NULL);
+
        /* Now call the architecture specific reboot code. */
        if (arm_pm_restart)
                arm_pm_restart(reboot_mode, cmd);
index 78d4483..ec4db6d 100644 (file)
@@ -67,6 +67,11 @@ extern unsigned long empty_zero_page;
  */
 #define pgtable_cache_init()   do { } while (0)
 
+/*
+ * c6x is !MMU, so define the simpliest implementation
+ */
+#define pgprot_writecombine pgprot_noncached
+
 #include <asm-generic/pgtable.h>
 
 #endif /* _ASM_C6X_PGTABLE_H */
index 0536bc0..ef54851 100644 (file)
@@ -348,8 +348,9 @@ C_ENTRY(_user_exception):
  * The LP register should point to the location where the called function
  * should return.  [note that MAKE_SYS_CALL uses label 1] */
        /* See if the system call number is valid */
+       blti    r12, 5f
        addi    r11, r12, -__NR_syscalls;
-       bgei    r11,5f;
+       bgei    r11, 5f;
        /* Figure out which function to use for this system call.  */
        /* Note Microblaze barrel shift is optional, so don't rely on it */
        add     r12, r12, r12;                  /* convert num -> ptr */
@@ -375,7 +376,7 @@ C_ENTRY(_user_exception):
 
        /* The syscall number is invalid, return an error.  */
 5:
-       rtsd    r15, 8;         /* looks like a normal subroutine return */
+       braid   ret_from_trap
        addi    r3, r0, -ENOSYS;
 
 /* Entry point used to return from a syscall/trap */
@@ -411,7 +412,7 @@ C_ENTRY(ret_from_trap):
        bri     1b
 
        /* Maybe handle a signal */
-5:     
+5:
        andi    r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
        beqi    r11, 4f;                /* Signals to handle, handle them */
 
index 20fb1cf..6424621 100644 (file)
 
 #include <uapi/asm/ptrace.h>
 
+/* This struct defines the way the registers are stored on the
+   stack during a system call.  */
+
 #ifndef __ASSEMBLY__
+struct pt_regs {
+       unsigned long  r8;      /* r8-r15 Caller-saved GP registers */
+       unsigned long  r9;
+       unsigned long  r10;
+       unsigned long  r11;
+       unsigned long  r12;
+       unsigned long  r13;
+       unsigned long  r14;
+       unsigned long  r15;
+       unsigned long  r1;      /* Assembler temporary */
+       unsigned long  r2;      /* Retval LS 32bits */
+       unsigned long  r3;      /* Retval MS 32bits */
+       unsigned long  r4;      /* r4-r7 Register arguments */
+       unsigned long  r5;
+       unsigned long  r6;
+       unsigned long  r7;
+       unsigned long  orig_r2; /* Copy of r2 ?? */
+       unsigned long  ra;      /* Return address */
+       unsigned long  fp;      /* Frame pointer */
+       unsigned long  sp;      /* Stack pointer */
+       unsigned long  gp;      /* Global pointer */
+       unsigned long  estatus;
+       unsigned long  ea;      /* Exception return address (pc) */
+       unsigned long  orig_r7;
+};
+
+/*
+ * This is the extended stack used by signal handlers and the context
+ * switcher: it's pushed after the normal "struct pt_regs".
+ */
+struct switch_stack {
+       unsigned long  r16;     /* r16-r23 Callee-saved GP registers */
+       unsigned long  r17;
+       unsigned long  r18;
+       unsigned long  r19;
+       unsigned long  r20;
+       unsigned long  r21;
+       unsigned long  r22;
+       unsigned long  r23;
+       unsigned long  fp;
+       unsigned long  gp;
+       unsigned long  ra;
+};
+
 #define user_mode(regs)        (((regs)->estatus & ESTATUS_EU))
 
 #define instruction_pointer(regs)      ((regs)->ra)
diff --git a/arch/nios2/include/asm/ucontext.h b/arch/nios2/include/asm/ucontext.h
deleted file mode 100644 (file)
index 2c87614..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch>
- * Copyright (C) 2004 Microtronix Datacom Ltd
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_NIOS2_UCONTEXT_H
-#define _ASM_NIOS2_UCONTEXT_H
-
-typedef int greg_t;
-#define NGREG 32
-typedef greg_t gregset_t[NGREG];
-
-struct mcontext {
-       int version;
-       gregset_t gregs;
-};
-
-#define MCONTEXT_VERSION 2
-
-struct ucontext {
-       unsigned long     uc_flags;
-       struct ucontext  *uc_link;
-       stack_t           uc_stack;
-       struct mcontext   uc_mcontext;
-       sigset_t          uc_sigmask;   /* mask last for extensibility */
-};
-
-#endif
index 4f07ca3..3761311 100644 (file)
@@ -2,3 +2,5 @@ include include/uapi/asm-generic/Kbuild.asm
 
 header-y += elf.h
 header-y += ucontext.h
+
+generic-y += ucontext.h
index a5b91ae..6f06d3b 100644 (file)
@@ -50,9 +50,7 @@
 
 typedef unsigned long elf_greg_t;
 
-#define ELF_NGREG      \
-       ((sizeof(struct pt_regs) + sizeof(struct switch_stack)) /       \
-               sizeof(elf_greg_t))
+#define ELF_NGREG              49
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
 typedef unsigned long elf_fpregset_t;
index e83a7c9..71a3305 100644 (file)
 
 #define NUM_PTRACE_REG (PTR_TLBMISC + 1)
 
-/* this struct defines the way the registers are stored on the
-   stack during a system call.
-
-   There is a fake_regs in setup.c that has to match pt_regs.*/
-
-struct pt_regs {
-       unsigned long  r8;              /* r8-r15 Caller-saved GP registers */
-       unsigned long  r9;
-       unsigned long  r10;
-       unsigned long  r11;
-       unsigned long  r12;
-       unsigned long  r13;
-       unsigned long  r14;
-       unsigned long  r15;
-       unsigned long  r1;              /* Assembler temporary */
-       unsigned long  r2;              /* Retval LS 32bits */
-       unsigned long  r3;              /* Retval MS 32bits */
-       unsigned long  r4;              /* r4-r7 Register arguments */
-       unsigned long  r5;
-       unsigned long  r6;
-       unsigned long  r7;
-       unsigned long  orig_r2;         /* Copy of r2 ?? */
-       unsigned long  ra;              /* Return address */
-       unsigned long  fp;              /* Frame pointer */
-       unsigned long  sp;              /* Stack pointer */
-       unsigned long  gp;              /* Global pointer */
-       unsigned long  estatus;
-       unsigned long  ea;              /* Exception return address (pc) */
-       unsigned long  orig_r7;
-};
-
-/*
- * This is the extended stack used by signal handlers and the context
- * switcher: it's pushed after the normal "struct pt_regs".
- */
-struct switch_stack {
-       unsigned long  r16;             /* r16-r23 Callee-saved GP registers */
-       unsigned long  r17;
-       unsigned long  r18;
-       unsigned long  r19;
-       unsigned long  r20;
-       unsigned long  r21;
-       unsigned long  r22;
-       unsigned long  r23;
-       unsigned long  fp;
-       unsigned long  gp;
-       unsigned long  ra;
+/* User structures for general purpose registers.  */
+struct user_pt_regs {
+       __u32           regs[49];
 };
 
 #endif /* __ASSEMBLY__ */
index 7b8bb41..b67944a 100644 (file)
  * details.
  */
 
-#ifndef _ASM_NIOS2_SIGCONTEXT_H
-#define _ASM_NIOS2_SIGCONTEXT_H
+#ifndef _UAPI__ASM_SIGCONTEXT_H
+#define _UAPI__ASM_SIGCONTEXT_H
 
-#include <asm/ptrace.h>
+#include <linux/types.h>
+
+#define MCONTEXT_VERSION 2
 
 struct sigcontext {
-       struct pt_regs regs;
-       unsigned long  sc_mask; /* old sigmask */
+       int version;
+       unsigned long gregs[32];
 };
 
 #endif
index 2d0ea25..dda41e4 100644 (file)
@@ -39,7 +39,7 @@ static inline int rt_restore_ucontext(struct pt_regs *regs,
                                        struct ucontext *uc, int *pr2)
 {
        int temp;
-       greg_t *gregs = uc->uc_mcontext.gregs;
+       unsigned long *gregs = uc->uc_mcontext.gregs;
        int err;
 
        /* Always make any pending restarted system calls return -EINTR */
@@ -127,7 +127,7 @@ badframe:
 static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
 {
        struct switch_stack *sw = (struct switch_stack *)regs - 1;
-       greg_t *gregs = uc->uc_mcontext.gregs;
+       unsigned long *gregs = uc->uc_mcontext.gregs;
        int err = 0;
 
        err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
index f6579cf..19e17bd 100644 (file)
@@ -165,7 +165,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_ONE_REG:
        case KVM_CAP_ENABLE_CAP:
        case KVM_CAP_S390_CSS_SUPPORT:
-       case KVM_CAP_IRQFD:
        case KVM_CAP_IOEVENTFD:
        case KVM_CAP_DEVICE_CTRL:
        case KVM_CAP_ENABLE_CAP_VM:
index 7083c16..bb13763 100644 (file)
 static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@"
                LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION;
 
-struct kaslr_setup_data {
-       __u64 next;
-       __u32 type;
-       __u32 len;
-       __u8 data[1];
-} kaslr_setup_data;
-
 #define I8254_PORT_CONTROL     0x43
 #define I8254_PORT_COUNTER0    0x40
 #define I8254_CMD_READBACK     0xC0
@@ -302,29 +295,7 @@ static unsigned long find_random_addr(unsigned long minimum,
        return slots_fetch_random();
 }
 
-static void add_kaslr_setup_data(struct boot_params *params, __u8 enabled)
-{
-       struct setup_data *data;
-
-       kaslr_setup_data.type = SETUP_KASLR;
-       kaslr_setup_data.len = 1;
-       kaslr_setup_data.next = 0;
-       kaslr_setup_data.data[0] = enabled;
-
-       data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
-
-       while (data && data->next)
-               data = (struct setup_data *)(unsigned long)data->next;
-
-       if (data)
-               data->next = (unsigned long)&kaslr_setup_data;
-       else
-               params->hdr.setup_data = (unsigned long)&kaslr_setup_data;
-
-}
-
-unsigned char *choose_kernel_location(struct boot_params *params,
-                                     unsigned char *input,
+unsigned char *choose_kernel_location(unsigned char *input,
                                      unsigned long input_size,
                                      unsigned char *output,
                                      unsigned long output_size)
@@ -335,17 +306,14 @@ unsigned char *choose_kernel_location(struct boot_params *params,
 #ifdef CONFIG_HIBERNATION
        if (!cmdline_find_option_bool("kaslr")) {
                debug_putstr("KASLR disabled by default...\n");
-               add_kaslr_setup_data(params, 0);
                goto out;
        }
 #else
        if (cmdline_find_option_bool("nokaslr")) {
                debug_putstr("KASLR disabled by cmdline...\n");
-               add_kaslr_setup_data(params, 0);
                goto out;
        }
 #endif
-       add_kaslr_setup_data(params, 1);
 
        /* Record the various known unsafe memory ranges. */
        mem_avoid_init((unsigned long)input, input_size,
index 5903089..a950864 100644 (file)
@@ -401,8 +401,7 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,
         * the entire decompressed kernel plus relocation table, or the
         * entire decompressed kernel plus .bss and .brk sections.
         */
-       output = choose_kernel_location(real_mode, input_data, input_len,
-                                       output,
+       output = choose_kernel_location(input_data, input_len, output,
                                        output_len > run_size ? output_len
                                                              : run_size);
 
index ee3576b..04477d6 100644 (file)
@@ -57,8 +57,7 @@ int cmdline_find_option_bool(const char *option);
 
 #if CONFIG_RANDOMIZE_BASE
 /* aslr.c */
-unsigned char *choose_kernel_location(struct boot_params *params,
-                                     unsigned char *input,
+unsigned char *choose_kernel_location(unsigned char *input,
                                      unsigned long input_size,
                                      unsigned char *output,
                                      unsigned long output_size);
@@ -66,8 +65,7 @@ unsigned char *choose_kernel_location(struct boot_params *params,
 bool has_cpuflag(int flag);
 #else
 static inline
-unsigned char *choose_kernel_location(struct boot_params *params,
-                                     unsigned char *input,
+unsigned char *choose_kernel_location(unsigned char *input,
                                      unsigned long input_size,
                                      unsigned char *output,
                                      unsigned long output_size)
index 947c6bf..54f60ab 100644 (file)
@@ -1155,7 +1155,7 @@ static int __driver_rfc4106_decrypt(struct aead_request *req)
                src = kmalloc(req->cryptlen + req->assoclen, GFP_ATOMIC);
                if (!src)
                        return -ENOMEM;
-               assoc = (src + req->cryptlen + auth_tag_len);
+               assoc = (src + req->cryptlen);
                scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0);
                scatterwalk_map_and_copy(assoc, req->assoc, 0,
                        req->assoclen, 0);
@@ -1180,7 +1180,7 @@ static int __driver_rfc4106_decrypt(struct aead_request *req)
                scatterwalk_done(&src_sg_walk, 0, 0);
                scatterwalk_done(&assoc_sg_walk, 0, 0);
        } else {
-               scatterwalk_map_and_copy(dst, req->dst, 0, req->cryptlen, 1);
+               scatterwalk_map_and_copy(dst, req->dst, 0, tempCipherLen, 1);
                kfree(src);
        }
        return retval;
index 0dbc082..72ba21a 100644 (file)
@@ -370,7 +370,7 @@ static inline void drop_fpu(struct task_struct *tsk)
        preempt_disable();
        tsk->thread.fpu_counter = 0;
        __drop_fpu(tsk);
-       clear_used_math();
+       clear_stopped_child_used_math(tsk);
        preempt_enable();
 }
 
index 95e11f7..f97fbe3 100644 (file)
@@ -51,8 +51,6 @@ extern int devmem_is_allowed(unsigned long pagenr);
 extern unsigned long max_low_pfn_mapped;
 extern unsigned long max_pfn_mapped;
 
-extern bool kaslr_enabled;
-
 static inline phys_addr_t get_max_mapped(void)
 {
        return (phys_addr_t)max_pfn_mapped << PAGE_SHIFT;
index 44e6dd7..225b098 100644 (file)
@@ -7,7 +7,6 @@
 #define SETUP_DTB                      2
 #define SETUP_PCI                      3
 #define SETUP_EFI                      4
-#define SETUP_KASLR                    5
 
 /* ram_size flags */
 #define RAMDISK_IMAGE_START_MASK       0x07FF
index 3d525c6..803b684 100644 (file)
@@ -1338,6 +1338,26 @@ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d)
 }
 
 /*
+ * ACPI offers an alternative platform interface model that removes
+ * ACPI hardware requirements for platforms that do not implement
+ * the PC Architecture.
+ *
+ * We initialize the Hardware-reduced ACPI model here:
+ */
+static void __init acpi_reduced_hw_init(void)
+{
+       if (acpi_gbl_reduced_hardware) {
+               /*
+                * Override x86_init functions and bypass legacy pic
+                * in Hardware-reduced ACPI mode
+                */
+               x86_init.timers.timer_init      = x86_init_noop;
+               x86_init.irqs.pre_vector_init   = x86_init_noop;
+               legacy_pic                      = &null_legacy_pic;
+       }
+}
+
+/*
  * If your system is blacklisted here, but you find that acpi=force
  * works for you, please contact linux-acpi@vger.kernel.org
  */
@@ -1536,6 +1556,11 @@ int __init early_acpi_boot_init(void)
         */
        early_acpi_process_madt();
 
+       /*
+        * Hardware-reduced ACPI mode initialization:
+        */
+       acpi_reduced_hw_init();
+
        return 0;
 }
 
index c2fd21f..017149c 100644 (file)
@@ -37,10 +37,12 @@ static const struct apic apic_numachip;
 static unsigned int get_apic_id(unsigned long x)
 {
        unsigned long value;
-       unsigned int id;
+       unsigned int id = (x >> 24) & 0xff;
 
-       rdmsrl(MSR_FAM10H_NODE_ID, value);
-       id = ((x >> 24) & 0xffU) | ((value << 2) & 0xff00U);
+       if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) {
+               rdmsrl(MSR_FAM10H_NODE_ID, value);
+               id |= (value << 2) & 0xff00;
+       }
 
        return id;
 }
@@ -155,10 +157,18 @@ static int __init numachip_probe(void)
 
 static void fixup_cpu_id(struct cpuinfo_x86 *c, int node)
 {
-       if (c->phys_proc_id != node) {
-               c->phys_proc_id = node;
-               per_cpu(cpu_llc_id, smp_processor_id()) = node;
+       u64 val;
+       u32 nodes = 1;
+
+       this_cpu_write(cpu_llc_id, node);
+
+       /* Account for nodes per socket in multi-core-module processors */
+       if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) {
+               rdmsrl(MSR_FAM10H_NODE_ID, val);
+               nodes = ((val >> 3) & 7) + 1;
        }
+
+       c->phys_proc_id = node / nodes;
 }
 
 static int __init numachip_system_init(void)
index 9bbb9b3..d1ac80b 100644 (file)
@@ -47,13 +47,21 @@ do {                                                        \
 
 #ifdef CONFIG_RANDOMIZE_BASE
 static unsigned long module_load_offset;
+static int randomize_modules = 1;
 
 /* Mutex protects the module_load_offset. */
 static DEFINE_MUTEX(module_kaslr_mutex);
 
+static int __init parse_nokaslr(char *p)
+{
+       randomize_modules = 0;
+       return 0;
+}
+early_param("nokaslr", parse_nokaslr);
+
 static unsigned long int get_module_load_offset(void)
 {
-       if (kaslr_enabled) {
+       if (randomize_modules) {
                mutex_lock(&module_kaslr_mutex);
                /*
                 * Calculate the module_load_offset the first time this
index 98dc931..0a2421c 100644 (file)
 unsigned long max_low_pfn_mapped;
 unsigned long max_pfn_mapped;
 
-bool __read_mostly kaslr_enabled = false;
-
 #ifdef CONFIG_DMI
 RESERVE_BRK(dmi_alloc, 65536);
 #endif
@@ -427,11 +425,6 @@ static void __init reserve_initrd(void)
 }
 #endif /* CONFIG_BLK_DEV_INITRD */
 
-static void __init parse_kaslr_setup(u64 pa_data, u32 data_len)
-{
-       kaslr_enabled = (bool)(pa_data + sizeof(struct setup_data));
-}
-
 static void __init parse_setup_data(void)
 {
        struct setup_data *data;
@@ -457,9 +450,6 @@ static void __init parse_setup_data(void)
                case SETUP_EFI:
                        parse_efi_setup(pa_data, data_len);
                        break;
-               case SETUP_KASLR:
-                       parse_kaslr_setup(pa_data, data_len);
-                       break;
                default:
                        break;
                }
@@ -842,14 +832,10 @@ static void __init trim_low_memory_range(void)
 static int
 dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
 {
-       if (kaslr_enabled)
-               pr_emerg("Kernel Offset: 0x%lx from 0x%lx (relocation range: 0x%lx-0x%lx)\n",
-                        (unsigned long)&_text - __START_KERNEL,
-                        __START_KERNEL,
-                        __START_KERNEL_map,
-                        MODULES_VADDR-1);
-       else
-               pr_emerg("Kernel Offset: disabled\n");
+       pr_emerg("Kernel Offset: 0x%lx from 0x%lx "
+                "(relocation range: 0x%lx-0x%lx)\n",
+                (unsigned long)&_text - __START_KERNEL, __START_KERNEL,
+                __START_KERNEL_map, MODULES_VADDR-1);
 
        return 0;
 }
index 9d2073e..4ff5d16 100644 (file)
@@ -384,7 +384,7 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
                goto exit;
        conditional_sti(regs);
 
-       if (!user_mode(regs))
+       if (!user_mode_vm(regs))
                die("bounds", regs, error_code);
 
        if (!cpu_feature_enabled(X86_FEATURE_MPX)) {
@@ -637,7 +637,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
         * then it's very likely the result of an icebp/int01 trap.
         * User wants a sigtrap for that.
         */
-       if (!dr6 && user_mode(regs))
+       if (!dr6 && user_mode_vm(regs))
                user_icebp = 1;
 
        /* Catch kmemcheck conditions first of all! */
index 34f66e5..cdc6cf9 100644 (file)
@@ -379,7 +379,7 @@ int __restore_xstate_sig(void __user *buf, void __user *buf_fx, int size)
                 * thread's fpu state, reconstruct fxstate from the fsave
                 * header. Sanitize the copied state etc.
                 */
-               struct xsave_struct *xsave = &tsk->thread.fpu.state->xsave;
+               struct fpu *fpu = &tsk->thread.fpu;
                struct user_i387_ia32_struct env;
                int err = 0;
 
@@ -393,14 +393,15 @@ int __restore_xstate_sig(void __user *buf, void __user *buf_fx, int size)
                 */
                drop_fpu(tsk);
 
-               if (__copy_from_user(xsave, buf_fx, state_size) ||
+               if (__copy_from_user(&fpu->state->xsave, buf_fx, state_size) ||
                    __copy_from_user(&env, buf, sizeof(env))) {
+                       fpu_finit(fpu);
                        err = -1;
                } else {
                        sanitize_restored_xstate(tsk, &env, xstate_bv, fx_only);
-                       set_used_math();
                }
 
+               set_used_math();
                if (use_eager_fpu()) {
                        preempt_disable();
                        math_state_restore();
index cc31f7c..9541ba3 100644 (file)
@@ -507,6 +507,7 @@ static int picdev_read(struct kvm_pic *s,
                return -EOPNOTSUPP;
 
        if (len != 1) {
+               memset(val, 0, len);
                pr_pic_unimpl("non byte read\n");
                return 0;
        }
index f7b20b4..10a481b 100644 (file)
@@ -2168,7 +2168,10 @@ static void vmx_set_msr_bitmap(struct kvm_vcpu *vcpu)
 {
        unsigned long *msr_bitmap;
 
-       if (irqchip_in_kernel(vcpu->kvm) && apic_x2apic_mode(vcpu->arch.apic)) {
+       if (is_guest_mode(vcpu))
+               msr_bitmap = vmx_msr_bitmap_nested;
+       else if (irqchip_in_kernel(vcpu->kvm) &&
+               apic_x2apic_mode(vcpu->arch.apic)) {
                if (is_long_mode(vcpu))
                        msr_bitmap = vmx_msr_bitmap_longmode_x2apic;
                else
@@ -9218,9 +9221,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
        }
 
        if (cpu_has_vmx_msr_bitmap() &&
-           exec_control & CPU_BASED_USE_MSR_BITMAPS &&
-           nested_vmx_merge_msr_bitmap(vcpu, vmcs12)) {
-               vmcs_write64(MSR_BITMAP, __pa(vmx_msr_bitmap_nested));
+           exec_control & CPU_BASED_USE_MSR_BITMAPS) {
+               nested_vmx_merge_msr_bitmap(vcpu, vmcs12);
+               /* MSR_BITMAP will be set by following vmx_set_efer. */
        } else
                exec_control &= ~CPU_BASED_USE_MSR_BITMAPS;
 
index bd7a70b..32bf19e 100644 (file)
@@ -2744,7 +2744,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_USER_NMI:
        case KVM_CAP_REINJECT_CONTROL:
        case KVM_CAP_IRQ_INJECT_STATUS:
-       case KVM_CAP_IRQFD:
        case KVM_CAP_IOEVENTFD:
        case KVM_CAP_IOEVENTFD_NO_LENGTH:
        case KVM_CAP_PIT2:
index 31776d0..d7ec4e2 100644 (file)
@@ -17,6 +17,7 @@
        .text
        .globl __kernel_sigreturn
        .type __kernel_sigreturn,@function
+       nop /* this guy is needed for .LSTARTFDEDLSI1 below (watch for HACK) */
        ALIGN
 __kernel_sigreturn:
 .LSTART_sigreturn:
index 740ae30..9f93af5 100644 (file)
@@ -563,7 +563,7 @@ static bool alloc_p2m(unsigned long pfn)
                if (p2m_pfn == PFN_DOWN(__pa(p2m_missing)))
                        p2m_init(p2m);
                else
-                       p2m_init_identity(p2m, pfn);
+                       p2m_init_identity(p2m, pfn & ~(P2M_PER_PAGE - 1));
 
                spin_lock_irqsave(&p2m_update_lock, flags);
 
index 657964e..37fb190 100644 (file)
@@ -65,6 +65,7 @@ struct lpss_private_data;
 
 struct lpss_device_desc {
        unsigned int flags;
+       const char *clk_con_id;
        unsigned int prv_offset;
        size_t prv_size_override;
        void (*setup)(struct lpss_private_data *pdata);
@@ -140,6 +141,7 @@ static struct lpss_device_desc lpt_i2c_dev_desc = {
 
 static struct lpss_device_desc lpt_uart_dev_desc = {
        .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_LTR,
+       .clk_con_id = "baudclk",
        .prv_offset = 0x800,
        .setup = lpss_uart_setup,
 };
@@ -156,6 +158,7 @@ static struct lpss_device_desc byt_pwm_dev_desc = {
 
 static struct lpss_device_desc byt_uart_dev_desc = {
        .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX,
+       .clk_con_id = "baudclk",
        .prv_offset = 0x800,
        .setup = lpss_uart_setup,
 };
@@ -313,7 +316,7 @@ out:
                return PTR_ERR(clk);
 
        pdata->clk = clk;
-       clk_register_clkdev(clk, NULL, devname);
+       clk_register_clkdev(clk, dev_desc->clk_con_id, devname);
        return 0;
 }
 
index d453a2c..81751a4 100644 (file)
@@ -307,7 +307,7 @@ static int regcache_rbtree_insert_to_block(struct regmap *map,
        if (pos == 0) {
                memmove(blk + offset * map->cache_word_size,
                        blk, rbnode->blklen * map->cache_word_size);
-               bitmap_shift_right(present, present, offset, blklen);
+               bitmap_shift_left(present, present, offset, blklen);
        }
 
        /* update the rbnode block, its size and the base register */
index f373c35..da84f54 100644 (file)
@@ -608,7 +608,8 @@ static int regcache_sync_block_single(struct regmap *map, void *block,
        for (i = start; i < end; i++) {
                regtmp = block_base + (i * map->reg_stride);
 
-               if (!regcache_reg_present(cache_present, i))
+               if (!regcache_reg_present(cache_present, i) ||
+                   !regmap_writeable(map, regtmp))
                        continue;
 
                val = regcache_get_val(map, block, i);
@@ -677,7 +678,8 @@ static int regcache_sync_block_raw(struct regmap *map, void *block,
        for (i = start; i < end; i++) {
                regtmp = block_base + (i * map->reg_stride);
 
-               if (!regcache_reg_present(cache_present, i)) {
+               if (!regcache_reg_present(cache_present, i) ||
+                   !regmap_writeable(map, regtmp)) {
                        ret = regcache_sync_block_raw_flush(map, &data,
                                                            base, regtmp);
                        if (ret != 0)
index 6299a50..a6c3f75 100644 (file)
@@ -499,7 +499,8 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
                goto err_alloc;
        }
 
-       ret = request_threaded_irq(irq, NULL, regmap_irq_thread, irq_flags,
+       ret = request_threaded_irq(irq, NULL, regmap_irq_thread,
+                                  irq_flags | IRQF_ONESHOT,
                                   chip->name, d);
        if (ret != 0) {
                dev_err(map->dev, "Failed to request IRQ %d for %s: %d\n",
index fae2dbb..72d7028 100644 (file)
@@ -142,6 +142,7 @@ struct ports_device {
         * notification
         */
        struct work_struct control_work;
+       struct work_struct config_work;
 
        struct list_head ports;
 
@@ -1837,10 +1838,21 @@ static void config_intr(struct virtio_device *vdev)
 
        portdev = vdev->priv;
 
+       if (!use_multiport(portdev))
+               schedule_work(&portdev->config_work);
+}
+
+static void config_work_handler(struct work_struct *work)
+{
+       struct ports_device *portdev;
+
+       portdev = container_of(work, struct ports_device, control_work);
        if (!use_multiport(portdev)) {
+               struct virtio_device *vdev;
                struct port *port;
                u16 rows, cols;
 
+               vdev = portdev->vdev;
                virtio_cread(vdev, struct virtio_console_config, cols, &cols);
                virtio_cread(vdev, struct virtio_console_config, rows, &rows);
 
@@ -2040,12 +2052,14 @@ static int virtcons_probe(struct virtio_device *vdev)
 
        virtio_device_ready(portdev->vdev);
 
+       INIT_WORK(&portdev->config_work, &config_work_handler);
+       INIT_WORK(&portdev->control_work, &control_work_handler);
+
        if (multiport) {
                unsigned int nr_added_bufs;
 
                spin_lock_init(&portdev->c_ivq_lock);
                spin_lock_init(&portdev->c_ovq_lock);
-               INIT_WORK(&portdev->control_work, &control_work_handler);
 
                nr_added_bufs = fill_queue(portdev->c_ivq,
                                           &portdev->c_ivq_lock);
@@ -2113,6 +2127,8 @@ static void virtcons_remove(struct virtio_device *vdev)
        /* Finish up work that's lined up */
        if (use_multiport(portdev))
                cancel_work_sync(&portdev->control_work);
+       else
+               cancel_work_sync(&portdev->config_work);
 
        list_for_each_entry_safe(port, port2, &portdev->ports, list)
                unplug_port(port);
@@ -2164,6 +2180,7 @@ static int virtcons_freeze(struct virtio_device *vdev)
 
        virtqueue_disable_cb(portdev->c_ivq);
        cancel_work_sync(&portdev->control_work);
+       cancel_work_sync(&portdev->config_work);
        /*
         * Once more: if control_work_handler() was running, it would
         * enable the cb as the last step.
index db7f8bc..25006a8 100644 (file)
@@ -144,12 +144,6 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
                                   divider->flags);
 }
 
-/*
- * The reverse of DIV_ROUND_UP: The maximum number which
- * divided by m is r
- */
-#define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)
-
 static bool _is_valid_table_div(const struct clk_div_table *table,
                                                         unsigned int div)
 {
@@ -225,19 +219,24 @@ static int _div_round_closest(const struct clk_div_table *table,
                              unsigned long parent_rate, unsigned long rate,
                              unsigned long flags)
 {
-       int up, down, div;
+       int up, down;
+       unsigned long up_rate, down_rate;
 
-       up = down = div = DIV_ROUND_CLOSEST(parent_rate, rate);
+       up = DIV_ROUND_UP(parent_rate, rate);
+       down = parent_rate / rate;
 
        if (flags & CLK_DIVIDER_POWER_OF_TWO) {
-               up = __roundup_pow_of_two(div);
-               down = __rounddown_pow_of_two(div);
+               up = __roundup_pow_of_two(up);
+               down = __rounddown_pow_of_two(down);
        } else if (table) {
-               up = _round_up_table(table, div);
-               down = _round_down_table(table, div);
+               up = _round_up_table(table, up);
+               down = _round_down_table(table, down);
        }
 
-       return (up - div) <= (div - down) ? up : down;
+       up_rate = DIV_ROUND_UP(parent_rate, up);
+       down_rate = DIV_ROUND_UP(parent_rate, down);
+
+       return (rate - up_rate) <= (down_rate - rate) ? up : down;
 }
 
 static int _div_round(const struct clk_div_table *table,
@@ -313,7 +312,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
                        return i;
                }
                parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
-                               MULT_ROUND_UP(rate, i));
+                                              rate * i);
                now = DIV_ROUND_UP(parent_rate, i);
                if (_is_best_div(rate, now, best, flags)) {
                        bestdiv = i;
@@ -353,7 +352,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
                bestdiv = readl(divider->reg) >> divider->shift;
                bestdiv &= div_mask(divider->width);
                bestdiv = _get_div(divider->table, bestdiv, divider->flags);
-               return bestdiv;
+               return DIV_ROUND_UP(*prate, bestdiv);
        }
 
        return divider_round_rate(hw, rate, prate, divider->table,
index eb01529..237f23f 100644 (file)
@@ -1350,7 +1350,6 @@ static unsigned long clk_core_get_rate(struct clk_core *clk)
 
        return rate;
 }
-EXPORT_SYMBOL_GPL(clk_core_get_rate);
 
 /**
  * clk_get_rate - return the rate of clk
@@ -2171,6 +2170,32 @@ int clk_get_phase(struct clk *clk)
 }
 
 /**
+ * clk_is_match - check if two clk's point to the same hardware clock
+ * @p: clk compared against q
+ * @q: clk compared against p
+ *
+ * Returns true if the two struct clk pointers both point to the same hardware
+ * clock node. Put differently, returns true if struct clk *p and struct clk *q
+ * share the same struct clk_core object.
+ *
+ * Returns false otherwise. Note that two NULL clks are treated as matching.
+ */
+bool clk_is_match(const struct clk *p, const struct clk *q)
+{
+       /* trivial case: identical struct clk's or both NULL */
+       if (p == q)
+               return true;
+
+       /* true if clk->core pointers match. Avoid derefing garbage */
+       if (!IS_ERR_OR_NULL(p) && !IS_ERR_OR_NULL(q))
+               if (p->core == q->core)
+                       return true;
+
+       return false;
+}
+EXPORT_SYMBOL_GPL(clk_is_match);
+
+/**
  * __clk_init - initialize the data structures in a struct clk
  * @dev:       device initializing this clk, placeholder for now
  * @clk:       clk being initialized
index b0b562b..e60feff 100644 (file)
@@ -48,6 +48,17 @@ static struct clk_pll pll3 = {
        },
 };
 
+static struct clk_regmap pll4_vote = {
+       .enable_reg = 0x34c0,
+       .enable_mask = BIT(4),
+       .hw.init = &(struct clk_init_data){
+               .name = "pll4_vote",
+               .parent_names = (const char *[]){ "pll4" },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
 static struct clk_pll pll8 = {
        .l_reg = 0x3144,
        .m_reg = 0x3148,
@@ -3023,6 +3034,7 @@ static struct clk_branch rpm_msg_ram_h_clk = {
 
 static struct clk_regmap *gcc_msm8960_clks[] = {
        [PLL3] = &pll3.clkr,
+       [PLL4_VOTE] = &pll4_vote,
        [PLL8] = &pll8.clkr,
        [PLL8_VOTE] = &pll8_vote,
        [PLL14] = &pll14.clkr,
@@ -3247,6 +3259,7 @@ static const struct qcom_reset_map gcc_msm8960_resets[] = {
 
 static struct clk_regmap *gcc_apq8064_clks[] = {
        [PLL3] = &pll3.clkr,
+       [PLL4_VOTE] = &pll4_vote,
        [PLL8] = &pll8.clkr,
        [PLL8_VOTE] = &pll8_vote,
        [PLL14] = &pll14.clkr,
index 121ffde..c9ff27b 100644 (file)
@@ -462,7 +462,6 @@ static struct platform_driver lcc_ipq806x_driver = {
        .remove         = lcc_ipq806x_remove,
        .driver         = {
                .name   = "lcc-ipq806x",
-               .owner  = THIS_MODULE,
                .of_match_table = lcc_ipq806x_match_table,
        },
 };
index a75a408..e2c8632 100644 (file)
@@ -417,8 +417,8 @@ static struct clk_rcg slimbus_src = {
                .mnctr_en_bit = 8,
                .mnctr_reset_bit = 7,
                .mnctr_mode_shift = 5,
-               .n_val_shift = 16,
-               .m_val_shift = 16,
+               .n_val_shift = 24,
+               .m_val_shift = 8,
                .width = 8,
        },
        .p = {
@@ -547,7 +547,7 @@ static int lcc_msm8960_probe(struct platform_device *pdev)
                return PTR_ERR(regmap);
 
        /* Use the correct frequency plan depending on speed of PLL4 */
-       val = regmap_read(regmap, 0x4, &val);
+       regmap_read(regmap, 0x4, &val);
        if (val == 0x12) {
                slimbus_src.freq_tbl = clk_tbl_aif_osr_492;
                mi2s_osr_src.freq_tbl = clk_tbl_aif_osr_492;
@@ -574,7 +574,6 @@ static struct platform_driver lcc_msm8960_driver = {
        .remove         = lcc_msm8960_remove,
        .driver         = {
                .name   = "lcc-msm8960",
-               .owner  = THIS_MODULE,
                .of_match_table = lcc_msm8960_match_table,
        },
 };
index 6ef8963..d216406 100644 (file)
@@ -84,7 +84,7 @@ static int ti_fapll_enable(struct clk_hw *hw)
        struct fapll_data *fd = to_fapll(hw);
        u32 v = readl_relaxed(fd->base);
 
-       v |= (1 << FAPLL_MAIN_PLLEN);
+       v |= FAPLL_MAIN_PLLEN;
        writel_relaxed(v, fd->base);
 
        return 0;
@@ -95,7 +95,7 @@ static void ti_fapll_disable(struct clk_hw *hw)
        struct fapll_data *fd = to_fapll(hw);
        u32 v = readl_relaxed(fd->base);
 
-       v &= ~(1 << FAPLL_MAIN_PLLEN);
+       v &= ~FAPLL_MAIN_PLLEN;
        writel_relaxed(v, fd->base);
 }
 
@@ -104,7 +104,7 @@ static int ti_fapll_is_enabled(struct clk_hw *hw)
        struct fapll_data *fd = to_fapll(hw);
        u32 v = readl_relaxed(fd->base);
 
-       return v & (1 << FAPLL_MAIN_PLLEN);
+       return v & FAPLL_MAIN_PLLEN;
 }
 
 static unsigned long ti_fapll_recalc_rate(struct clk_hw *hw,
index bba62f9..ec57ba2 100644 (file)
@@ -225,12 +225,12 @@ static int __init efm32_clockevent_init(struct device_node *np)
        clock_event_ddata.base = base;
        clock_event_ddata.periodic_top = DIV_ROUND_CLOSEST(rate, 1024 * HZ);
 
-       setup_irq(irq, &efm32_clock_event_irq);
-
        clockevents_config_and_register(&clock_event_ddata.evtdev,
                                        DIV_ROUND_CLOSEST(rate, 1024),
                                        0xf, 0xffff);
 
+       setup_irq(irq, &efm32_clock_event_irq);
+
        return 0;
 
 err_get_irq:
index 0226844..5dcbf90 100644 (file)
@@ -178,10 +178,6 @@ static void __init sun5i_timer_init(struct device_node *node)
 
        ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
 
-       ret = setup_irq(irq, &sun5i_timer_irq);
-       if (ret)
-               pr_warn("failed to setup irq %d\n", irq);
-
        /* Enable timer0 interrupt */
        val = readl(timer_base + TIMER_IRQ_EN_REG);
        writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG);
@@ -191,6 +187,10 @@ static void __init sun5i_timer_init(struct device_node *node)
 
        clockevents_config_and_register(&sun5i_clockevent, rate,
                                        TIMER_SYNC_TICKS, 0xffffffff);
+
+       ret = setup_irq(irq, &sun5i_timer_irq);
+       if (ret)
+               pr_warn("failed to setup irq %d\n", irq);
 }
 CLOCKSOURCE_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer",
                       sun5i_timer_init);
index 6b6b07f..f6d04c7 100644 (file)
 #include "drm_crtc_internal.h"
 #include "drm_internal.h"
 
-static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
-                                                       struct drm_mode_fb_cmd2 *r,
-                                                       struct drm_file *file_priv);
+static struct drm_framebuffer *
+internal_framebuffer_create(struct drm_device *dev,
+                           struct drm_mode_fb_cmd2 *r,
+                           struct drm_file *file_priv);
 
 /* Avoid boilerplate.  I'm tired of typing. */
 #define DRM_ENUM_NAME_FN(fnname, list)                         \
@@ -2908,13 +2909,11 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
         */
        if (req->flags & DRM_MODE_CURSOR_BO) {
                if (req->handle) {
-                       fb = add_framebuffer_internal(dev, &fbreq, file_priv);
+                       fb = internal_framebuffer_create(dev, &fbreq, file_priv);
                        if (IS_ERR(fb)) {
                                DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n");
                                return PTR_ERR(fb);
                        }
-
-                       drm_framebuffer_reference(fb);
                } else {
                        fb = NULL;
                }
@@ -3267,9 +3266,10 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
        return 0;
 }
 
-static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
-                                                       struct drm_mode_fb_cmd2 *r,
-                                                       struct drm_file *file_priv)
+static struct drm_framebuffer *
+internal_framebuffer_create(struct drm_device *dev,
+                           struct drm_mode_fb_cmd2 *r,
+                           struct drm_file *file_priv)
 {
        struct drm_mode_config *config = &dev->mode_config;
        struct drm_framebuffer *fb;
@@ -3301,12 +3301,6 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
                return fb;
        }
 
-       mutex_lock(&file_priv->fbs_lock);
-       r->fb_id = fb->base.id;
-       list_add(&fb->filp_head, &file_priv->fbs);
-       DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
-       mutex_unlock(&file_priv->fbs_lock);
-
        return fb;
 }
 
@@ -3328,15 +3322,24 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
 int drm_mode_addfb2(struct drm_device *dev,
                    void *data, struct drm_file *file_priv)
 {
+       struct drm_mode_fb_cmd2 *r = data;
        struct drm_framebuffer *fb;
 
        if (!drm_core_check_feature(dev, DRIVER_MODESET))
                return -EINVAL;
 
-       fb = add_framebuffer_internal(dev, data, file_priv);
+       fb = internal_framebuffer_create(dev, r, file_priv);
        if (IS_ERR(fb))
                return PTR_ERR(fb);
 
+       /* Transfer ownership to the filp for reaping on close */
+
+       DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
+       mutex_lock(&file_priv->fbs_lock);
+       r->fb_id = fb->base.id;
+       list_add(&fb->filp_head, &file_priv->fbs);
+       mutex_unlock(&file_priv->fbs_lock);
+
        return 0;
 }
 
index 9a5b687..379ab45 100644 (file)
@@ -733,10 +733,14 @@ static bool check_txmsg_state(struct drm_dp_mst_topology_mgr *mgr,
                              struct drm_dp_sideband_msg_tx *txmsg)
 {
        bool ret;
-       mutex_lock(&mgr->qlock);
+
+       /*
+        * All updates to txmsg->state are protected by mgr->qlock, and the two
+        * cases we check here are terminal states. For those the barriers
+        * provided by the wake_up/wait_event pair are enough.
+        */
        ret = (txmsg->state == DRM_DP_SIDEBAND_TX_RX ||
               txmsg->state == DRM_DP_SIDEBAND_TX_TIMEOUT);
-       mutex_unlock(&mgr->qlock);
        return ret;
 }
 
@@ -1363,12 +1367,13 @@ static int process_single_tx_qlock(struct drm_dp_mst_topology_mgr *mgr,
        return 0;
 }
 
-/* must be called holding qlock */
 static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
 {
        struct drm_dp_sideband_msg_tx *txmsg;
        int ret;
 
+       WARN_ON(!mutex_is_locked(&mgr->qlock));
+
        /* construct a chunk from the first msg in the tx_msg queue */
        if (list_empty(&mgr->tx_msg_downq)) {
                mgr->tx_down_in_progress = false;
index 7fc6f8b..1134526 100644 (file)
@@ -403,7 +403,7 @@ static int check_free_hole(u64 start, u64 end, u64 size, unsigned alignment)
                unsigned rem;
 
                rem = do_div(tmp, alignment);
-               if (tmp)
+               if (rem)
                        start += alignment - rem;
        }
 
index e5daad5..5b20586 100644 (file)
@@ -2936,9 +2936,9 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
        req = obj->last_read_req;
 
        /* Do this after OLR check to make sure we make forward progress polling
-        * on this IOCTL with a timeout <=0 (like busy ioctl)
+        * on this IOCTL with a timeout == 0 (like busy ioctl)
         */
-       if (args->timeout_ns <= 0) {
+       if (args->timeout_ns == 0) {
                ret = -ETIME;
                goto out;
        }
@@ -2948,7 +2948,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
        i915_gem_request_reference(req);
        mutex_unlock(&dev->struct_mutex);
 
-       ret = __i915_wait_request(req, reset_counter, true, &args->timeout_ns,
+       ret = __i915_wait_request(req, reset_counter, true,
+                                 args->timeout_ns > 0 ? &args->timeout_ns : NULL,
                                  file->driver_priv);
        mutex_lock(&dev->struct_mutex);
        i915_gem_request_unreference(req);
@@ -4792,6 +4793,9 @@ i915_gem_init_hw(struct drm_device *dev)
        if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt())
                return -EIO;
 
+       /* Double layer security blanket, see i915_gem_init() */
+       intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
        if (dev_priv->ellc_size)
                I915_WRITE(HSW_IDICR, I915_READ(HSW_IDICR) | IDIHASHMSK(0xf));
 
@@ -4824,7 +4828,7 @@ i915_gem_init_hw(struct drm_device *dev)
        for_each_ring(ring, dev_priv, i) {
                ret = ring->init_hw(ring);
                if (ret)
-                       return ret;
+                       goto out;
        }
 
        for (i = 0; i < NUM_L3_SLICES(dev); i++)
@@ -4841,9 +4845,11 @@ i915_gem_init_hw(struct drm_device *dev)
                DRM_ERROR("Context enable failed %d\n", ret);
                i915_gem_cleanup_ringbuffer(dev);
 
-               return ret;
+               goto out;
        }
 
+out:
+       intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
        return ret;
 }
 
@@ -4877,6 +4883,14 @@ int i915_gem_init(struct drm_device *dev)
                dev_priv->gt.stop_ring = intel_logical_ring_stop;
        }
 
+       /* This is just a security blanket to placate dragons.
+        * On some systems, we very sporadically observe that the first TLBs
+        * used by the CS may be stale, despite us poking the TLB reset. If
+        * we hold the forcewake during initialisation these problems
+        * just magically go away.
+        */
+       intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
        ret = i915_gem_init_userptr(dev);
        if (ret)
                goto out_unlock;
@@ -4903,6 +4917,7 @@ int i915_gem_init(struct drm_device *dev)
        }
 
 out_unlock:
+       intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
        mutex_unlock(&dev->struct_mutex);
 
        return ret;
index e730789..9943c20 100644 (file)
@@ -9716,7 +9716,7 @@ void intel_check_page_flip(struct drm_device *dev, int pipe)
        struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
-       WARN_ON(!in_irq());
+       WARN_ON(!in_interrupt());
 
        if (crtc == NULL)
                return;
index c47a3ba..4e8fb89 100644 (file)
@@ -1048,8 +1048,14 @@ static void intel_uncore_fw_domains_init(struct drm_device *dev)
 
                /* We need to init first for ECOBUS access and then
                 * determine later if we want to reinit, in case of MT access is
-                * not working
+                * not working. In this stage we don't know which flavour this
+                * ivb is, so it is better to reset also the gen6 fw registers
+                * before the ecobus check.
                 */
+
+               __raw_i915_write32(dev_priv, FORCEWAKE, 0);
+               __raw_posting_read(dev_priv, ECOBUS);
+
                fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
                               FORCEWAKE_MT, FORCEWAKE_MT_ACK);
 
index d13d1b5..df09ca7 100644 (file)
@@ -1030,37 +1030,59 @@ static inline bool radeon_test_signaled(struct radeon_fence *fence)
        return test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->base.flags);
 }
 
+struct radeon_wait_cb {
+       struct fence_cb base;
+       struct task_struct *task;
+};
+
+static void
+radeon_fence_wait_cb(struct fence *fence, struct fence_cb *cb)
+{
+       struct radeon_wait_cb *wait =
+               container_of(cb, struct radeon_wait_cb, base);
+
+       wake_up_process(wait->task);
+}
+
 static signed long radeon_fence_default_wait(struct fence *f, bool intr,
                                             signed long t)
 {
        struct radeon_fence *fence = to_radeon_fence(f);
        struct radeon_device *rdev = fence->rdev;
-       bool signaled;
+       struct radeon_wait_cb cb;
 
-       fence_enable_sw_signaling(&fence->base);
+       cb.task = current;
 
-       /*
-        * This function has to return -EDEADLK, but cannot hold
-        * exclusive_lock during the wait because some callers
-        * may already hold it. This means checking needs_reset without
-        * lock, and not fiddling with any gpu internals.
-        *
-        * The callback installed with fence_enable_sw_signaling will
-        * run before our wait_event_*timeout call, so we will see
-        * both the signaled fence and the changes to needs_reset.
-        */
+       if (fence_add_callback(f, &cb.base, radeon_fence_wait_cb))
+               return t;
+
+       while (t > 0) {
+               if (intr)
+                       set_current_state(TASK_INTERRUPTIBLE);
+               else
+                       set_current_state(TASK_UNINTERRUPTIBLE);
+
+               /*
+                * radeon_test_signaled must be called after
+                * set_current_state to prevent a race with wake_up_process
+                */
+               if (radeon_test_signaled(fence))
+                       break;
+
+               if (rdev->needs_reset) {
+                       t = -EDEADLK;
+                       break;
+               }
+
+               t = schedule_timeout(t);
+
+               if (t > 0 && intr && signal_pending(current))
+                       t = -ERESTARTSYS;
+       }
+
+       __set_current_state(TASK_RUNNING);
+       fence_remove_callback(f, &cb.base);
 
-       if (intr)
-               t = wait_event_interruptible_timeout(rdev->fence_queue,
-                       ((signaled = radeon_test_signaled(fence)) ||
-                        rdev->needs_reset), t);
-       else
-               t = wait_event_timeout(rdev->fence_queue,
-                       ((signaled = radeon_test_signaled(fence)) ||
-                        rdev->needs_reset), t);
-
-       if (t > 0 && !signaled)
-               return -EDEADLK;
        return t;
 }
 
index e088e55..a7fb273 100644 (file)
@@ -7130,8 +7130,7 @@ int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
        WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK);
 
        if (!vclk || !dclk) {
-               /* keep the Bypass mode, put PLL to sleep */
-               WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
+               /* keep the Bypass mode */
                return 0;
        }
 
@@ -7147,8 +7146,7 @@ int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
        /* set VCO_MODE to 1 */
        WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_VCO_MODE_MASK, ~UPLL_VCO_MODE_MASK);
 
-       /* toggle UPLL_SLEEP to 1 then back to 0 */
-       WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
+       /* disable sleep mode */
        WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_SLEEP_MASK);
 
        /* deassert UPLL_RESET */
index 6c6b655..e13b9cb 100644 (file)
@@ -725,32 +725,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
                goto out_err1;
        }
 
-       ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM,
-                            (dev_priv->vram_size >> PAGE_SHIFT));
-       if (unlikely(ret != 0)) {
-               DRM_ERROR("Failed initializing memory manager for VRAM.\n");
-               goto out_err2;
-       }
-
-       dev_priv->has_gmr = true;
-       if (((dev_priv->capabilities & (SVGA_CAP_GMR | SVGA_CAP_GMR2)) == 0) ||
-           refuse_dma || ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_GMR,
-                                        VMW_PL_GMR) != 0) {
-               DRM_INFO("No GMR memory available. "
-                        "Graphics memory resources are very limited.\n");
-               dev_priv->has_gmr = false;
-       }
-
-       if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) {
-               dev_priv->has_mob = true;
-               if (ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_MOB,
-                                  VMW_PL_MOB) != 0) {
-                       DRM_INFO("No MOB memory available. "
-                                "3D will be disabled.\n");
-                       dev_priv->has_mob = false;
-               }
-       }
-
        dev_priv->mmio_mtrr = arch_phys_wc_add(dev_priv->mmio_start,
                                               dev_priv->mmio_size);
 
@@ -813,6 +787,33 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
                goto out_no_fman;
        }
 
+
+       ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM,
+                            (dev_priv->vram_size >> PAGE_SHIFT));
+       if (unlikely(ret != 0)) {
+               DRM_ERROR("Failed initializing memory manager for VRAM.\n");
+               goto out_no_vram;
+       }
+
+       dev_priv->has_gmr = true;
+       if (((dev_priv->capabilities & (SVGA_CAP_GMR | SVGA_CAP_GMR2)) == 0) ||
+           refuse_dma || ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_GMR,
+                                        VMW_PL_GMR) != 0) {
+               DRM_INFO("No GMR memory available. "
+                        "Graphics memory resources are very limited.\n");
+               dev_priv->has_gmr = false;
+       }
+
+       if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) {
+               dev_priv->has_mob = true;
+               if (ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_MOB,
+                                  VMW_PL_MOB) != 0) {
+                       DRM_INFO("No MOB memory available. "
+                                "3D will be disabled.\n");
+                       dev_priv->has_mob = false;
+               }
+       }
+
        vmw_kms_save_vga(dev_priv);
 
        /* Start kms and overlay systems, needs fifo. */
@@ -838,6 +839,12 @@ out_no_fifo:
        vmw_kms_close(dev_priv);
 out_no_kms:
        vmw_kms_restore_vga(dev_priv);
+       if (dev_priv->has_mob)
+               (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB);
+       if (dev_priv->has_gmr)
+               (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR);
+       (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
+out_no_vram:
        vmw_fence_manager_takedown(dev_priv->fman);
 out_no_fman:
        if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
@@ -853,12 +860,6 @@ out_err4:
        iounmap(dev_priv->mmio_virt);
 out_err3:
        arch_phys_wc_del(dev_priv->mmio_mtrr);
-       if (dev_priv->has_mob)
-               (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB);
-       if (dev_priv->has_gmr)
-               (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR);
-       (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
-out_err2:
        (void)ttm_bo_device_release(&dev_priv->bdev);
 out_err1:
        vmw_ttm_global_release(dev_priv);
@@ -887,6 +888,13 @@ static int vmw_driver_unload(struct drm_device *dev)
        }
        vmw_kms_close(dev_priv);
        vmw_overlay_close(dev_priv);
+
+       if (dev_priv->has_mob)
+               (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB);
+       if (dev_priv->has_gmr)
+               (void)ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR);
+       (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
+
        vmw_fence_manager_takedown(dev_priv->fman);
        if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
                drm_irq_uninstall(dev_priv->dev);
@@ -898,11 +906,6 @@ static int vmw_driver_unload(struct drm_device *dev)
        ttm_object_device_release(&dev_priv->tdev);
        iounmap(dev_priv->mmio_virt);
        arch_phys_wc_del(dev_priv->mmio_mtrr);
-       if (dev_priv->has_mob)
-               (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB);
-       if (dev_priv->has_gmr)
-               (void)ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR);
-       (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
        (void)ttm_bo_device_release(&dev_priv->bdev);
        vmw_ttm_global_release(dev_priv);
 
@@ -1235,6 +1238,7 @@ static void vmw_remove(struct pci_dev *pdev)
 {
        struct drm_device *dev = pci_get_drvdata(pdev);
 
+       pci_disable_device(pdev);
        drm_put_dev(dev);
 }
 
index 33176d0..654c8da 100644 (file)
@@ -890,7 +890,8 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv,
        ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo);
        if (unlikely(ret != 0)) {
                DRM_ERROR("Could not find or use MOB buffer.\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_no_reloc;
        }
        bo = &vmw_bo->base;
 
@@ -914,7 +915,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv,
 
 out_no_reloc:
        vmw_dmabuf_unreference(&vmw_bo);
-       vmw_bo_p = NULL;
+       *vmw_bo_p = NULL;
        return ret;
 }
 
@@ -951,7 +952,8 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
        ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo);
        if (unlikely(ret != 0)) {
                DRM_ERROR("Could not find or use GMR region.\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_no_reloc;
        }
        bo = &vmw_bo->base;
 
@@ -974,7 +976,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
 
 out_no_reloc:
        vmw_dmabuf_unreference(&vmw_bo);
-       vmw_bo_p = NULL;
+       *vmw_bo_p = NULL;
        return ret;
 }
 
@@ -2780,13 +2782,11 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
                                  NULL, arg->command_size, arg->throttle_us,
                                  (void __user *)(unsigned long)arg->fence_rep,
                                  NULL);
-
+       ttm_read_unlock(&dev_priv->reservation_sem);
        if (unlikely(ret != 0))
-               goto out_unlock;
+               return ret;
 
        vmw_kms_cursor_post_execbuf(dev_priv);
 
-out_unlock:
-       ttm_read_unlock(&dev_priv->reservation_sem);
-       return ret;
+       return 0;
 }
index 8725b79..07cda8c 100644 (file)
@@ -2033,23 +2033,17 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
        int i;
        struct drm_mode_config *mode_config = &dev->mode_config;
 
-       ret = ttm_read_lock(&dev_priv->reservation_sem, true);
-       if (unlikely(ret != 0))
-               return ret;
-
        if (!arg->num_outputs) {
                struct drm_vmw_rect def_rect = {0, 0, 800, 600};
                vmw_du_update_layout(dev_priv, 1, &def_rect);
-               goto out_unlock;
+               return 0;
        }
 
        rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
        rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect),
                        GFP_KERNEL);
-       if (unlikely(!rects)) {
-               ret = -ENOMEM;
-               goto out_unlock;
-       }
+       if (unlikely(!rects))
+               return -ENOMEM;
 
        user_rects = (void __user *)(unsigned long)arg->rects;
        ret = copy_from_user(rects, user_rects, rects_size);
@@ -2074,7 +2068,5 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
 
 out_free:
        kfree(rects);
-out_unlock:
-       ttm_read_unlock(&dev_priv->reservation_sem);
        return ret;
 }
index 7c669c3..56ce8c2 100644 (file)
@@ -1959,6 +1959,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_PRO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
index 204312b..9c47867 100644 (file)
 #define USB_VENDOR_ID_LOGITECH         0x046d
 #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
 #define USB_DEVICE_ID_LOGITECH_T651    0xb00c
+#define USB_DEVICE_ID_LOGITECH_C077    0xc007
 #define USB_DEVICE_ID_LOGITECH_RECEIVER        0xc101
 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST  0xc110
 #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
 #define USB_VENDOR_ID_TIVO             0x150a
 #define USB_DEVICE_ID_TIVO_SLIDE_BT    0x1200
 #define USB_DEVICE_ID_TIVO_SLIDE       0x1201
+#define USB_DEVICE_ID_TIVO_SLIDE_PRO   0x1203
 
 #define USB_VENDOR_ID_TOPSEED          0x0766
 #define USB_DEVICE_ID_TOPSEED_CYBERLINK        0x0204
index d790d8d..d986969 100644 (file)
@@ -64,6 +64,7 @@ static const struct hid_device_id tivo_devices[] = {
        /* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) },
        { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_PRO) },
        { }
 };
 MODULE_DEVICE_TABLE(hid, tivo_devices);
index 9be99a6..a821277 100644 (file)
@@ -78,6 +78,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
        { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
+       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL },
        { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS },
        { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3_JP, HID_QUIRK_NO_INIT_REPORTS },
index 046351c..bbe32d6 100644 (file)
@@ -551,9 +551,13 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
           (features->type == CINTIQ && !(data[1] & 0x40)))
                return 1;
 
-       if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
+       if (wacom->shared) {
                wacom->shared->stylus_in_proximity = true;
 
+               if (wacom->shared->touch_down)
+                       return 1;
+       }
+
        /* in Range while exiting */
        if (((data[1] & 0xfe) == 0x20) && wacom->reporting_data) {
                input_report_key(input, BTN_TOUCH, 0);
@@ -1043,27 +1047,28 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
        struct input_dev *input = wacom->input;
        unsigned char *data = wacom->data;
        int i;
-       int current_num_contacts = 0;
+       int current_num_contacts = data[61];
        int contacts_to_send = 0;
        int num_contacts_left = 4; /* maximum contacts per packet */
        int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET;
        int y_offset = 2;
+       static int contact_with_no_pen_down_count = 0;
 
        if (wacom->features.type == WACOM_27QHDT) {
                current_num_contacts = data[63];
                num_contacts_left = 10;
                byte_per_packet = WACOM_BYTES_PER_QHDTHID_PACKET;
                y_offset = 0;
-       } else {
-               current_num_contacts = data[61];
        }
 
        /*
         * First packet resets the counter since only the first
         * packet in series will have non-zero current_num_contacts.
         */
-       if (current_num_contacts)
+       if (current_num_contacts) {
                wacom->num_contacts_left = current_num_contacts;
+               contact_with_no_pen_down_count = 0;
+       }
 
        contacts_to_send = min(num_contacts_left, wacom->num_contacts_left);
 
@@ -1096,15 +1101,16 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
                                input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));
                                input_report_abs(input, ABS_MT_ORIENTATION, w > h);
                        }
+                       contact_with_no_pen_down_count++;
                }
        }
        input_mt_report_pointer_emulation(input, true);
 
        wacom->num_contacts_left -= contacts_to_send;
-       if (wacom->num_contacts_left <= 0)
+       if (wacom->num_contacts_left <= 0) {
                wacom->num_contacts_left = 0;
-
-       wacom->shared->touch_down = (wacom->num_contacts_left > 0);
+               wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
+       }
        return 1;
 }
 
@@ -1116,6 +1122,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom)
        int current_num_contacts = data[2];
        int contacts_to_send = 0;
        int x_offset = 0;
+       static int contact_with_no_pen_down_count = 0;
 
        /* MTTPC does not support Height and Width */
        if (wacom->features.type == MTTPC || wacom->features.type == MTTPC_B)
@@ -1125,8 +1132,10 @@ static int wacom_mt_touch(struct wacom_wac *wacom)
         * First packet resets the counter since only the first
         * packet in series will have non-zero current_num_contacts.
         */
-       if (current_num_contacts)
+       if (current_num_contacts) {
                wacom->num_contacts_left = current_num_contacts;
+               contact_with_no_pen_down_count = 0;
+       }
 
        /* There are at most 5 contacts per packet */
        contacts_to_send = min(5, wacom->num_contacts_left);
@@ -1147,15 +1156,16 @@ static int wacom_mt_touch(struct wacom_wac *wacom)
                        int y = get_unaligned_le16(&data[offset + x_offset + 9]);
                        input_report_abs(input, ABS_MT_POSITION_X, x);
                        input_report_abs(input, ABS_MT_POSITION_Y, y);
+                       contact_with_no_pen_down_count++;
                }
        }
        input_mt_report_pointer_emulation(input, true);
 
        wacom->num_contacts_left -= contacts_to_send;
-       if (wacom->num_contacts_left < 0)
+       if (wacom->num_contacts_left <= 0) {
                wacom->num_contacts_left = 0;
-
-       wacom->shared->touch_down = (wacom->num_contacts_left > 0);
+               wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
+       }
        return 1;
 }
 
@@ -1193,29 +1203,25 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
 {
        unsigned char *data = wacom->data;
        struct input_dev *input = wacom->input;
-       bool prox;
+       bool prox = !wacom->shared->stylus_in_proximity;
        int x = 0, y = 0;
 
        if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG)
                return 0;
 
-       if (!wacom->shared->stylus_in_proximity) {
-               if (len == WACOM_PKGLEN_TPC1FG) {
-                       prox = data[0] & 0x01;
-                       x = get_unaligned_le16(&data[1]);
-                       y = get_unaligned_le16(&data[3]);
-               } else if (len == WACOM_PKGLEN_TPC1FG_B) {
-                       prox = data[2] & 0x01;
-                       x = get_unaligned_le16(&data[3]);
-                       y = get_unaligned_le16(&data[5]);
-               } else {
-                       prox = data[1] & 0x01;
-                       x = le16_to_cpup((__le16 *)&data[2]);
-                       y = le16_to_cpup((__le16 *)&data[4]);
-               }
-       } else
-               /* force touch out when pen is in prox */
-               prox = 0;
+       if (len == WACOM_PKGLEN_TPC1FG) {
+               prox = prox && (data[0] & 0x01);
+               x = get_unaligned_le16(&data[1]);
+               y = get_unaligned_le16(&data[3]);
+       } else if (len == WACOM_PKGLEN_TPC1FG_B) {
+               prox = prox && (data[2] & 0x01);
+               x = get_unaligned_le16(&data[3]);
+               y = get_unaligned_le16(&data[5]);
+       } else {
+               prox = prox && (data[1] & 0x01);
+               x = le16_to_cpup((__le16 *)&data[2]);
+               y = le16_to_cpup((__le16 *)&data[4]);
+       }
 
        if (prox) {
                input_report_abs(input, ABS_X, x);
@@ -1613,6 +1619,7 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
        struct input_dev *pad_input = wacom->pad_input;
        unsigned char *data = wacom->data;
        int i;
+       int contact_with_no_pen_down_count = 0;
 
        if (data[0] != 0x02)
            return 0;
@@ -1640,6 +1647,7 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
                        }
                        input_report_abs(input, ABS_MT_POSITION_X, x);
                        input_report_abs(input, ABS_MT_POSITION_Y, y);
+                       contact_with_no_pen_down_count++;
                }
        }
 
@@ -1649,11 +1657,12 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
        input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0);
        input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0);
        input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0);
+       wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
 
        return 1;
 }
 
-static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
+static int wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data, int last_touch_count)
 {
        struct wacom_features *features = &wacom->features;
        struct input_dev *input = wacom->input;
@@ -1661,7 +1670,7 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
        int slot = input_mt_get_slot_by_key(input, data[0]);
 
        if (slot < 0)
-               return;
+               return 0;
 
        touch = touch && !wacom->shared->stylus_in_proximity;
 
@@ -1693,7 +1702,9 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
                input_report_abs(input, ABS_MT_POSITION_Y, y);
                input_report_abs(input, ABS_MT_TOUCH_MAJOR, width);
                input_report_abs(input, ABS_MT_TOUCH_MINOR, height);
+               last_touch_count++;
        }
+       return last_touch_count;
 }
 
 static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
@@ -1718,6 +1729,7 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom)
        unsigned char *data = wacom->data;
        int count = data[1] & 0x07;
        int i;
+       int contact_with_no_pen_down_count = 0;
 
        if (data[0] != 0x02)
            return 0;
@@ -1728,12 +1740,15 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom)
                int msg_id = data[offset];
 
                if (msg_id >= 2 && msg_id <= 17)
-                       wacom_bpt3_touch_msg(wacom, data + offset);
+                       contact_with_no_pen_down_count = 
+                           wacom_bpt3_touch_msg(wacom, data + offset,
+                                                contact_with_no_pen_down_count);
                else if (msg_id == 128)
                        wacom_bpt3_button_msg(wacom, data + offset);
 
        }
        input_mt_report_pointer_emulation(input, true);
+       wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
 
        return 1;
 }
@@ -1759,6 +1774,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
                return 0;
        }
 
+       if (wacom->shared->touch_down)
+               return 0;
+
        prox = (data[1] & 0x20) == 0x20;
 
        /*
index 210cf48..edf274c 100644 (file)
@@ -679,9 +679,6 @@ static int i2c_device_remove(struct device *dev)
                status = driver->remove(client);
        }
 
-       if (dev->of_node)
-               irq_dispose_mapping(client->irq);
-
        dev_pm_domain_detach(&client->dev, true);
        return status;
 }
index baa0d97..1ae4e54 100644 (file)
@@ -23,6 +23,7 @@ config IOMMU_IO_PGTABLE
 config IOMMU_IO_PGTABLE_LPAE
        bool "ARMv7/v8 Long Descriptor Format"
        select IOMMU_IO_PGTABLE
+       depends on ARM || ARM64 || COMPILE_TEST
        help
          Enable support for the ARM long descriptor pagetable format.
          This allocator supports 4K/2M/1G, 16K/32M and 64K/512M page
@@ -63,6 +64,7 @@ config MSM_IOMMU
        bool "MSM IOMMU Support"
        depends on ARM
        depends on ARCH_MSM8X60 || ARCH_MSM8960 || COMPILE_TEST
+       depends on BROKEN
        select IOMMU_API
        help
          Support for the IOMMUs found on certain Qualcomm SOCs.
index 7ce5273..dc14fec 100644 (file)
@@ -1186,8 +1186,15 @@ static const struct iommu_ops exynos_iommu_ops = {
 
 static int __init exynos_iommu_init(void)
 {
+       struct device_node *np;
        int ret;
 
+       np = of_find_matching_node(NULL, sysmmu_of_match);
+       if (!np)
+               return 0;
+
+       of_node_put(np);
+
        lv2table_kmem_cache = kmem_cache_create("exynos-iommu-lv2table",
                                LV2TABLE_SIZE, LV2TABLE_SIZE, 0, NULL);
        if (!lv2table_kmem_cache) {
index 5a500ed..b610a8d 100644 (file)
@@ -56,7 +56,8 @@
        ((((d)->levels - ((l) - ARM_LPAE_START_LVL(d) + 1))             \
          * (d)->bits_per_level) + (d)->pg_shift)
 
-#define ARM_LPAE_PAGES_PER_PGD(d)      ((d)->pgd_size >> (d)->pg_shift)
+#define ARM_LPAE_PAGES_PER_PGD(d)                                      \
+       DIV_ROUND_UP((d)->pgd_size, 1UL << (d)->pg_shift)
 
 /*
  * Calculate the index at level l used to map virtual address a using the
@@ -66,7 +67,7 @@
        ((l) == ARM_LPAE_START_LVL(d) ? ilog2(ARM_LPAE_PAGES_PER_PGD(d)) : 0)
 
 #define ARM_LPAE_LVL_IDX(a,l,d)                                                \
-       (((a) >> ARM_LPAE_LVL_SHIFT(l,d)) &                             \
+       (((u64)(a) >> ARM_LPAE_LVL_SHIFT(l,d)) &                        \
         ((1 << ((d)->bits_per_level + ARM_LPAE_PGD_IDX(l,d))) - 1))
 
 /* Calculate the block/page mapping size at level l for pagetable in d. */
index f59f857..a4ba851 100644 (file)
@@ -1376,6 +1376,13 @@ static int __init omap_iommu_init(void)
        struct kmem_cache *p;
        const unsigned long flags = SLAB_HWCACHE_ALIGN;
        size_t align = 1 << 10; /* L2 pagetable alignement */
+       struct device_node *np;
+
+       np = of_find_matching_node(NULL, omap_iommu_of_match);
+       if (!np)
+               return 0;
+
+       of_node_put(np);
 
        p = kmem_cache_create("iopte_cache", IOPTE_TABLE_SIZE, align, flags,
                              iopte_cachep_ctor);
index 6a8b1ec..9f74fdd 100644 (file)
@@ -1015,8 +1015,15 @@ static struct platform_driver rk_iommu_driver = {
 
 static int __init rk_iommu_init(void)
 {
+       struct device_node *np;
        int ret;
 
+       np = of_find_matching_node(NULL, rk_iommu_dt_ids);
+       if (!np)
+               return 0;
+
+       of_node_put(np);
+
        ret = bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
        if (ret)
                return ret;
index 463c235..4387dae 100644 (file)
@@ -69,6 +69,7 @@ static void __iomem *per_cpu_int_base;
 static void __iomem *main_int_base;
 static struct irq_domain *armada_370_xp_mpic_domain;
 static u32 doorbell_mask_reg;
+static int parent_irq;
 #ifdef CONFIG_PCI_MSI
 static struct irq_domain *armada_370_xp_msi_domain;
 static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR);
@@ -356,6 +357,7 @@ static int armada_xp_mpic_secondary_init(struct notifier_block *nfb,
 {
        if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
                armada_xp_mpic_smp_cpu_init();
+
        return NOTIFY_OK;
 }
 
@@ -364,6 +366,20 @@ static struct notifier_block armada_370_xp_mpic_cpu_notifier = {
        .priority = 100,
 };
 
+static int mpic_cascaded_secondary_init(struct notifier_block *nfb,
+                                       unsigned long action, void *hcpu)
+{
+       if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
+               enable_percpu_irq(parent_irq, IRQ_TYPE_NONE);
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block mpic_cascaded_cpu_notifier = {
+       .notifier_call = mpic_cascaded_secondary_init,
+       .priority = 100,
+};
+
 #endif /* CONFIG_SMP */
 
 static struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
@@ -539,7 +555,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
                                             struct device_node *parent)
 {
        struct resource main_int_res, per_cpu_int_res;
-       int parent_irq, nr_irqs, i;
+       int nr_irqs, i;
        u32 control;
 
        BUG_ON(of_address_to_resource(node, 0, &main_int_res));
@@ -587,6 +603,9 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
                register_cpu_notifier(&armada_370_xp_mpic_cpu_notifier);
 #endif
        } else {
+#ifdef CONFIG_SMP
+               register_cpu_notifier(&mpic_cascaded_cpu_notifier);
+#endif
                irq_set_chained_handler(parent_irq,
                                        armada_370_xp_mpic_handle_cascade_irq);
        }
index d8996bd..596b0a9 100644 (file)
@@ -416,13 +416,14 @@ static void its_send_single_command(struct its_node *its,
 {
        struct its_cmd_block *cmd, *sync_cmd, *next_cmd;
        struct its_collection *sync_col;
+       unsigned long flags;
 
-       raw_spin_lock(&its->lock);
+       raw_spin_lock_irqsave(&its->lock, flags);
 
        cmd = its_allocate_entry(its);
        if (!cmd) {             /* We're soooooo screewed... */
                pr_err_ratelimited("ITS can't allocate, dropping command\n");
-               raw_spin_unlock(&its->lock);
+               raw_spin_unlock_irqrestore(&its->lock, flags);
                return;
        }
        sync_col = builder(cmd, desc);
@@ -442,7 +443,7 @@ static void its_send_single_command(struct its_node *its,
 
 post:
        next_cmd = its_post_commands(its);
-       raw_spin_unlock(&its->lock);
+       raw_spin_unlock_irqrestore(&its->lock, flags);
 
        its_wait_for_range_completion(its, cmd, next_cmd);
 }
@@ -799,21 +800,43 @@ static int its_alloc_tables(struct its_node *its)
 {
        int err;
        int i;
-       int psz = PAGE_SIZE;
+       int psz = SZ_64K;
        u64 shr = GITS_BASER_InnerShareable;
 
        for (i = 0; i < GITS_BASER_NR_REGS; i++) {
                u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
                u64 type = GITS_BASER_TYPE(val);
                u64 entry_size = GITS_BASER_ENTRY_SIZE(val);
+               int order = get_order(psz);
+               int alloc_size;
                u64 tmp;
                void *base;
 
                if (type == GITS_BASER_TYPE_NONE)
                        continue;
 
-               /* We're lazy and only allocate a single page for now */
-               base = (void *)get_zeroed_page(GFP_KERNEL);
+               /*
+                * Allocate as many entries as required to fit the
+                * range of device IDs that the ITS can grok... The ID
+                * space being incredibly sparse, this results in a
+                * massive waste of memory.
+                *
+                * For other tables, only allocate a single page.
+                */
+               if (type == GITS_BASER_TYPE_DEVICE) {
+                       u64 typer = readq_relaxed(its->base + GITS_TYPER);
+                       u32 ids = GITS_TYPER_DEVBITS(typer);
+
+                       order = get_order((1UL << ids) * entry_size);
+                       if (order >= MAX_ORDER) {
+                               order = MAX_ORDER - 1;
+                               pr_warn("%s: Device Table too large, reduce its page order to %u\n",
+                                       its->msi_chip.of_node->full_name, order);
+                       }
+               }
+
+               alloc_size = (1 << order) * PAGE_SIZE;
+               base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
                if (!base) {
                        err = -ENOMEM;
                        goto out_free;
@@ -841,7 +864,7 @@ retry_baser:
                        break;
                }
 
-               val |= (PAGE_SIZE / psz) - 1;
+               val |= (alloc_size / psz) - 1;
 
                writeq_relaxed(val, its->base + GITS_BASER + i * 8);
                tmp = readq_relaxed(its->base + GITS_BASER + i * 8);
@@ -882,7 +905,7 @@ retry_baser:
                }
 
                pr_info("ITS: allocated %d %s @%lx (psz %dK, shr %d)\n",
-                       (int)(PAGE_SIZE / entry_size),
+                       (int)(alloc_size / entry_size),
                        its_base_type_string[type],
                        (unsigned long)virt_to_phys(base),
                        psz / SZ_1K, (int)shr >> GITS_BASER_SHAREABILITY_SHIFT);
@@ -1020,8 +1043,9 @@ static void its_cpu_init_collection(void)
 static struct its_device *its_find_device(struct its_node *its, u32 dev_id)
 {
        struct its_device *its_dev = NULL, *tmp;
+       unsigned long flags;
 
-       raw_spin_lock(&its->lock);
+       raw_spin_lock_irqsave(&its->lock, flags);
 
        list_for_each_entry(tmp, &its->its_device_list, entry) {
                if (tmp->device_id == dev_id) {
@@ -1030,7 +1054,7 @@ static struct its_device *its_find_device(struct its_node *its, u32 dev_id)
                }
        }
 
-       raw_spin_unlock(&its->lock);
+       raw_spin_unlock_irqrestore(&its->lock, flags);
 
        return its_dev;
 }
@@ -1040,6 +1064,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
 {
        struct its_device *dev;
        unsigned long *lpi_map;
+       unsigned long flags;
        void *itt;
        int lpi_base;
        int nr_lpis;
@@ -1056,7 +1081,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
        nr_ites = max(2UL, roundup_pow_of_two(nvecs));
        sz = nr_ites * its->ite_size;
        sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
-       itt = kmalloc(sz, GFP_KERNEL);
+       itt = kzalloc(sz, GFP_KERNEL);
        lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis);
 
        if (!dev || !itt || !lpi_map) {
@@ -1075,9 +1100,9 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
        dev->device_id = dev_id;
        INIT_LIST_HEAD(&dev->entry);
 
-       raw_spin_lock(&its->lock);
+       raw_spin_lock_irqsave(&its->lock, flags);
        list_add(&dev->entry, &its->its_device_list);
-       raw_spin_unlock(&its->lock);
+       raw_spin_unlock_irqrestore(&its->lock, flags);
 
        /* Bind the device to the first possible CPU */
        cpu = cpumask_first(cpu_online_mask);
@@ -1091,9 +1116,11 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
 
 static void its_free_device(struct its_device *its_dev)
 {
-       raw_spin_lock(&its_dev->its->lock);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&its_dev->its->lock, flags);
        list_del(&its_dev->entry);
-       raw_spin_unlock(&its_dev->its->lock);
+       raw_spin_unlock_irqrestore(&its_dev->its->lock, flags);
        kfree(its_dev->itt);
        kfree(its_dev);
 }
@@ -1112,31 +1139,69 @@ static int its_alloc_device_irq(struct its_device *dev, irq_hw_number_t *hwirq)
        return 0;
 }
 
+struct its_pci_alias {
+       struct pci_dev  *pdev;
+       u32             dev_id;
+       u32             count;
+};
+
+static int its_pci_msi_vec_count(struct pci_dev *pdev)
+{
+       int msi, msix;
+
+       msi = max(pci_msi_vec_count(pdev), 0);
+       msix = max(pci_msix_vec_count(pdev), 0);
+
+       return max(msi, msix);
+}
+
+static int its_get_pci_alias(struct pci_dev *pdev, u16 alias, void *data)
+{
+       struct its_pci_alias *dev_alias = data;
+
+       dev_alias->dev_id = alias;
+       if (pdev != dev_alias->pdev)
+               dev_alias->count += its_pci_msi_vec_count(dev_alias->pdev);
+
+       return 0;
+}
+
 static int its_msi_prepare(struct irq_domain *domain, struct device *dev,
                           int nvec, msi_alloc_info_t *info)
 {
        struct pci_dev *pdev;
        struct its_node *its;
-       u32 dev_id;
        struct its_device *its_dev;
+       struct its_pci_alias dev_alias;
 
        if (!dev_is_pci(dev))
                return -EINVAL;
 
        pdev = to_pci_dev(dev);
-       dev_id = PCI_DEVID(pdev->bus->number, pdev->devfn);
+       dev_alias.pdev = pdev;
+       dev_alias.count = nvec;
+
+       pci_for_each_dma_alias(pdev, its_get_pci_alias, &dev_alias);
        its = domain->parent->host_data;
 
-       its_dev = its_find_device(its, dev_id);
-       if (WARN_ON(its_dev))
-               return -EINVAL;
+       its_dev = its_find_device(its, dev_alias.dev_id);
+       if (its_dev) {
+               /*
+                * We already have seen this ID, probably through
+                * another alias (PCI bridge of some sort). No need to
+                * create the device.
+                */
+               dev_dbg(dev, "Reusing ITT for devID %x\n", dev_alias.dev_id);
+               goto out;
+       }
 
-       its_dev = its_create_device(its, dev_id, nvec);
+       its_dev = its_create_device(its, dev_alias.dev_id, dev_alias.count);
        if (!its_dev)
                return -ENOMEM;
 
-       dev_dbg(&pdev->dev, "ITT %d entries, %d bits\n", nvec, ilog2(nvec));
-
+       dev_dbg(&pdev->dev, "ITT %d entries, %d bits\n",
+               dev_alias.count, ilog2(dev_alias.count));
+out:
        info->scratchpad[0].ptr = its_dev;
        info->scratchpad[1].ptr = dev;
        return 0;
@@ -1255,6 +1320,34 @@ static const struct irq_domain_ops its_domain_ops = {
        .deactivate             = its_irq_domain_deactivate,
 };
 
+static int its_force_quiescent(void __iomem *base)
+{
+       u32 count = 1000000;    /* 1s */
+       u32 val;
+
+       val = readl_relaxed(base + GITS_CTLR);
+       if (val & GITS_CTLR_QUIESCENT)
+               return 0;
+
+       /* Disable the generation of all interrupts to this ITS */
+       val &= ~GITS_CTLR_ENABLE;
+       writel_relaxed(val, base + GITS_CTLR);
+
+       /* Poll GITS_CTLR and wait until ITS becomes quiescent */
+       while (1) {
+               val = readl_relaxed(base + GITS_CTLR);
+               if (val & GITS_CTLR_QUIESCENT)
+                       return 0;
+
+               count--;
+               if (!count)
+                       return -EBUSY;
+
+               cpu_relax();
+               udelay(1);
+       }
+}
+
 static int its_probe(struct device_node *node, struct irq_domain *parent)
 {
        struct resource res;
@@ -1283,6 +1376,13 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
                goto out_unmap;
        }
 
+       err = its_force_quiescent(its_base);
+       if (err) {
+               pr_warn("%s: failed to quiesce, giving up\n",
+                       node->full_name);
+               goto out_unmap;
+       }
+
        pr_info("ITS: %s\n", node->full_name);
 
        its = kzalloc(sizeof(*its), GFP_KERNEL);
@@ -1323,7 +1423,7 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
        writeq_relaxed(baser, its->base + GITS_CBASER);
        tmp = readq_relaxed(its->base + GITS_CBASER);
        writeq_relaxed(0, its->base + GITS_CWRITER);
-       writel_relaxed(1, its->base + GITS_CTLR);
+       writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
 
        if ((tmp ^ baser) & GITS_BASER_SHAREABILITY_MASK) {
                pr_info("ITS: using cache flushing for cmd queue\n");
@@ -1382,12 +1482,11 @@ static bool gic_rdists_supports_plpis(void)
 
 int its_cpu_init(void)
 {
-       if (!gic_rdists_supports_plpis()) {
-               pr_info("CPU%d: LPIs not supported\n", smp_processor_id());
-               return -ENXIO;
-       }
-
        if (!list_empty(&its_nodes)) {
+               if (!gic_rdists_supports_plpis()) {
+                       pr_info("CPU%d: LPIs not supported\n", smp_processor_id());
+                       return -ENXIO;
+               }
                its_cpu_init_lpis();
                its_cpu_init_collection();
        }
index 1c6dea2..fd8850d 100644 (file)
@@ -466,7 +466,7 @@ static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask,
                tlist |= 1 << (mpidr & 0xf);
 
                cpu = cpumask_next(cpu, mask);
-               if (cpu == nr_cpu_ids)
+               if (cpu >= nr_cpu_ids)
                        goto out;
 
                mpidr = cpu_logical_map(cpu);
index 4634cf7..471e1cd 100644 (file)
@@ -154,23 +154,25 @@ static inline unsigned int gic_irq(struct irq_data *d)
 static void gic_mask_irq(struct irq_data *d)
 {
        u32 mask = 1 << (gic_irq(d) % 32);
+       unsigned long flags;
 
-       raw_spin_lock(&irq_controller_lock);
+       raw_spin_lock_irqsave(&irq_controller_lock, flags);
        writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4);
        if (gic_arch_extn.irq_mask)
                gic_arch_extn.irq_mask(d);
-       raw_spin_unlock(&irq_controller_lock);
+       raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
 
 static void gic_unmask_irq(struct irq_data *d)
 {
        u32 mask = 1 << (gic_irq(d) % 32);
+       unsigned long flags;
 
-       raw_spin_lock(&irq_controller_lock);
+       raw_spin_lock_irqsave(&irq_controller_lock, flags);
        if (gic_arch_extn.irq_unmask)
                gic_arch_extn.irq_unmask(d);
        writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
-       raw_spin_unlock(&irq_controller_lock);
+       raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
 
 static void gic_eoi_irq(struct irq_data *d)
@@ -188,6 +190,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 {
        void __iomem *base = gic_dist_base(d);
        unsigned int gicirq = gic_irq(d);
+       unsigned long flags;
        int ret;
 
        /* Interrupt configuration for SGIs can't be changed */
@@ -199,14 +202,14 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
                            type != IRQ_TYPE_EDGE_RISING)
                return -EINVAL;
 
-       raw_spin_lock(&irq_controller_lock);
+       raw_spin_lock_irqsave(&irq_controller_lock, flags);
 
        if (gic_arch_extn.irq_set_type)
                gic_arch_extn.irq_set_type(d, type);
 
        ret = gic_configure_irq(gicirq, type, base, NULL);
 
-       raw_spin_unlock(&irq_controller_lock);
+       raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
 
        return ret;
 }
@@ -227,6 +230,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
        void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
        unsigned int cpu, shift = (gic_irq(d) % 4) * 8;
        u32 val, mask, bit;
+       unsigned long flags;
 
        if (!force)
                cpu = cpumask_any_and(mask_val, cpu_online_mask);
@@ -236,12 +240,12 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
        if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
                return -EINVAL;
 
-       raw_spin_lock(&irq_controller_lock);
+       raw_spin_lock_irqsave(&irq_controller_lock, flags);
        mask = 0xff << shift;
        bit = gic_cpu_map[cpu] << shift;
        val = readl_relaxed(reg) & ~mask;
        writel_relaxed(val | bit, reg);
-       raw_spin_unlock(&irq_controller_lock);
+       raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
 
        return IRQ_SET_MASK_OK;
 }
index 5b76a17..5897d8d 100644 (file)
@@ -526,6 +526,7 @@ config MTD_NAND_SUNXI
 
 config MTD_NAND_HISI504
        tristate "Support for NAND controller on Hisilicon SoC Hip04"
+       depends on HAS_DMA
        help
          Enables support for NAND controller on Hisilicon SoC Hip04.
 
index 96b0b1d..10b1f7a 100644 (file)
@@ -480,6 +480,42 @@ static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
        nand_writel(info, NDCR, ndcr | int_mask);
 }
 
+static void drain_fifo(struct pxa3xx_nand_info *info, void *data, int len)
+{
+       if (info->ecc_bch) {
+               int timeout;
+
+               /*
+                * According to the datasheet, when reading from NDDB
+                * with BCH enabled, after each 32 bytes reads, we
+                * have to make sure that the NDSR.RDDREQ bit is set.
+                *
+                * Drain the FIFO 8 32 bits reads at a time, and skip
+                * the polling on the last read.
+                */
+               while (len > 8) {
+                       __raw_readsl(info->mmio_base + NDDB, data, 8);
+
+                       for (timeout = 0;
+                            !(nand_readl(info, NDSR) & NDSR_RDDREQ);
+                            timeout++) {
+                               if (timeout >= 5) {
+                                       dev_err(&info->pdev->dev,
+                                               "Timeout on RDDREQ while draining the FIFO\n");
+                                       return;
+                               }
+
+                               mdelay(1);
+                       }
+
+                       data += 32;
+                       len -= 8;
+               }
+       }
+
+       __raw_readsl(info->mmio_base + NDDB, data, len);
+}
+
 static void handle_data_pio(struct pxa3xx_nand_info *info)
 {
        unsigned int do_bytes = min(info->data_size, info->chunk_size);
@@ -496,14 +532,14 @@ static void handle_data_pio(struct pxa3xx_nand_info *info)
                                      DIV_ROUND_UP(info->oob_size, 4));
                break;
        case STATE_PIO_READING:
-               __raw_readsl(info->mmio_base + NDDB,
-                            info->data_buff + info->data_buff_pos,
-                            DIV_ROUND_UP(do_bytes, 4));
+               drain_fifo(info,
+                          info->data_buff + info->data_buff_pos,
+                          DIV_ROUND_UP(do_bytes, 4));
 
                if (info->oob_size > 0)
-                       __raw_readsl(info->mmio_base + NDDB,
-                                    info->oob_buff + info->oob_buff_pos,
-                                    DIV_ROUND_UP(info->oob_size, 4));
+                       drain_fifo(info,
+                                  info->oob_buff + info->oob_buff_pos,
+                                  DIV_ROUND_UP(info->oob_size, 4));
                break;
        default:
                dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
@@ -1572,6 +1608,8 @@ static int alloc_nand_resource(struct platform_device *pdev)
        int ret, irq, cs;
 
        pdata = dev_get_platdata(&pdev->dev);
+       if (pdata->num_cs <= 0)
+               return -ENODEV;
        info = devm_kzalloc(&pdev->dev, sizeof(*info) + (sizeof(*mtd) +
                            sizeof(*host)) * pdata->num_cs, GFP_KERNEL);
        if (!info)
index 38d1c51..7bcaeec 100644 (file)
@@ -84,8 +84,7 @@ config OF_RESOLVE
        bool
 
 config OF_OVERLAY
-       bool
-       depends on OF
+       bool "Device Tree overlays"
        select OF_DYNAMIC
        select OF_RESOLVE
 
index 0a8aeb8..adb8764 100644 (file)
@@ -714,16 +714,17 @@ static struct device_node *__of_find_node_by_path(struct device_node *parent,
                                                const char *path)
 {
        struct device_node *child;
-       int len = strchrnul(path, '/') - path;
-       int term;
+       int len;
+       const char *end;
 
+       end = strchr(path, ':');
+       if (!end)
+               end = strchrnul(path, '/');
+
+       len = end - path;
        if (!len)
                return NULL;
 
-       term = strchrnul(path, ':') - path;
-       if (term < len)
-               len = term;
-
        __for_each_child_of_node(parent, child) {
                const char *name = strrchr(child->full_name, '/');
                if (WARN(!name, "malformed device_node %s\n", child->full_name))
@@ -768,8 +769,12 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt
 
        /* The path could begin with an alias */
        if (*path != '/') {
-               char *p = strchrnul(path, '/');
-               int len = separator ? separator - path : p - path;
+               int len;
+               const char *p = separator;
+
+               if (!p)
+                       p = strchrnul(path, '/');
+               len = p - path;
 
                /* of_aliases must not be NULL */
                if (!of_aliases)
@@ -794,6 +799,8 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt
                path++; /* Increment past '/' delimiter */
                np = __of_find_node_by_path(np, path);
                path = strchrnul(path, '/');
+               if (separator && separator < path)
+                       break;
        }
        raw_spin_unlock_irqrestore(&devtree_lock, flags);
        return np;
@@ -1886,8 +1893,10 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
                        name = of_get_property(of_chosen, "linux,stdout-path", NULL);
                if (IS_ENABLED(CONFIG_PPC) && !name)
                        name = of_get_property(of_aliases, "stdout", NULL);
-               if (name)
+               if (name) {
                        of_stdout = of_find_node_opts_by_path(name, &of_stdout_options);
+                       add_preferred_console("stdout-path", 0, NULL);
+               }
        }
 
        if (!of_aliases)
index 352b4f2..dee9270 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/idr.h>
 
 #include "of_private.h"
 
@@ -85,7 +86,7 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov,
                struct device_node *target, struct device_node *child)
 {
        const char *cname;
-       struct device_node *tchild, *grandchild;
+       struct device_node *tchild;
        int ret = 0;
 
        cname = kbasename(child->full_name);
index 0cf9a23..aba8946 100644 (file)
@@ -92,6 +92,11 @@ static void __init of_selftest_find_node_by_name(void)
                 "option path test failed\n");
        of_node_put(np);
 
+       np = of_find_node_opts_by_path("/testcase-data:test/option", &options);
+       selftest(np && !strcmp("test/option", options),
+                "option path test, subcase #1 failed\n");
+       of_node_put(np);
+
        np = of_find_node_opts_by_path("/testcase-data:testoption", NULL);
        selftest(np, "NULL option path test failed\n");
        of_node_put(np);
@@ -102,6 +107,12 @@ static void __init of_selftest_find_node_by_name(void)
                 "option alias path test failed\n");
        of_node_put(np);
 
+       np = of_find_node_opts_by_path("testcase-alias:test/alias/option",
+                                      &options);
+       selftest(np && !strcmp("test/alias/option", options),
+                "option alias path test, subcase #1 failed\n");
+       of_node_put(np);
+
        np = of_find_node_opts_by_path("testcase-alias:testaliasoption", NULL);
        selftest(np, "NULL option alias path test failed\n");
        of_node_put(np);
@@ -378,9 +389,9 @@ static void __init of_selftest_property_string(void)
        rc = of_property_match_string(np, "phandle-list-names", "first");
        selftest(rc == 0, "first expected:0 got:%i\n", rc);
        rc = of_property_match_string(np, "phandle-list-names", "second");
-       selftest(rc == 1, "second expected:0 got:%i\n", rc);
+       selftest(rc == 1, "second expected:1 got:%i\n", rc);
        rc = of_property_match_string(np, "phandle-list-names", "third");
-       selftest(rc == 2, "third expected:0 got:%i\n", rc);
+       selftest(rc == 2, "third expected:2 got:%i\n", rc);
        rc = of_property_match_string(np, "phandle-list-names", "fourth");
        selftest(rc == -ENODATA, "unmatched string; rc=%i\n", rc);
        rc = of_property_match_string(np, "missing-property", "blah");
@@ -478,7 +489,6 @@ static void __init of_selftest_changeset(void)
        struct device_node *n1, *n2, *n21, *nremove, *parent, *np;
        struct of_changeset chgset;
 
-       of_changeset_init(&chgset);
        n1 = __of_node_dup(NULL, "/testcase-data/changeset/n1");
        selftest(n1, "testcase setup failure\n");
        n2 = __of_node_dup(NULL, "/testcase-data/changeset/n2");
@@ -979,7 +989,7 @@ static int of_path_platform_device_exists(const char *path)
        return pdev != NULL;
 }
 
-#if IS_ENABLED(CONFIG_I2C)
+#if IS_BUILTIN(CONFIG_I2C)
 
 /* get the i2c client device instantiated at the path */
 static struct i2c_client *of_path_to_i2c_client(const char *path)
@@ -1445,7 +1455,7 @@ static void of_selftest_overlay_11(void)
                return;
 }
 
-#if IS_ENABLED(CONFIG_I2C) && IS_ENABLED(CONFIG_OF_OVERLAY)
+#if IS_BUILTIN(CONFIG_I2C) && IS_ENABLED(CONFIG_OF_OVERLAY)
 
 struct selftest_i2c_bus_data {
        struct platform_device  *pdev;
@@ -1584,7 +1594,7 @@ static struct i2c_driver selftest_i2c_dev_driver = {
        .id_table = selftest_i2c_dev_id,
 };
 
-#if IS_ENABLED(CONFIG_I2C_MUX)
+#if IS_BUILTIN(CONFIG_I2C_MUX)
 
 struct selftest_i2c_mux_data {
        int nchans;
@@ -1695,7 +1705,7 @@ static int of_selftest_overlay_i2c_init(void)
                        "could not register selftest i2c bus driver\n"))
                return ret;
 
-#if IS_ENABLED(CONFIG_I2C_MUX)
+#if IS_BUILTIN(CONFIG_I2C_MUX)
        ret = i2c_add_driver(&selftest_i2c_mux_driver);
        if (selftest(ret == 0,
                        "could not register selftest i2c mux driver\n"))
@@ -1707,7 +1717,7 @@ static int of_selftest_overlay_i2c_init(void)
 
 static void of_selftest_overlay_i2c_cleanup(void)
 {
-#if IS_ENABLED(CONFIG_I2C_MUX)
+#if IS_BUILTIN(CONFIG_I2C_MUX)
        i2c_del_driver(&selftest_i2c_mux_driver);
 #endif
        platform_driver_unregister(&selftest_i2c_bus_driver);
@@ -1814,7 +1824,7 @@ static void __init of_selftest_overlay(void)
        of_selftest_overlay_10();
        of_selftest_overlay_11();
 
-#if IS_ENABLED(CONFIG_I2C)
+#if IS_BUILTIN(CONFIG_I2C)
        if (selftest(of_selftest_overlay_i2c_init() == 0, "i2c init failed\n"))
                goto out;
 
index aab5547..ee082c0 100644 (file)
@@ -127,7 +127,7 @@ static bool xgene_pcie_hide_rc_bars(struct pci_bus *bus, int offset)
        return false;
 }
 
-static int xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
+static void __iomem *xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
                              int offset)
 {
        struct xgene_pcie_port *port = bus->sysdata;
@@ -137,7 +137,7 @@ static int xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
                return NULL;
 
        xgene_pcie_set_rtdid_reg(bus, devfn);
-       return xgene_pcie_get_cfg_base(bus);
+       return xgene_pcie_get_cfg_base(bus) + offset;
 }
 
 static struct pci_ops xgene_pcie_ops = {
index aa012fb..312f23a 100644 (file)
@@ -521,7 +521,8 @@ static ssize_t driver_override_store(struct device *dev,
        struct pci_dev *pdev = to_pci_dev(dev);
        char *driver_override, *old = pdev->driver_override, *cp;
 
-       if (count > PATH_MAX)
+       /* We need to keep extra room for a newline */
+       if (count >= (PAGE_SIZE - 1))
                return -EINVAL;
 
        driver_override = kstrndup(buf, count, GFP_KERNEL);
@@ -549,7 +550,7 @@ static ssize_t driver_override_show(struct device *dev,
 {
        struct pci_dev *pdev = to_pci_dev(dev);
 
-       return sprintf(buf, "%s\n", pdev->driver_override);
+       return snprintf(buf, PAGE_SIZE, "%s\n", pdev->driver_override);
 }
 static DEVICE_ATTR_RW(driver_override);
 
index 1245dca..a4a8a6d 100644 (file)
@@ -1839,10 +1839,12 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
        }
 
        if (rdev->ena_pin) {
-               ret = regulator_ena_gpio_ctrl(rdev, true);
-               if (ret < 0)
-                       return ret;
-               rdev->ena_gpio_state = 1;
+               if (!rdev->ena_gpio_state) {
+                       ret = regulator_ena_gpio_ctrl(rdev, true);
+                       if (ret < 0)
+                               return ret;
+                       rdev->ena_gpio_state = 1;
+               }
        } else if (rdev->desc->ops->enable) {
                ret = rdev->desc->ops->enable(rdev);
                if (ret < 0)
@@ -1939,10 +1941,12 @@ static int _regulator_do_disable(struct regulator_dev *rdev)
        trace_regulator_disable(rdev_get_name(rdev));
 
        if (rdev->ena_pin) {
-               ret = regulator_ena_gpio_ctrl(rdev, false);
-               if (ret < 0)
-                       return ret;
-               rdev->ena_gpio_state = 0;
+               if (rdev->ena_gpio_state) {
+                       ret = regulator_ena_gpio_ctrl(rdev, false);
+                       if (ret < 0)
+                               return ret;
+                       rdev->ena_gpio_state = 0;
+               }
 
        } else if (rdev->desc->ops->disable) {
                ret = rdev->desc->ops->disable(rdev);
@@ -3626,12 +3630,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
                                 config->ena_gpio, ret);
                        goto wash;
                }
-
-               if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH)
-                       rdev->ena_gpio_state = 1;
-
-               if (config->ena_gpio_invert)
-                       rdev->ena_gpio_state = !rdev->ena_gpio_state;
        }
 
        /* set regulator constraints */
@@ -3800,9 +3798,11 @@ int regulator_suspend_finish(void)
        list_for_each_entry(rdev, &regulator_list, list) {
                mutex_lock(&rdev->mutex);
                if (rdev->use_count > 0  || rdev->constraints->always_on) {
-                       error = _regulator_do_enable(rdev);
-                       if (error)
-                               ret = error;
+                       if (!_regulator_is_enabled(rdev)) {
+                               error = _regulator_do_enable(rdev);
+                               if (error)
+                                       ret = error;
+                       }
                } else {
                        if (!have_full_constraints())
                                goto unlock;
index e2cffe0..fb991ec 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
index 92f6af6..73354ee 100644 (file)
@@ -951,6 +951,7 @@ static int rpmsg_probe(struct virtio_device *vdev)
        void *bufs_va;
        int err = 0, i;
        size_t total_buf_space;
+       bool notify;
 
        vrp = kzalloc(sizeof(*vrp), GFP_KERNEL);
        if (!vrp)
@@ -1030,8 +1031,22 @@ static int rpmsg_probe(struct virtio_device *vdev)
                }
        }
 
+       /*
+        * Prepare to kick but don't notify yet - we can't do this before
+        * device is ready.
+        */
+       notify = virtqueue_kick_prepare(vrp->rvq);
+
+       /* From this point on, we can notify and get callbacks. */
+       virtio_device_ready(vdev);
+
        /* tell the remote processor it can start sending messages */
-       virtqueue_kick(vrp->rvq);
+       /*
+        * this might be concurrent with callbacks, but we are only
+        * doing notify, not a full kick here, so that's ok.
+        */
+       if (notify)
+               virtqueue_notify(vrp->rvq);
 
        dev_info(&vdev->dev, "rpmsg host is online\n");
 
index 4241eea..f4cf685 100644 (file)
@@ -849,6 +849,7 @@ static struct s3c_rtc_data const s3c2443_rtc_data = {
 
 static struct s3c_rtc_data const s3c6410_rtc_data = {
        .max_user_freq          = 32768,
+       .needs_src_clk          = true,
        .irq_handler            = s3c6410_rtc_irq,
        .set_freq               = s3c6410_rtc_setfreq,
        .enable_tick            = s3c6410_rtc_enable_tick,
index 62b58d3..60de662 100644 (file)
@@ -500,6 +500,7 @@ static void sas_revalidate_domain(struct work_struct *work)
        struct sas_discovery_event *ev = to_sas_discovery_event(work);
        struct asd_sas_port *port = ev->port;
        struct sas_ha_struct *ha = port->ha;
+       struct domain_device *ddev = port->port_dev;
 
        /* prevent revalidation from finding sata links in recovery */
        mutex_lock(&ha->disco_mutex);
@@ -514,8 +515,9 @@ static void sas_revalidate_domain(struct work_struct *work)
        SAS_DPRINTK("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id,
                    task_pid_nr(current));
 
-       if (port->port_dev)
-               res = sas_ex_revalidate_domain(port->port_dev);
+       if (ddev && (ddev->dev_type == SAS_FANOUT_EXPANDER_DEVICE ||
+                    ddev->dev_type == SAS_EDGE_EXPANDER_DEVICE))
+               res = sas_ex_revalidate_domain(ddev);
 
        SAS_DPRINTK("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n",
                    port->id, task_pid_nr(current), res);
index af98b09..175c995 100644 (file)
@@ -144,10 +144,9 @@ struct ffs_io_data {
        bool read;
 
        struct kiocb *kiocb;
-       const struct iovec *iovec;
-       unsigned long nr_segs;
-       char __user *buf;
-       size_t len;
+       struct iov_iter data;
+       const void *to_free;
+       char *buf;
 
        struct mm_struct *mm;
        struct work_struct work;
@@ -649,29 +648,10 @@ static void ffs_user_copy_worker(struct work_struct *work)
                                         io_data->req->actual;
 
        if (io_data->read && ret > 0) {
-               int i;
-               size_t pos = 0;
-
-               /*
-                * Since req->length may be bigger than io_data->len (after
-                * being rounded up to maxpacketsize), we may end up with more
-                * data then user space has space for.
-                */
-               ret = min_t(int, ret, io_data->len);
-
                use_mm(io_data->mm);
-               for (i = 0; i < io_data->nr_segs; i++) {
-                       size_t len = min_t(size_t, ret - pos,
-                                       io_data->iovec[i].iov_len);
-                       if (!len)
-                               break;
-                       if (unlikely(copy_to_user(io_data->iovec[i].iov_base,
-                                                &io_data->buf[pos], len))) {
-                               ret = -EFAULT;
-                               break;
-                       }
-                       pos += len;
-               }
+               ret = copy_to_iter(io_data->buf, ret, &io_data->data);
+               if (iov_iter_count(&io_data->data))
+                       ret = -EFAULT;
                unuse_mm(io_data->mm);
        }
 
@@ -684,7 +664,7 @@ static void ffs_user_copy_worker(struct work_struct *work)
 
        io_data->kiocb->private = NULL;
        if (io_data->read)
-               kfree(io_data->iovec);
+               kfree(io_data->to_free);
        kfree(io_data->buf);
        kfree(io_data);
 }
@@ -743,6 +723,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
                 * before the waiting completes, so do not assign to 'gadget' earlier
                 */
                struct usb_gadget *gadget = epfile->ffs->gadget;
+               size_t copied;
 
                spin_lock_irq(&epfile->ffs->eps_lock);
                /* In the meantime, endpoint got disabled or changed. */
@@ -750,34 +731,21 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
                        spin_unlock_irq(&epfile->ffs->eps_lock);
                        return -ESHUTDOWN;
                }
+               data_len = iov_iter_count(&io_data->data);
                /*
                 * Controller may require buffer size to be aligned to
                 * maxpacketsize of an out endpoint.
                 */
-               data_len = io_data->read ?
-                          usb_ep_align_maybe(gadget, ep->ep, io_data->len) :
-                          io_data->len;
+               if (io_data->read)
+                       data_len = usb_ep_align_maybe(gadget, ep->ep, data_len);
                spin_unlock_irq(&epfile->ffs->eps_lock);
 
                data = kmalloc(data_len, GFP_KERNEL);
                if (unlikely(!data))
                        return -ENOMEM;
-               if (io_data->aio && !io_data->read) {
-                       int i;
-                       size_t pos = 0;
-                       for (i = 0; i < io_data->nr_segs; i++) {
-                               if (unlikely(copy_from_user(&data[pos],
-                                            io_data->iovec[i].iov_base,
-                                            io_data->iovec[i].iov_len))) {
-                                       ret = -EFAULT;
-                                       goto error;
-                               }
-                               pos += io_data->iovec[i].iov_len;
-                       }
-               } else {
-                       if (!io_data->read &&
-                           unlikely(__copy_from_user(data, io_data->buf,
-                                                     io_data->len))) {
+               if (!io_data->read) {
+                       copied = copy_from_iter(data, data_len, &io_data->data);
+                       if (copied != data_len) {
                                ret = -EFAULT;
                                goto error;
                        }
@@ -876,10 +844,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
                                 */
                                ret = ep->status;
                                if (io_data->read && ret > 0) {
-                                       ret = min_t(size_t, ret, io_data->len);
-
-                                       if (unlikely(copy_to_user(io_data->buf,
-                                               data, ret)))
+                                       ret = copy_to_iter(data, ret, &io_data->data);
+                                       if (unlikely(iov_iter_count(&io_data->data)))
                                                ret = -EFAULT;
                                }
                        }
@@ -898,37 +864,6 @@ error:
        return ret;
 }
 
-static ssize_t
-ffs_epfile_write(struct file *file, const char __user *buf, size_t len,
-                loff_t *ptr)
-{
-       struct ffs_io_data io_data;
-
-       ENTER();
-
-       io_data.aio = false;
-       io_data.read = false;
-       io_data.buf = (char * __user)buf;
-       io_data.len = len;
-
-       return ffs_epfile_io(file, &io_data);
-}
-
-static ssize_t
-ffs_epfile_read(struct file *file, char __user *buf, size_t len, loff_t *ptr)
-{
-       struct ffs_io_data io_data;
-
-       ENTER();
-
-       io_data.aio = false;
-       io_data.read = true;
-       io_data.buf = buf;
-       io_data.len = len;
-
-       return ffs_epfile_io(file, &io_data);
-}
-
 static int
 ffs_epfile_open(struct inode *inode, struct file *file)
 {
@@ -965,67 +900,86 @@ static int ffs_aio_cancel(struct kiocb *kiocb)
        return value;
 }
 
-static ssize_t ffs_epfile_aio_write(struct kiocb *kiocb,
-                                   const struct iovec *iovec,
-                                   unsigned long nr_segs, loff_t loff)
+static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from)
 {
-       struct ffs_io_data *io_data;
+       struct ffs_io_data io_data, *p = &io_data;
+       ssize_t res;
 
        ENTER();
 
-       io_data = kmalloc(sizeof(*io_data), GFP_KERNEL);
-       if (unlikely(!io_data))
-               return -ENOMEM;
+       if (!is_sync_kiocb(kiocb)) {
+               p = kmalloc(sizeof(io_data), GFP_KERNEL);
+               if (unlikely(!p))
+                       return -ENOMEM;
+               p->aio = true;
+       } else {
+               p->aio = false;
+       }
 
-       io_data->aio = true;
-       io_data->read = false;
-       io_data->kiocb = kiocb;
-       io_data->iovec = iovec;
-       io_data->nr_segs = nr_segs;
-       io_data->len = kiocb->ki_nbytes;
-       io_data->mm = current->mm;
+       p->read = false;
+       p->kiocb = kiocb;
+       p->data = *from;
+       p->mm = current->mm;
 
-       kiocb->private = io_data;
+       kiocb->private = p;
 
        kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
 
-       return ffs_epfile_io(kiocb->ki_filp, io_data);
+       res = ffs_epfile_io(kiocb->ki_filp, p);
+       if (res == -EIOCBQUEUED)
+               return res;
+       if (p->aio)
+               kfree(p);
+       else
+               *from = p->data;
+       return res;
 }
 
-static ssize_t ffs_epfile_aio_read(struct kiocb *kiocb,
-                                  const struct iovec *iovec,
-                                  unsigned long nr_segs, loff_t loff)
+static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to)
 {
-       struct ffs_io_data *io_data;
-       struct iovec *iovec_copy;
+       struct ffs_io_data io_data, *p = &io_data;
+       ssize_t res;
 
        ENTER();
 
-       iovec_copy = kmalloc_array(nr_segs, sizeof(*iovec_copy), GFP_KERNEL);
-       if (unlikely(!iovec_copy))
-               return -ENOMEM;
-
-       memcpy(iovec_copy, iovec, sizeof(struct iovec)*nr_segs);
-
-       io_data = kmalloc(sizeof(*io_data), GFP_KERNEL);
-       if (unlikely(!io_data)) {
-               kfree(iovec_copy);
-               return -ENOMEM;
+       if (!is_sync_kiocb(kiocb)) {
+               p = kmalloc(sizeof(io_data), GFP_KERNEL);
+               if (unlikely(!p))
+                       return -ENOMEM;
+               p->aio = true;
+       } else {
+               p->aio = false;
        }
 
-       io_data->aio = true;
-       io_data->read = true;
-       io_data->kiocb = kiocb;
-       io_data->iovec = iovec_copy;
-       io_data->nr_segs = nr_segs;
-       io_data->len = kiocb->ki_nbytes;
-       io_data->mm = current->mm;
+       p->read = true;
+       p->kiocb = kiocb;
+       if (p->aio) {
+               p->to_free = dup_iter(&p->data, to, GFP_KERNEL);
+               if (!p->to_free) {
+                       kfree(p);
+                       return -ENOMEM;
+               }
+       } else {
+               p->data = *to;
+               p->to_free = NULL;
+       }
+       p->mm = current->mm;
 
-       kiocb->private = io_data;
+       kiocb->private = p;
 
        kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
 
-       return ffs_epfile_io(kiocb->ki_filp, io_data);
+       res = ffs_epfile_io(kiocb->ki_filp, p);
+       if (res == -EIOCBQUEUED)
+               return res;
+
+       if (p->aio) {
+               kfree(p->to_free);
+               kfree(p);
+       } else {
+               *to = p->data;
+       }
+       return res;
 }
 
 static int
@@ -1105,10 +1059,10 @@ static const struct file_operations ffs_epfile_operations = {
        .llseek =       no_llseek,
 
        .open =         ffs_epfile_open,
-       .write =        ffs_epfile_write,
-       .read =         ffs_epfile_read,
-       .aio_write =    ffs_epfile_aio_write,
-       .aio_read =     ffs_epfile_aio_read,
+       .write =        new_sync_write,
+       .read =         new_sync_read,
+       .write_iter =   ffs_epfile_write_iter,
+       .read_iter =    ffs_epfile_read_iter,
        .release =      ffs_epfile_release,
        .unlocked_ioctl =       ffs_epfile_ioctl,
 };
index db49ec4..200f9a5 100644 (file)
@@ -74,6 +74,8 @@ MODULE_DESCRIPTION (DRIVER_DESC);
 MODULE_AUTHOR ("David Brownell");
 MODULE_LICENSE ("GPL");
 
+static int ep_open(struct inode *, struct file *);
+
 
 /*----------------------------------------------------------------------*/
 
@@ -283,14 +285,15 @@ static void epio_complete (struct usb_ep *ep, struct usb_request *req)
  * still need dev->lock to use epdata->ep.
  */
 static int
-get_ready_ep (unsigned f_flags, struct ep_data *epdata)
+get_ready_ep (unsigned f_flags, struct ep_data *epdata, bool is_write)
 {
        int     val;
 
        if (f_flags & O_NONBLOCK) {
                if (!mutex_trylock(&epdata->lock))
                        goto nonblock;
-               if (epdata->state != STATE_EP_ENABLED) {
+               if (epdata->state != STATE_EP_ENABLED &&
+                   (!is_write || epdata->state != STATE_EP_READY)) {
                        mutex_unlock(&epdata->lock);
 nonblock:
                        val = -EAGAIN;
@@ -305,18 +308,20 @@ nonblock:
 
        switch (epdata->state) {
        case STATE_EP_ENABLED:
+               return 0;
+       case STATE_EP_READY:                    /* not configured yet */
+               if (is_write)
+                       return 0;
+               // FALLTHRU
+       case STATE_EP_UNBOUND:                  /* clean disconnect */
                break;
        // case STATE_EP_DISABLED:              /* "can't happen" */
-       // case STATE_EP_READY:                 /* "can't happen" */
        default:                                /* error! */
                pr_debug ("%s: ep %p not available, state %d\n",
                                shortname, epdata, epdata->state);
-               // FALLTHROUGH
-       case STATE_EP_UNBOUND:                  /* clean disconnect */
-               val = -ENODEV;
-               mutex_unlock(&epdata->lock);
        }
-       return val;
+       mutex_unlock(&epdata->lock);
+       return -ENODEV;
 }
 
 static ssize_t
@@ -363,97 +368,6 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len)
        return value;
 }
 
-
-/* handle a synchronous OUT bulk/intr/iso transfer */
-static ssize_t
-ep_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
-{
-       struct ep_data          *data = fd->private_data;
-       void                    *kbuf;
-       ssize_t                 value;
-
-       if ((value = get_ready_ep (fd->f_flags, data)) < 0)
-               return value;
-
-       /* halt any endpoint by doing a "wrong direction" i/o call */
-       if (usb_endpoint_dir_in(&data->desc)) {
-               if (usb_endpoint_xfer_isoc(&data->desc)) {
-                       mutex_unlock(&data->lock);
-                       return -EINVAL;
-               }
-               DBG (data->dev, "%s halt\n", data->name);
-               spin_lock_irq (&data->dev->lock);
-               if (likely (data->ep != NULL))
-                       usb_ep_set_halt (data->ep);
-               spin_unlock_irq (&data->dev->lock);
-               mutex_unlock(&data->lock);
-               return -EBADMSG;
-       }
-
-       /* FIXME readahead for O_NONBLOCK and poll(); careful with ZLPs */
-
-       value = -ENOMEM;
-       kbuf = kmalloc (len, GFP_KERNEL);
-       if (unlikely (!kbuf))
-               goto free1;
-
-       value = ep_io (data, kbuf, len);
-       VDEBUG (data->dev, "%s read %zu OUT, status %d\n",
-               data->name, len, (int) value);
-       if (value >= 0 && copy_to_user (buf, kbuf, value))
-               value = -EFAULT;
-
-free1:
-       mutex_unlock(&data->lock);
-       kfree (kbuf);
-       return value;
-}
-
-/* handle a synchronous IN bulk/intr/iso transfer */
-static ssize_t
-ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
-{
-       struct ep_data          *data = fd->private_data;
-       void                    *kbuf;
-       ssize_t                 value;
-
-       if ((value = get_ready_ep (fd->f_flags, data)) < 0)
-               return value;
-
-       /* halt any endpoint by doing a "wrong direction" i/o call */
-       if (!usb_endpoint_dir_in(&data->desc)) {
-               if (usb_endpoint_xfer_isoc(&data->desc)) {
-                       mutex_unlock(&data->lock);
-                       return -EINVAL;
-               }
-               DBG (data->dev, "%s halt\n", data->name);
-               spin_lock_irq (&data->dev->lock);
-               if (likely (data->ep != NULL))
-                       usb_ep_set_halt (data->ep);
-               spin_unlock_irq (&data->dev->lock);
-               mutex_unlock(&data->lock);
-               return -EBADMSG;
-       }
-
-       /* FIXME writebehind for O_NONBLOCK and poll(), qlen = 1 */
-
-       value = -ENOMEM;
-       kbuf = memdup_user(buf, len);
-       if (IS_ERR(kbuf)) {
-               value = PTR_ERR(kbuf);
-               kbuf = NULL;
-               goto free1;
-       }
-
-       value = ep_io (data, kbuf, len);
-       VDEBUG (data->dev, "%s write %zu IN, status %d\n",
-               data->name, len, (int) value);
-free1:
-       mutex_unlock(&data->lock);
-       kfree (kbuf);
-       return value;
-}
-
 static int
 ep_release (struct inode *inode, struct file *fd)
 {
@@ -481,7 +395,7 @@ static long ep_ioctl(struct file *fd, unsigned code, unsigned long value)
        struct ep_data          *data = fd->private_data;
        int                     status;
 
-       if ((status = get_ready_ep (fd->f_flags, data)) < 0)
+       if ((status = get_ready_ep (fd->f_flags, data, false)) < 0)
                return status;
 
        spin_lock_irq (&data->dev->lock);
@@ -517,8 +431,8 @@ struct kiocb_priv {
        struct mm_struct        *mm;
        struct work_struct      work;
        void                    *buf;
-       const struct iovec      *iv;
-       unsigned long           nr_segs;
+       struct iov_iter         to;
+       const void              *to_free;
        unsigned                actual;
 };
 
@@ -541,35 +455,6 @@ static int ep_aio_cancel(struct kiocb *iocb)
        return value;
 }
 
-static ssize_t ep_copy_to_user(struct kiocb_priv *priv)
-{
-       ssize_t                 len, total;
-       void                    *to_copy;
-       int                     i;
-
-       /* copy stuff into user buffers */
-       total = priv->actual;
-       len = 0;
-       to_copy = priv->buf;
-       for (i=0; i < priv->nr_segs; i++) {
-               ssize_t this = min((ssize_t)(priv->iv[i].iov_len), total);
-
-               if (copy_to_user(priv->iv[i].iov_base, to_copy, this)) {
-                       if (len == 0)
-                               len = -EFAULT;
-                       break;
-               }
-
-               total -= this;
-               len += this;
-               to_copy += this;
-               if (total == 0)
-                       break;
-       }
-
-       return len;
-}
-
 static void ep_user_copy_worker(struct work_struct *work)
 {
        struct kiocb_priv *priv = container_of(work, struct kiocb_priv, work);
@@ -578,13 +463,16 @@ static void ep_user_copy_worker(struct work_struct *work)
        size_t ret;
 
        use_mm(mm);
-       ret = ep_copy_to_user(priv);
+       ret = copy_to_iter(priv->buf, priv->actual, &priv->to);
        unuse_mm(mm);
+       if (!ret)
+               ret = -EFAULT;
 
        /* completing the iocb can drop the ctx and mm, don't touch mm after */
        aio_complete(iocb, ret, ret);
 
        kfree(priv->buf);
+       kfree(priv->to_free);
        kfree(priv);
 }
 
@@ -603,8 +491,9 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)
         * don't need to copy anything to userspace, so we can
         * complete the aio request immediately.
         */
-       if (priv->iv == NULL || unlikely(req->actual == 0)) {
+       if (priv->to_free == NULL || unlikely(req->actual == 0)) {
                kfree(req->buf);
+               kfree(priv->to_free);
                kfree(priv);
                iocb->private = NULL;
                /* aio_complete() reports bytes-transferred _and_ faults */
@@ -618,6 +507,7 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)
 
                priv->buf = req->buf;
                priv->actual = req->actual;
+               INIT_WORK(&priv->work, ep_user_copy_worker);
                schedule_work(&priv->work);
        }
        spin_unlock(&epdata->dev->lock);
@@ -626,38 +516,17 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)
        put_ep(epdata);
 }
 
-static ssize_t
-ep_aio_rwtail(
-       struct kiocb    *iocb,
-       char            *buf,
-       size_t          len,
-       struct ep_data  *epdata,
-       const struct iovec *iv,
-       unsigned long   nr_segs
-)
+static ssize_t ep_aio(struct kiocb *iocb,
+                     struct kiocb_priv *priv,
+                     struct ep_data *epdata,
+                     char *buf,
+                     size_t len)
 {
-       struct kiocb_priv       *priv;
-       struct usb_request      *req;
-       ssize_t                 value;
+       struct usb_request *req;
+       ssize_t value;
 
-       priv = kmalloc(sizeof *priv, GFP_KERNEL);
-       if (!priv) {
-               value = -ENOMEM;
-fail:
-               kfree(buf);
-               return value;
-       }
        iocb->private = priv;
        priv->iocb = iocb;
-       priv->iv = iv;
-       priv->nr_segs = nr_segs;
-       INIT_WORK(&priv->work, ep_user_copy_worker);
-
-       value = get_ready_ep(iocb->ki_filp->f_flags, epdata);
-       if (unlikely(value < 0)) {
-               kfree(priv);
-               goto fail;
-       }
 
        kiocb_set_cancel_fn(iocb, ep_aio_cancel);
        get_ep(epdata);
@@ -669,75 +538,154 @@ fail:
         * allocate or submit those if the host disconnected.
         */
        spin_lock_irq(&epdata->dev->lock);
-       if (likely(epdata->ep)) {
-               req = usb_ep_alloc_request(epdata->ep, GFP_ATOMIC);
-               if (likely(req)) {
-                       priv->req = req;
-                       req->buf = buf;
-                       req->length = len;
-                       req->complete = ep_aio_complete;
-                       req->context = iocb;
-                       value = usb_ep_queue(epdata->ep, req, GFP_ATOMIC);
-                       if (unlikely(0 != value))
-                               usb_ep_free_request(epdata->ep, req);
-               } else
-                       value = -EAGAIN;
-       } else
-               value = -ENODEV;
-       spin_unlock_irq(&epdata->dev->lock);
+       value = -ENODEV;
+       if (unlikely(epdata->ep))
+               goto fail;
 
-       mutex_unlock(&epdata->lock);
+       req = usb_ep_alloc_request(epdata->ep, GFP_ATOMIC);
+       value = -ENOMEM;
+       if (unlikely(!req))
+               goto fail;
 
-       if (unlikely(value)) {
-               kfree(priv);
-               put_ep(epdata);
-       } else
-               value = -EIOCBQUEUED;
+       priv->req = req;
+       req->buf = buf;
+       req->length = len;
+       req->complete = ep_aio_complete;
+       req->context = iocb;
+       value = usb_ep_queue(epdata->ep, req, GFP_ATOMIC);
+       if (unlikely(0 != value)) {
+               usb_ep_free_request(epdata->ep, req);
+               goto fail;
+       }
+       spin_unlock_irq(&epdata->dev->lock);
+       return -EIOCBQUEUED;
+
+fail:
+       spin_unlock_irq(&epdata->dev->lock);
+       kfree(priv->to_free);
+       kfree(priv);
+       put_ep(epdata);
        return value;
 }
 
 static ssize_t
-ep_aio_read(struct kiocb *iocb, const struct iovec *iov,
-               unsigned long nr_segs, loff_t o)
+ep_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
-       struct ep_data          *epdata = iocb->ki_filp->private_data;
-       char                    *buf;
+       struct file *file = iocb->ki_filp;
+       struct ep_data *epdata = file->private_data;
+       size_t len = iov_iter_count(to);
+       ssize_t value;
+       char *buf;
 
-       if (unlikely(usb_endpoint_dir_in(&epdata->desc)))
-               return -EINVAL;
+       if ((value = get_ready_ep(file->f_flags, epdata, false)) < 0)
+               return value;
 
-       buf = kmalloc(iocb->ki_nbytes, GFP_KERNEL);
-       if (unlikely(!buf))
-               return -ENOMEM;
+       /* halt any endpoint by doing a "wrong direction" i/o call */
+       if (usb_endpoint_dir_in(&epdata->desc)) {
+               if (usb_endpoint_xfer_isoc(&epdata->desc) ||
+                   !is_sync_kiocb(iocb)) {
+                       mutex_unlock(&epdata->lock);
+                       return -EINVAL;
+               }
+               DBG (epdata->dev, "%s halt\n", epdata->name);
+               spin_lock_irq(&epdata->dev->lock);
+               if (likely(epdata->ep != NULL))
+                       usb_ep_set_halt(epdata->ep);
+               spin_unlock_irq(&epdata->dev->lock);
+               mutex_unlock(&epdata->lock);
+               return -EBADMSG;
+       }
 
-       return ep_aio_rwtail(iocb, buf, iocb->ki_nbytes, epdata, iov, nr_segs);
+       buf = kmalloc(len, GFP_KERNEL);
+       if (unlikely(!buf)) {
+               mutex_unlock(&epdata->lock);
+               return -ENOMEM;
+       }
+       if (is_sync_kiocb(iocb)) {
+               value = ep_io(epdata, buf, len);
+               if (value >= 0 && copy_to_iter(buf, value, to))
+                       value = -EFAULT;
+       } else {
+               struct kiocb_priv *priv = kzalloc(sizeof *priv, GFP_KERNEL);
+               value = -ENOMEM;
+               if (!priv)
+                       goto fail;
+               priv->to_free = dup_iter(&priv->to, to, GFP_KERNEL);
+               if (!priv->to_free) {
+                       kfree(priv);
+                       goto fail;
+               }
+               value = ep_aio(iocb, priv, epdata, buf, len);
+               if (value == -EIOCBQUEUED)
+                       buf = NULL;
+       }
+fail:
+       kfree(buf);
+       mutex_unlock(&epdata->lock);
+       return value;
 }
 
+static ssize_t ep_config(struct ep_data *, const char *, size_t);
+
 static ssize_t
-ep_aio_write(struct kiocb *iocb, const struct iovec *iov,
-               unsigned long nr_segs, loff_t o)
+ep_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
-       struct ep_data          *epdata = iocb->ki_filp->private_data;
-       char                    *buf;
-       size_t                  len = 0;
-       int                     i = 0;
+       struct file *file = iocb->ki_filp;
+       struct ep_data *epdata = file->private_data;
+       size_t len = iov_iter_count(from);
+       bool configured;
+       ssize_t value;
+       char *buf;
+
+       if ((value = get_ready_ep(file->f_flags, epdata, true)) < 0)
+               return value;
 
-       if (unlikely(!usb_endpoint_dir_in(&epdata->desc)))
-               return -EINVAL;
+       configured = epdata->state == STATE_EP_ENABLED;
 
-       buf = kmalloc(iocb->ki_nbytes, GFP_KERNEL);
-       if (unlikely(!buf))
+       /* halt any endpoint by doing a "wrong direction" i/o call */
+       if (configured && !usb_endpoint_dir_in(&epdata->desc)) {
+               if (usb_endpoint_xfer_isoc(&epdata->desc) ||
+                   !is_sync_kiocb(iocb)) {
+                       mutex_unlock(&epdata->lock);
+                       return -EINVAL;
+               }
+               DBG (epdata->dev, "%s halt\n", epdata->name);
+               spin_lock_irq(&epdata->dev->lock);
+               if (likely(epdata->ep != NULL))
+                       usb_ep_set_halt(epdata->ep);
+               spin_unlock_irq(&epdata->dev->lock);
+               mutex_unlock(&epdata->lock);
+               return -EBADMSG;
+       }
+
+       buf = kmalloc(len, GFP_KERNEL);
+       if (unlikely(!buf)) {
+               mutex_unlock(&epdata->lock);
                return -ENOMEM;
+       }
 
-       for (i=0; i < nr_segs; i++) {
-               if (unlikely(copy_from_user(&buf[len], iov[i].iov_base,
-                               iov[i].iov_len) != 0)) {
-                       kfree(buf);
-                       return -EFAULT;
+       if (unlikely(copy_from_iter(buf, len, from) != len)) {
+               value = -EFAULT;
+               goto out;
+       }
+
+       if (unlikely(!configured)) {
+               value = ep_config(epdata, buf, len);
+       } else if (is_sync_kiocb(iocb)) {
+               value = ep_io(epdata, buf, len);
+       } else {
+               struct kiocb_priv *priv = kzalloc(sizeof *priv, GFP_KERNEL);
+               value = -ENOMEM;
+               if (priv) {
+                       value = ep_aio(iocb, priv, epdata, buf, len);
+                       if (value == -EIOCBQUEUED)
+                               buf = NULL;
                }
-               len += iov[i].iov_len;
        }
-       return ep_aio_rwtail(iocb, buf, len, epdata, NULL, 0);
+out:
+       kfree(buf);
+       mutex_unlock(&epdata->lock);
+       return value;
 }
 
 /*----------------------------------------------------------------------*/
@@ -745,15 +693,15 @@ ep_aio_write(struct kiocb *iocb, const struct iovec *iov,
 /* used after endpoint configuration */
 static const struct file_operations ep_io_operations = {
        .owner =        THIS_MODULE,
-       .llseek =       no_llseek,
 
-       .read =         ep_read,
-       .write =        ep_write,
-       .unlocked_ioctl = ep_ioctl,
+       .open =         ep_open,
        .release =      ep_release,
-
-       .aio_read =     ep_aio_read,
-       .aio_write =    ep_aio_write,
+       .llseek =       no_llseek,
+       .read =         new_sync_read,
+       .write =        new_sync_write,
+       .unlocked_ioctl = ep_ioctl,
+       .read_iter =    ep_read_iter,
+       .write_iter =   ep_write_iter,
 };
 
 /* ENDPOINT INITIALIZATION
@@ -770,17 +718,12 @@ static const struct file_operations ep_io_operations = {
  * speed descriptor, then optional high speed descriptor.
  */
 static ssize_t
-ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
+ep_config (struct ep_data *data, const char *buf, size_t len)
 {
-       struct ep_data          *data = fd->private_data;
        struct usb_ep           *ep;
        u32                     tag;
        int                     value, length = len;
 
-       value = mutex_lock_interruptible(&data->lock);
-       if (value < 0)
-               return value;
-
        if (data->state != STATE_EP_READY) {
                value = -EL2HLT;
                goto fail;
@@ -791,9 +734,7 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
                goto fail0;
 
        /* we might need to change message format someday */
-       if (copy_from_user (&tag, buf, 4)) {
-               goto fail1;
-       }
+       memcpy(&tag, buf, 4);
        if (tag != 1) {
                DBG(data->dev, "config %s, bad tag %d\n", data->name, tag);
                goto fail0;
@@ -806,19 +747,15 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
         */
 
        /* full/low speed descriptor, then high speed */
-       if (copy_from_user (&data->desc, buf, USB_DT_ENDPOINT_SIZE)) {
-               goto fail1;
-       }
+       memcpy(&data->desc, buf, USB_DT_ENDPOINT_SIZE);
        if (data->desc.bLength != USB_DT_ENDPOINT_SIZE
                        || data->desc.bDescriptorType != USB_DT_ENDPOINT)
                goto fail0;
        if (len != USB_DT_ENDPOINT_SIZE) {
                if (len != 2 * USB_DT_ENDPOINT_SIZE)
                        goto fail0;
-               if (copy_from_user (&data->hs_desc, buf + USB_DT_ENDPOINT_SIZE,
-                                       USB_DT_ENDPOINT_SIZE)) {
-                       goto fail1;
-               }
+               memcpy(&data->hs_desc, buf + USB_DT_ENDPOINT_SIZE,
+                       USB_DT_ENDPOINT_SIZE);
                if (data->hs_desc.bLength != USB_DT_ENDPOINT_SIZE
                                || data->hs_desc.bDescriptorType
                                        != USB_DT_ENDPOINT) {
@@ -840,24 +777,20 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
        case USB_SPEED_LOW:
        case USB_SPEED_FULL:
                ep->desc = &data->desc;
-               value = usb_ep_enable(ep);
-               if (value == 0)
-                       data->state = STATE_EP_ENABLED;
                break;
        case USB_SPEED_HIGH:
                /* fails if caller didn't provide that descriptor... */
                ep->desc = &data->hs_desc;
-               value = usb_ep_enable(ep);
-               if (value == 0)
-                       data->state = STATE_EP_ENABLED;
                break;
        default:
                DBG(data->dev, "unconnected, %s init abandoned\n",
                                data->name);
                value = -EINVAL;
+               goto gone;
        }
+       value = usb_ep_enable(ep);
        if (value == 0) {
-               fd->f_op = &ep_io_operations;
+               data->state = STATE_EP_ENABLED;
                value = length;
        }
 gone:
@@ -867,14 +800,10 @@ fail:
                data->desc.bDescriptorType = 0;
                data->hs_desc.bDescriptorType = 0;
        }
-       mutex_unlock(&data->lock);
        return value;
 fail0:
        value = -EINVAL;
        goto fail;
-fail1:
-       value = -EFAULT;
-       goto fail;
 }
 
 static int
@@ -902,15 +831,6 @@ ep_open (struct inode *inode, struct file *fd)
        return value;
 }
 
-/* used before endpoint configuration */
-static const struct file_operations ep_config_operations = {
-       .llseek =       no_llseek,
-
-       .open =         ep_open,
-       .write =        ep_config,
-       .release =      ep_release,
-};
-
 /*----------------------------------------------------------------------*/
 
 /* EP0 IMPLEMENTATION can be partly in userspace.
@@ -989,6 +909,10 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
        enum ep0_state                  state;
 
        spin_lock_irq (&dev->lock);
+       if (dev->state <= STATE_DEV_OPENED) {
+               retval = -EINVAL;
+               goto done;
+       }
 
        /* report fd mode change before acting on it */
        if (dev->setup_abort) {
@@ -1187,8 +1111,6 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
        struct dev_data         *dev = fd->private_data;
        ssize_t                 retval = -ESRCH;
 
-       spin_lock_irq (&dev->lock);
-
        /* report fd mode change before acting on it */
        if (dev->setup_abort) {
                dev->setup_abort = 0;
@@ -1234,7 +1156,6 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
        } else
                DBG (dev, "fail %s, state %d\n", __func__, dev->state);
 
-       spin_unlock_irq (&dev->lock);
        return retval;
 }
 
@@ -1281,6 +1202,9 @@ ep0_poll (struct file *fd, poll_table *wait)
        struct dev_data         *dev = fd->private_data;
        int                     mask = 0;
 
+       if (dev->state <= STATE_DEV_OPENED)
+               return DEFAULT_POLLMASK;
+
        poll_wait(fd, &dev->wait, wait);
 
        spin_lock_irq (&dev->lock);
@@ -1316,19 +1240,6 @@ static long dev_ioctl (struct file *fd, unsigned code, unsigned long value)
        return ret;
 }
 
-/* used after device configuration */
-static const struct file_operations ep0_io_operations = {
-       .owner =        THIS_MODULE,
-       .llseek =       no_llseek,
-
-       .read =         ep0_read,
-       .write =        ep0_write,
-       .fasync =       ep0_fasync,
-       .poll =         ep0_poll,
-       .unlocked_ioctl =       dev_ioctl,
-       .release =      dev_release,
-};
-
 /*----------------------------------------------------------------------*/
 
 /* The in-kernel gadget driver handles most ep0 issues, in particular
@@ -1650,7 +1561,7 @@ static int activate_ep_files (struct dev_data *dev)
                        goto enomem1;
 
                data->dentry = gadgetfs_create_file (dev->sb, data->name,
-                               data, &ep_config_operations);
+                               data, &ep_io_operations);
                if (!data->dentry)
                        goto enomem2;
                list_add_tail (&data->epfiles, &dev->epfiles);
@@ -1852,6 +1763,14 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
        u32                     tag;
        char                    *kbuf;
 
+       spin_lock_irq(&dev->lock);
+       if (dev->state > STATE_DEV_OPENED) {
+               value = ep0_write(fd, buf, len, ptr);
+               spin_unlock_irq(&dev->lock);
+               return value;
+       }
+       spin_unlock_irq(&dev->lock);
+
        if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4))
                return -EINVAL;
 
@@ -1925,7 +1844,6 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
                 * on, they can work ... except in cleanup paths that
                 * kick in after the ep0 descriptor is closed.
                 */
-               fd->f_op = &ep0_io_operations;
                value = len;
        }
        return value;
@@ -1956,12 +1874,14 @@ dev_open (struct inode *inode, struct file *fd)
        return value;
 }
 
-static const struct file_operations dev_init_operations = {
+static const struct file_operations ep0_operations = {
        .llseek =       no_llseek,
 
        .open =         dev_open,
+       .read =         ep0_read,
        .write =        dev_config,
        .fasync =       ep0_fasync,
+       .poll =         ep0_poll,
        .unlocked_ioctl = dev_ioctl,
        .release =      dev_release,
 };
@@ -2077,7 +1997,7 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent)
                goto Enomem;
 
        dev->sb = sb;
-       dev->dentry = gadgetfs_create_file(sb, CHIP, dev, &dev_init_operations);
+       dev->dentry = gadgetfs_create_file(sb, CHIP, dev, &ep0_operations);
        if (!dev->dentry) {
                put_dev(dev);
                goto Enomem;
index f88bfdf..2027a27 100644 (file)
@@ -868,12 +868,14 @@ int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags,
                                func = vfio_pci_set_err_trigger;
                        break;
                }
+               break;
        case VFIO_PCI_REQ_IRQ_INDEX:
                switch (flags & VFIO_IRQ_SET_ACTION_TYPE_MASK) {
                case VFIO_IRQ_SET_ACTION_TRIGGER:
                        func = vfio_pci_set_req_trigger;
                        break;
                }
+               break;
        }
 
        if (!func)
index 0413157..6a356e3 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/balloon_compaction.h>
 #include <linux/oom.h>
+#include <linux/wait.h>
 
 /*
  * Balloon device works in 4K page units.  So each page is pointed to by
@@ -334,17 +335,25 @@ static int virtballoon_oom_notify(struct notifier_block *self,
 static int balloon(void *_vballoon)
 {
        struct virtio_balloon *vb = _vballoon;
+       DEFINE_WAIT_FUNC(wait, woken_wake_function);
 
        set_freezable();
        while (!kthread_should_stop()) {
                s64 diff;
 
                try_to_freeze();
-               wait_event_interruptible(vb->config_change,
-                                        (diff = towards_target(vb)) != 0
-                                        || vb->need_stats_update
-                                        || kthread_should_stop()
-                                        || freezing(current));
+
+               add_wait_queue(&vb->config_change, &wait);
+               for (;;) {
+                       if ((diff = towards_target(vb)) != 0 ||
+                           vb->need_stats_update ||
+                           kthread_should_stop() ||
+                           freezing(current))
+                               break;
+                       wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
+               }
+               remove_wait_queue(&vb->config_change, &wait);
+
                if (vb->need_stats_update)
                        stats_handle_request(vb);
                if (diff > 0)
@@ -499,6 +508,8 @@ static int virtballoon_probe(struct virtio_device *vdev)
        if (err < 0)
                goto out_oom_notify;
 
+       virtio_device_ready(vdev);
+
        vb->thread = kthread_run(balloon, vb, "vballoon");
        if (IS_ERR(vb->thread)) {
                err = PTR_ERR(vb->thread);
index cad5698..6010d7e 100644 (file)
@@ -156,22 +156,95 @@ static void vm_get(struct virtio_device *vdev, unsigned offset,
                   void *buf, unsigned len)
 {
        struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
-       u8 *ptr = buf;
-       int i;
+       void __iomem *base = vm_dev->base + VIRTIO_MMIO_CONFIG;
+       u8 b;
+       __le16 w;
+       __le32 l;
 
-       for (i = 0; i < len; i++)
-               ptr[i] = readb(vm_dev->base + VIRTIO_MMIO_CONFIG + offset + i);
+       if (vm_dev->version == 1) {
+               u8 *ptr = buf;
+               int i;
+
+               for (i = 0; i < len; i++)
+                       ptr[i] = readb(base + offset + i);
+               return;
+       }
+
+       switch (len) {
+       case 1:
+               b = readb(base + offset);
+               memcpy(buf, &b, sizeof b);
+               break;
+       case 2:
+               w = cpu_to_le16(readw(base + offset));
+               memcpy(buf, &w, sizeof w);
+               break;
+       case 4:
+               l = cpu_to_le32(readl(base + offset));
+               memcpy(buf, &l, sizeof l);
+               break;
+       case 8:
+               l = cpu_to_le32(readl(base + offset));
+               memcpy(buf, &l, sizeof l);
+               l = cpu_to_le32(ioread32(base + offset + sizeof l));
+               memcpy(buf + sizeof l, &l, sizeof l);
+               break;
+       default:
+               BUG();
+       }
 }
 
 static void vm_set(struct virtio_device *vdev, unsigned offset,
                   const void *buf, unsigned len)
 {
        struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
-       const u8 *ptr = buf;
-       int i;
+       void __iomem *base = vm_dev->base + VIRTIO_MMIO_CONFIG;
+       u8 b;
+       __le16 w;
+       __le32 l;
 
-       for (i = 0; i < len; i++)
-               writeb(ptr[i], vm_dev->base + VIRTIO_MMIO_CONFIG + offset + i);
+       if (vm_dev->version == 1) {
+               const u8 *ptr = buf;
+               int i;
+
+               for (i = 0; i < len; i++)
+                       writeb(ptr[i], base + offset + i);
+
+               return;
+       }
+
+       switch (len) {
+       case 1:
+               memcpy(&b, buf, sizeof b);
+               writeb(b, base + offset);
+               break;
+       case 2:
+               memcpy(&w, buf, sizeof w);
+               writew(le16_to_cpu(w), base + offset);
+               break;
+       case 4:
+               memcpy(&l, buf, sizeof l);
+               writel(le32_to_cpu(l), base + offset);
+               break;
+       case 8:
+               memcpy(&l, buf, sizeof l);
+               writel(le32_to_cpu(l), base + offset);
+               memcpy(&l, buf + sizeof l, sizeof l);
+               writel(le32_to_cpu(l), base + offset + sizeof l);
+               break;
+       default:
+               BUG();
+       }
+}
+
+static u32 vm_generation(struct virtio_device *vdev)
+{
+       struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+
+       if (vm_dev->version == 1)
+               return 0;
+       else
+               return readl(vm_dev->base + VIRTIO_MMIO_CONFIG_GENERATION);
 }
 
 static u8 vm_get_status(struct virtio_device *vdev)
@@ -440,6 +513,7 @@ static const char *vm_bus_name(struct virtio_device *vdev)
 static const struct virtio_config_ops virtio_mmio_config_ops = {
        .get            = vm_get,
        .set            = vm_set,
+       .generation     = vm_generation,
        .get_status     = vm_get_status,
        .set_status     = vm_set_status,
        .reset          = vm_reset,
index b4bca2d..70fba97 100644 (file)
@@ -526,20 +526,26 @@ static unsigned int __startup_pirq(unsigned int irq)
        pirq_query_unmask(irq);
 
        rc = set_evtchn_to_irq(evtchn, irq);
-       if (rc != 0) {
-               pr_err("irq%d: Failed to set port to irq mapping (%d)\n",
-                      irq, rc);
-               xen_evtchn_close(evtchn);
-               return 0;
-       }
+       if (rc)
+               goto err;
+
        bind_evtchn_to_cpu(evtchn, 0);
        info->evtchn = evtchn;
 
+       rc = xen_evtchn_port_setup(info);
+       if (rc)
+               goto err;
+
 out:
        unmask_evtchn(evtchn);
        eoi_pirq(irq_get_irq_data(irq));
 
        return 0;
+
+err:
+       pr_err("irq%d: Failed to set port to irq mapping (%d)\n", irq, rc);
+       xen_evtchn_close(evtchn);
+       return 0;
 }
 
 static unsigned int startup_pirq(struct irq_data *data)
index 46ae0f9..75fe3d4 100644 (file)
@@ -16,7 +16,7 @@
 #include "conf_space.h"
 #include "conf_space_quirks.h"
 
-static bool permissive;
+bool permissive;
 module_param(permissive, bool, 0644);
 
 /* This is where xen_pcibk_read_config_byte, xen_pcibk_read_config_word,
index e56c934..2e1d73d 100644 (file)
@@ -64,6 +64,8 @@ struct config_field_entry {
        void *data;
 };
 
+extern bool permissive;
+
 #define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)
 
 /* Add fields to a device - the add_fields macro expects to get a pointer to
index c5ee825..2d73693 100644 (file)
 #include "pciback.h"
 #include "conf_space.h"
 
+struct pci_cmd_info {
+       u16 val;
+};
+
 struct pci_bar_info {
        u32 val;
        u32 len_val;
@@ -20,22 +24,36 @@ struct pci_bar_info {
 #define is_enable_cmd(value) ((value)&(PCI_COMMAND_MEMORY|PCI_COMMAND_IO))
 #define is_master_cmd(value) ((value)&PCI_COMMAND_MASTER)
 
-static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data)
+/* Bits guests are allowed to control in permissive mode. */
+#define PCI_COMMAND_GUEST (PCI_COMMAND_MASTER|PCI_COMMAND_SPECIAL| \
+                          PCI_COMMAND_INVALIDATE|PCI_COMMAND_VGA_PALETTE| \
+                          PCI_COMMAND_WAIT|PCI_COMMAND_FAST_BACK)
+
+static void *command_init(struct pci_dev *dev, int offset)
 {
-       int i;
-       int ret;
-
-       ret = xen_pcibk_read_config_word(dev, offset, value, data);
-       if (!pci_is_enabled(dev))
-               return ret;
-
-       for (i = 0; i < PCI_ROM_RESOURCE; i++) {
-               if (dev->resource[i].flags & IORESOURCE_IO)
-                       *value |= PCI_COMMAND_IO;
-               if (dev->resource[i].flags & IORESOURCE_MEM)
-                       *value |= PCI_COMMAND_MEMORY;
+       struct pci_cmd_info *cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
+       int err;
+
+       if (!cmd)
+               return ERR_PTR(-ENOMEM);
+
+       err = pci_read_config_word(dev, PCI_COMMAND, &cmd->val);
+       if (err) {
+               kfree(cmd);
+               return ERR_PTR(err);
        }
 
+       return cmd;
+}
+
+static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data)
+{
+       int ret = pci_read_config_word(dev, offset, value);
+       const struct pci_cmd_info *cmd = data;
+
+       *value &= PCI_COMMAND_GUEST;
+       *value |= cmd->val & ~PCI_COMMAND_GUEST;
+
        return ret;
 }
 
@@ -43,6 +61,8 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
 {
        struct xen_pcibk_dev_data *dev_data;
        int err;
+       u16 val;
+       struct pci_cmd_info *cmd = data;
 
        dev_data = pci_get_drvdata(dev);
        if (!pci_is_enabled(dev) && is_enable_cmd(value)) {
@@ -83,6 +103,19 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
                }
        }
 
+       cmd->val = value;
+
+       if (!permissive && (!dev_data || !dev_data->permissive))
+               return 0;
+
+       /* Only allow the guest to control certain bits. */
+       err = pci_read_config_word(dev, offset, &val);
+       if (err || val == value)
+               return err;
+
+       value &= PCI_COMMAND_GUEST;
+       value |= val & ~PCI_COMMAND_GUEST;
+
        return pci_write_config_word(dev, offset, value);
 }
 
@@ -282,6 +315,8 @@ static const struct config_field header_common[] = {
        {
         .offset    = PCI_COMMAND,
         .size      = 2,
+        .init      = command_init,
+        .release   = bar_release,
         .u.w.read  = command_read,
         .u.w.write = command_write,
        },
index f1bad68..528fedf 100644 (file)
@@ -1728,7 +1728,7 @@ static int generic_delete_lease(struct file *filp, void *owner)
                        break;
                }
        }
-       trace_generic_delete_lease(inode, fl);
+       trace_generic_delete_lease(inode, victim);
        if (victim)
                error = fl->fl_lmops->lm_change(victim, F_UNLCK, &dispose);
        spin_unlock(&ctx->flc_lock);
index 469086b..0c3f303 100644 (file)
@@ -1907,6 +1907,7 @@ static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci,
                                             struct the_nilfs *nilfs)
 {
        struct nilfs_inode_info *ii, *n;
+       int during_mount = !(sci->sc_super->s_flags & MS_ACTIVE);
        int defer_iput = false;
 
        spin_lock(&nilfs->ns_inode_lock);
@@ -1919,10 +1920,10 @@ static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci,
                brelse(ii->i_bh);
                ii->i_bh = NULL;
                list_del_init(&ii->i_dirty);
-               if (!ii->vfs_inode.i_nlink) {
+               if (!ii->vfs_inode.i_nlink || during_mount) {
                        /*
-                        * Defer calling iput() to avoid a deadlock
-                        * over I_SYNC flag for inodes with i_nlink == 0
+                        * Defer calling iput() to avoid deadlocks if
+                        * i_nlink == 0 or mount is not yet finished.
                         */
                        list_add_tail(&ii->i_dirty, &sci->sc_iput_queue);
                        defer_iput = true;
index 9a66ff7..d2f97ec 100644 (file)
@@ -143,7 +143,8 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark,
            !(marks_mask & FS_ISDIR & ~marks_ignored_mask))
                return false;
 
-       if (event_mask & marks_mask & ~marks_ignored_mask)
+       if (event_mask & FAN_ALL_OUTGOING_EVENTS & marks_mask &
+                                ~marks_ignored_mask)
                return true;
 
        return false;
index 8490c64..460c6c3 100644 (file)
@@ -502,7 +502,7 @@ static inline int ocfs2_writes_unwritten_extents(struct ocfs2_super *osb)
 
 static inline int ocfs2_supports_append_dio(struct ocfs2_super *osb)
 {
-       if (osb->s_feature_ro_compat & OCFS2_FEATURE_RO_COMPAT_APPEND_DIO)
+       if (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_APPEND_DIO)
                return 1;
        return 0;
 }
index 20e37a3..db64ce2 100644 (file)
                                         | OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS \
                                         | OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE \
                                         | OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG  \
-                                        | OCFS2_FEATURE_INCOMPAT_CLUSTERINFO)
+                                        | OCFS2_FEATURE_INCOMPAT_CLUSTERINFO \
+                                        | OCFS2_FEATURE_INCOMPAT_APPEND_DIO)
 #define OCFS2_FEATURE_RO_COMPAT_SUPP   (OCFS2_FEATURE_RO_COMPAT_UNWRITTEN \
                                         | OCFS2_FEATURE_RO_COMPAT_USRQUOTA \
-                                        | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA \
-                                        | OCFS2_FEATURE_RO_COMPAT_APPEND_DIO)
+                                        | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)
 
 /*
  * Heartbeat-only devices are missing journals and other files.  The
 #define OCFS2_FEATURE_INCOMPAT_CLUSTERINFO     0x4000
 
 /*
+ * Append Direct IO support
+ */
+#define OCFS2_FEATURE_INCOMPAT_APPEND_DIO      0x8000
+
+/*
  * backup superblock flag is used to indicate that this volume
  * has backup superblocks.
  */
 #define OCFS2_FEATURE_RO_COMPAT_USRQUOTA       0x0002
 #define OCFS2_FEATURE_RO_COMPAT_GRPQUOTA       0x0004
 
-/*
- * Append Direct IO support
- */
-#define OCFS2_FEATURE_RO_COMPAT_APPEND_DIO     0x0008
 
 /* The byte offset of the first backup block will be 1G.
  * The following will be 4G, 16G, 64G, 256G and 1T.
index 956b75d..6dee68d 100644 (file)
@@ -1325,6 +1325,9 @@ out:
 
 static int pagemap_open(struct inode *inode, struct file *file)
 {
+       /* do not disclose physical addresses: attack vector */
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
        pr_warn_once("Bits 55-60 of /proc/PID/pagemap entries are about "
                        "to stop being page-shift some time soon. See the "
                        "linux/Documentation/vm/pagemap.txt for details.\n");
index 2fbc804..226f772 100644 (file)
@@ -13,7 +13,8 @@
 
 #define PULL_DISABLE           (1 << 3)
 #define INPUT_EN               (1 << 5)
-#define SLEWCTRL_FAST          (1 << 6)
+#define SLEWCTRL_SLOW          (1 << 6)
+#define SLEWCTRL_FAST          0
 
 /* update macro depending on INPUT_EN and PULL_ENA */
 #undef PIN_OUTPUT
index 9c2e4f8..5f4d018 100644 (file)
@@ -18,7 +18,8 @@
 #define PULL_DISABLE           (1 << 16)
 #define PULL_UP                        (1 << 17)
 #define INPUT_EN               (1 << 18)
-#define SLEWCTRL_FAST          (1 << 19)
+#define SLEWCTRL_SLOW          (1 << 19)
+#define SLEWCTRL_FAST          0
 #define DS0_PULL_UP_DOWN_EN    (1 << 27)
 
 #define PIN_OUTPUT             (PULL_DISABLE)
index 7c55dd5..66203b2 100644 (file)
@@ -114,6 +114,7 @@ struct vgic_ops {
        void    (*sync_lr_elrsr)(struct kvm_vcpu *, int, struct vgic_lr);
        u64     (*get_elrsr)(const struct kvm_vcpu *vcpu);
        u64     (*get_eisr)(const struct kvm_vcpu *vcpu);
+       void    (*clear_eisr)(struct kvm_vcpu *vcpu);
        u32     (*get_interrupt_status)(const struct kvm_vcpu *vcpu);
        void    (*enable_underflow)(struct kvm_vcpu *vcpu);
        void    (*disable_underflow)(struct kvm_vcpu *vcpu);
index 8381bbf..68c16a6 100644 (file)
@@ -125,6 +125,19 @@ int clk_set_phase(struct clk *clk, int degrees);
  */
 int clk_get_phase(struct clk *clk);
 
+/**
+ * clk_is_match - check if two clk's point to the same hardware clock
+ * @p: clk compared against q
+ * @q: clk compared against p
+ *
+ * Returns true if the two struct clk pointers both point to the same hardware
+ * clock node. Put differently, returns true if struct clk *p and struct clk *q
+ * share the same struct clk_core object.
+ *
+ * Returns false otherwise. Note that two NULL clks are treated as matching.
+ */
+bool clk_is_match(const struct clk *p, const struct clk *q);
+
 #else
 
 static inline long clk_get_accuracy(struct clk *clk)
@@ -142,6 +155,11 @@ static inline long clk_get_phase(struct clk *clk)
        return -ENOTSUPP;
 }
 
+static inline bool clk_is_match(const struct clk *p, const struct clk *q)
+{
+       return p == q;
+}
+
 #endif
 
 /**
index 800544b..781974a 100644 (file)
 
 #define GITS_TRANSLATER                        0x10040
 
+#define GITS_CTLR_ENABLE               (1U << 0)
+#define GITS_CTLR_QUIESCENT            (1U << 31)
+
+#define GITS_TYPER_DEVBITS_SHIFT       13
+#define GITS_TYPER_DEVBITS(r)          ((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1)
 #define GITS_TYPER_PTA                 (1UL << 19)
 
 #define GITS_CBASER_VALID              (1UL << 63)
index 72ba725..5bb0744 100644 (file)
@@ -5,6 +5,7 @@
 
 struct kmem_cache;
 struct page;
+struct vm_struct;
 
 #ifdef CONFIG_KASAN
 
@@ -49,15 +50,11 @@ void kasan_krealloc(const void *object, size_t new_size);
 void kasan_slab_alloc(struct kmem_cache *s, void *object);
 void kasan_slab_free(struct kmem_cache *s, void *object);
 
-#define MODULE_ALIGN (PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
-
 int kasan_module_alloc(void *addr, size_t size);
-void kasan_module_free(void *addr);
+void kasan_free_shadow(const struct vm_struct *vm);
 
 #else /* CONFIG_KASAN */
 
-#define MODULE_ALIGN 1
-
 static inline void kasan_unpoison_shadow(const void *address, size_t size) {}
 
 static inline void kasan_enable_current(void) {}
@@ -82,7 +79,7 @@ static inline void kasan_slab_alloc(struct kmem_cache *s, void *object) {}
 static inline void kasan_slab_free(struct kmem_cache *s, void *object) {}
 
 static inline int kasan_module_alloc(void *addr, size_t size) { return 0; }
-static inline void kasan_module_free(void *addr) {}
+static inline void kasan_free_shadow(const struct vm_struct *vm) {}
 
 #endif /* CONFIG_KASAN */
 
index 42999fe..b03485b 100644 (file)
@@ -344,6 +344,10 @@ struct module {
        unsigned long *ftrace_callsites;
 #endif
 
+#ifdef CONFIG_LIVEPATCH
+       bool klp_alive;
+#endif
+
 #ifdef CONFIG_MODULE_UNLOAD
        /* What modules depend on me? */
        struct list_head source_list;
index f755626..4d0cb9b 100644 (file)
@@ -84,4 +84,12 @@ void module_arch_cleanup(struct module *mod);
 
 /* Any cleanup before freeing mod->module_init */
 void module_arch_freeing_init(struct module *mod);
+
+#ifdef CONFIG_KASAN
+#include <linux/kasan.h>
+#define MODULE_ALIGN (PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
+#else
+#define MODULE_ALIGN PAGE_SIZE
+#endif
+
 #endif
index 8a860f0..611a691 100644 (file)
@@ -84,7 +84,7 @@ static inline int of_platform_populate(struct device_node *root,
 static inline void of_platform_depopulate(struct device *parent) { }
 #endif
 
-#ifdef CONFIG_OF_DYNAMIC
+#if defined(CONFIG_OF_DYNAMIC) && defined(CONFIG_OF_ADDRESS)
 extern void of_platform_register_reconfig_notifier(void);
 #else
 static inline void of_platform_register_reconfig_notifier(void) { }
index 07a0226..7188029 100644 (file)
@@ -98,6 +98,8 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages,
                        size_t maxsize, size_t *start);
 int iov_iter_npages(const struct iov_iter *i, int maxpages);
 
+const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags);
+
 static inline size_t iov_iter_count(struct iov_iter *i)
 {
        return i->count;
index 7d7acb3..0ec5983 100644 (file)
@@ -17,6 +17,7 @@ struct vm_area_struct;                /* vma defining user mapping in mm_types.h */
 #define VM_VPAGES              0x00000010      /* buffer for pages was vmalloc'ed */
 #define VM_UNINITIALIZED       0x00000020      /* vm_struct is not fully initialized */
 #define VM_NO_GUARD            0x00000040      /* don't add guard page */
+#define VM_KASAN               0x00000080      /* has allocated kasan shadow memory */
 /* bits [20..32] reserved for arch specific ioremap internals */
 
 /*
index 0210797..dc10c52 100644 (file)
@@ -92,7 +92,7 @@
 #define                AT91_DDRSDRC_UPD_MR     (3 << 20)        /* Update load mode register and extended mode register */
 
 #define AT91_DDRSDRC_MDR       0x20    /* Memory Device Register */
-#define                AT91_DDRSDRC_MD         (3 << 0)                /* Memory Device Type */
+#define                AT91_DDRSDRC_MD         (7 << 0)        /* Memory Device Type */
 #define                        AT91_DDRSDRC_MD_SDR             0
 #define                        AT91_DDRSDRC_MD_LOW_POWER_SDR   1
 #define                        AT91_DDRSDRC_MD_LOW_POWER_DDR   3
index 3c53eec..19c66fc 100644 (file)
@@ -60,7 +60,7 @@ struct virtio_blk_config {
        __u32 size_max;
        /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
        __u32 seg_max;
-       /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */
+       /* geometry of the device (if VIRTIO_BLK_F_GEOMETRY) */
        struct virtio_blk_geometry {
                __u16 cylinders;
                __u8 heads;
@@ -119,7 +119,11 @@ struct virtio_blk_config {
 #define VIRTIO_BLK_T_BARRIER   0x80000000
 #endif /* !VIRTIO_BLK_NO_LEGACY */
 
-/* This is the first element of the read scatter-gather list. */
+/*
+ * This comes first in the read scatter-gather list.
+ * For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated,
+ * this is the first element of the read scatter-gather list.
+ */
 struct virtio_blk_outhdr {
        /* VIRTIO_BLK_T* */
        __virtio32 type;
index 42b9370..cc18ef8 100644 (file)
 
 #include <linux/virtio_types.h>
 
-#define VIRTIO_SCSI_CDB_SIZE   32
-#define VIRTIO_SCSI_SENSE_SIZE 96
+/* Default values of the CDB and sense data size configuration fields */
+#define VIRTIO_SCSI_CDB_DEFAULT_SIZE   32
+#define VIRTIO_SCSI_SENSE_DEFAULT_SIZE 96
+
+#ifndef VIRTIO_SCSI_CDB_SIZE
+#define VIRTIO_SCSI_CDB_SIZE VIRTIO_SCSI_CDB_DEFAULT_SIZE
+#endif
+#ifndef VIRTIO_SCSI_SENSE_SIZE
+#define VIRTIO_SCSI_SENSE_SIZE VIRTIO_SCSI_SENSE_DEFAULT_SIZE
+#endif
 
 /* SCSI command request, followed by data-out */
 struct virtio_scsi_cmd_req {
index b78f21c..b0f1c9e 100644 (file)
@@ -114,9 +114,9 @@ int __must_check __xenbus_register_backend(struct xenbus_driver *drv,
                                           const char *mod_name);
 
 #define xenbus_register_frontend(drv) \
-       __xenbus_register_frontend(drv, THIS_MODULE, KBUILD_MODNAME);
+       __xenbus_register_frontend(drv, THIS_MODULE, KBUILD_MODNAME)
 #define xenbus_register_backend(drv) \
-       __xenbus_register_backend(drv, THIS_MODULE, KBUILD_MODNAME);
+       __xenbus_register_backend(drv, THIS_MODULE, KBUILD_MODNAME)
 
 void xenbus_unregister_driver(struct xenbus_driver *drv);
 
index f04daab..453ef61 100644 (file)
@@ -3591,7 +3591,7 @@ static void put_event(struct perf_event *event)
        ctx = perf_event_ctx_lock_nested(event, SINGLE_DEPTH_NESTING);
        WARN_ON_ONCE(ctx->parent_ctx);
        perf_remove_from_context(event, true);
-       mutex_unlock(&ctx->mutex);
+       perf_event_ctx_unlock(event, ctx);
 
        _free_event(event);
 }
index 01ca088..3f9f1d6 100644 (file)
@@ -89,16 +89,28 @@ static bool klp_is_object_loaded(struct klp_object *obj)
 /* sets obj->mod if object is not vmlinux and module is found */
 static void klp_find_object_module(struct klp_object *obj)
 {
+       struct module *mod;
+
        if (!klp_is_module(obj))
                return;
 
        mutex_lock(&module_mutex);
        /*
-        * We don't need to take a reference on the module here because we have
-        * the klp_mutex, which is also taken by the module notifier.  This
-        * prevents any module from unloading until we release the klp_mutex.
+        * We do not want to block removal of patched modules and therefore
+        * we do not take a reference here. The patches are removed by
+        * a going module handler instead.
+        */
+       mod = find_module(obj->name);
+       /*
+        * Do not mess work of the module coming and going notifiers.
+        * Note that the patch might still be needed before the going handler
+        * is called. Module functions can be called even in the GOING state
+        * until mod->exit() finishes. This is especially important for
+        * patches that modify semantic of the functions.
         */
-       obj->mod = find_module(obj->name);
+       if (mod && mod->klp_alive)
+               obj->mod = mod;
+
        mutex_unlock(&module_mutex);
 }
 
@@ -767,6 +779,7 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj)
                return -EINVAL;
 
        obj->state = KLP_DISABLED;
+       obj->mod = NULL;
 
        klp_find_object_module(obj);
 
@@ -961,6 +974,15 @@ static int klp_module_notify(struct notifier_block *nb, unsigned long action,
 
        mutex_lock(&klp_mutex);
 
+       /*
+        * Each module has to know that the notifier has been called.
+        * We never know what module will get patched by a new patch.
+        */
+       if (action == MODULE_STATE_COMING)
+               mod->klp_alive = true;
+       else /* MODULE_STATE_GOING */
+               mod->klp_alive = false;
+
        list_for_each_entry(patch, &klp_patches, list) {
                for (obj = patch->objs; obj->funcs; obj++) {
                        if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
index cc93cf6..b3d634e 100644 (file)
@@ -56,7 +56,6 @@
 #include <linux/async.h>
 #include <linux/percpu.h>
 #include <linux/kmemleak.h>
-#include <linux/kasan.h>
 #include <linux/jump_label.h>
 #include <linux/pfn.h>
 #include <linux/bsearch.h>
@@ -1814,7 +1813,6 @@ static void unset_module_init_ro_nx(struct module *mod) { }
 void __weak module_memfree(void *module_region)
 {
        vfree(module_region);
-       kasan_module_free(module_region);
 }
 
 void __weak module_arch_cleanup(struct module *mod)
index 87eb3bf..58f74d2 100644 (file)
@@ -24,7 +24,7 @@ obj-y += lockref.o
 
 obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
         bust_spinlocks.o kasprintf.o bitmap.o scatterlist.o \
-        gcd.o lcm.o list_sort.o uuid.o flex_array.o clz_ctz.o \
+        gcd.o lcm.o list_sort.o uuid.o flex_array.o iov_iter.o clz_ctz.o \
         bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \
         percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o
 obj-y += string_helpers.o
similarity index 97%
rename from mm/iov_iter.c
rename to lib/iov_iter.c
index 8277320..9d96e28 100644 (file)
@@ -751,3 +751,18 @@ int iov_iter_npages(const struct iov_iter *i, int maxpages)
        return npages;
 }
 EXPORT_SYMBOL(iov_iter_npages);
+
+const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags)
+{
+       *new = *old;
+       if (new->type & ITER_BVEC)
+               return new->bvec = kmemdup(new->bvec,
+                                   new->nr_segs * sizeof(struct bio_vec),
+                                   flags);
+       else
+               /* iovec and kvec have identical layout */
+               return new->iov = kmemdup(new->iov,
+                                  new->nr_segs * sizeof(struct iovec),
+                                  flags);
+}
+EXPORT_SYMBOL(dup_iter);
index 3c1caa2..15dbe99 100644 (file)
@@ -21,7 +21,7 @@ obj-y                 := filemap.o mempool.o oom_kill.o \
                           mm_init.o mmu_context.o percpu.o slab_common.o \
                           compaction.o vmacache.o \
                           interval_tree.o list_lru.o workingset.o \
-                          iov_iter.o debug.o $(mmu-y)
+                          debug.o $(mmu-y)
 
 obj-y += init-mm.o
 
index 75016fd..68ecb7a 100644 (file)
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -64,15 +64,17 @@ static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int align_order)
        return (1UL << (align_order - cma->order_per_bit)) - 1;
 }
 
+/*
+ * Find a PFN aligned to the specified order and return an offset represented in
+ * order_per_bits.
+ */
 static unsigned long cma_bitmap_aligned_offset(struct cma *cma, int align_order)
 {
-       unsigned int alignment;
-
        if (align_order <= cma->order_per_bit)
                return 0;
-       alignment = 1UL << (align_order - cma->order_per_bit);
-       return ALIGN(cma->base_pfn, alignment) -
-               (cma->base_pfn >> cma->order_per_bit);
+
+       return (ALIGN(cma->base_pfn, (1UL << align_order))
+               - cma->base_pfn) >> cma->order_per_bit;
 }
 
 static unsigned long cma_bitmap_maxno(struct cma *cma)
index fc00c8c..626e93d 100644 (file)
@@ -1295,8 +1295,13 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
         * Avoid grouping on DSO/COW pages in specific and RO pages
         * in general, RO pages shouldn't hurt as much anyway since
         * they can be in shared cache state.
+        *
+        * FIXME! This checks "pmd_dirty()" as an approximation of
+        * "is this a read-only page", since checking "pmd_write()"
+        * is even more broken. We haven't actually turned this into
+        * a writable page, so pmd_write() will always be false.
         */
-       if (!pmd_write(pmd))
+       if (!pmd_dirty(pmd))
                flags |= TNF_NO_GROUP;
 
        /*
@@ -1482,6 +1487,7 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
 
        if (__pmd_trans_huge_lock(pmd, vma, &ptl) == 1) {
                pmd_t entry;
+               ret = 1;
 
                /*
                 * Avoid trapping faults against the zero page. The read-only
@@ -1490,11 +1496,10 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
                 */
                if (prot_numa && is_huge_zero_pmd(*pmd)) {
                        spin_unlock(ptl);
-                       return 0;
+                       return ret;
                }
 
                if (!prot_numa || !pmd_protnone(*pmd)) {
-                       ret = 1;
                        entry = pmdp_get_and_clear_notify(mm, addr, pmd);
                        entry = pmd_modify(entry, newprot);
                        ret = HPAGE_PMD_NR;
index 0a9ac6c..c41b2a0 100644 (file)
@@ -917,7 +917,6 @@ static void prep_compound_gigantic_page(struct page *page, unsigned long order)
        __SetPageHead(page);
        __ClearPageReserved(page);
        for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) {
-               __SetPageTail(p);
                /*
                 * For gigantic hugepages allocated through bootmem at
                 * boot, it's safer to be consistent with the not-gigantic
@@ -933,6 +932,9 @@ static void prep_compound_gigantic_page(struct page *page, unsigned long order)
                __ClearPageReserved(p);
                set_page_count(p, 0);
                p->first_page = page;
+               /* Make sure p->first_page is always valid for PageTail() */
+               smp_wmb();
+               __SetPageTail(p);
        }
 }
 
index 78fee63..936d816 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/stacktrace.h>
 #include <linux/string.h>
 #include <linux/types.h>
+#include <linux/vmalloc.h>
 #include <linux/kasan.h>
 
 #include "kasan.h"
@@ -414,12 +415,19 @@ int kasan_module_alloc(void *addr, size_t size)
                        GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
                        PAGE_KERNEL, VM_NO_GUARD, NUMA_NO_NODE,
                        __builtin_return_address(0));
-       return ret ? 0 : -ENOMEM;
+
+       if (ret) {
+               find_vm_area(addr)->flags |= VM_KASAN;
+               return 0;
+       }
+
+       return -ENOMEM;
 }
 
-void kasan_module_free(void *addr)
+void kasan_free_shadow(const struct vm_struct *vm)
 {
-       vfree(kasan_mem_to_shadow(addr));
+       if (vm->flags & VM_KASAN)
+               vfree(kasan_mem_to_shadow(vm->addr));
 }
 
 static void register_global(struct kasan_global *global)
index 9fe0769..b34ef4a 100644 (file)
@@ -5232,7 +5232,9 @@ static void mem_cgroup_bind(struct cgroup_subsys_state *root_css)
         * on for the root memcg is enough.
         */
        if (cgroup_on_dfl(root_css->cgroup))
-               mem_cgroup_from_css(root_css)->use_hierarchy = true;
+               root_mem_cgroup->use_hierarchy = true;
+       else
+               root_mem_cgroup->use_hierarchy = false;
 }
 
 static u64 memory_current_read(struct cgroup_subsys_state *css,
index 8068893..411144f 100644 (file)
@@ -3072,8 +3072,13 @@ static int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
         * Avoid grouping on DSO/COW pages in specific and RO pages
         * in general, RO pages shouldn't hurt as much anyway since
         * they can be in shared cache state.
+        *
+        * FIXME! This checks "pmd_dirty()" as an approximation of
+        * "is this a read-only page", since checking "pmd_write()"
+        * is even more broken. We haven't actually turned this into
+        * a writable page, so pmd_write() will always be false.
         */
-       if (!pte_write(pte))
+       if (!pte_dirty(pte))
                flags |= TNF_NO_GROUP;
 
        /*
index 73cf098..8a54cd2 100644 (file)
 
 int can_do_mlock(void)
 {
-       if (capable(CAP_IPC_LOCK))
-               return 1;
        if (rlimit(RLIMIT_MEMLOCK) != 0)
                return 1;
+       if (capable(CAP_IPC_LOCK))
+               return 1;
        return 0;
 }
 EXPORT_SYMBOL(can_do_mlock);
index 3e67e75..3fba2dc 100644 (file)
@@ -62,6 +62,7 @@ void *high_memory;
 EXPORT_SYMBOL(high_memory);
 struct page *mem_map;
 unsigned long max_mapnr;
+EXPORT_SYMBOL(max_mapnr);
 unsigned long highest_memmap_pfn;
 struct percpu_counter vm_committed_as;
 int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */
index 7abfa70..40e2942 100644 (file)
@@ -2373,7 +2373,8 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,
                        goto out;
        }
        /* Exhausted what can be done so it's blamo time */
-       if (out_of_memory(ac->zonelist, gfp_mask, order, ac->nodemask, false))
+       if (out_of_memory(ac->zonelist, gfp_mask, order, ac->nodemask, false)
+                       || WARN_ON_ONCE(gfp_mask & __GFP_NOFAIL))
                *did_some_progress = 1;
 out:
        oom_zonelist_unlock(ac->zonelist, gfp_mask);
index 35b25e1..49abccf 100644 (file)
@@ -1418,6 +1418,7 @@ struct vm_struct *remove_vm_area(const void *addr)
                spin_unlock(&vmap_area_lock);
 
                vmap_debug_free_range(va->va_start, va->va_end);
+               kasan_free_shadow(vm);
                free_unmap_vmap_area(va);
                vm->size -= PAGE_SIZE;
 
index d8e376a..36a1a73 100644 (file)
@@ -658,14 +658,30 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
 static void p9_virtio_remove(struct virtio_device *vdev)
 {
        struct virtio_chan *chan = vdev->priv;
-
-       if (chan->inuse)
-               p9_virtio_close(chan->client);
-       vdev->config->del_vqs(vdev);
+       unsigned long warning_time;
 
        mutex_lock(&virtio_9p_lock);
+
+       /* Remove self from list so we don't get new users. */
        list_del(&chan->chan_list);
+       warning_time = jiffies;
+
+       /* Wait for existing users to close. */
+       while (chan->inuse) {
+               mutex_unlock(&virtio_9p_lock);
+               msleep(250);
+               if (time_after(jiffies, warning_time + 10 * HZ)) {
+                       dev_emerg(&vdev->dev,
+                                 "p9_virtio_remove: waiting for device in use.\n");
+                       warning_time = jiffies;
+               }
+               mutex_lock(&virtio_9p_lock);
+       }
+
        mutex_unlock(&virtio_9p_lock);
+
+       vdev->config->del_vqs(vdev);
+
        sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
        kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE);
        kfree(chan->tag);
index 35324a8..eeb691d 100644 (file)
@@ -1170,6 +1170,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
 
        if (info->count < 1)
                return -EINVAL;
+       if (!*info->id.name)
+               return -EINVAL;
+       if (strnlen(info->id.name, sizeof(info->id.name)) >= sizeof(info->id.name))
+               return -EINVAL;
        access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
                (info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
                                 SNDRV_CTL_ELEM_ACCESS_INACTIVE|
index de7602b..27b044f 100644 (file)
 #define RX_ISOCHRONOUS                 0x008
 
 /*
+ * Index of first quadlet to be interpreted; read/write.  If > 0, that many
+ * quadlets at the beginning of each data block will be ignored, and all the
+ * audio and MIDI quadlets will follow.
+ */
+#define RX_SEQ_START                   0x00c
+
+/*
  * The number of audio channels; read-only.  There will be one quadlet per
  * channel.
  */
-#define RX_NUMBER_AUDIO                        0x00c
+#define RX_NUMBER_AUDIO                        0x010
 
 /*
  * The number of MIDI ports, 0-8; read-only.  If > 0, there will be one
  * additional quadlet in each data block, following the audio quadlets.
  */
-#define RX_NUMBER_MIDI                 0x010
-
-/*
- * Index of first quadlet to be interpreted; read/write.  If > 0, that many
- * quadlets at the beginning of each data block will be ignored, and all the
- * audio and MIDI quadlets will follow.
- */
-#define RX_SEQ_START                   0x014
+#define RX_NUMBER_MIDI                 0x014
 
 /*
  * Names of all audio channels; read-only.  Quadlets are byte-swapped.  Names
index ecfe20f..f5c1d1b 100644 (file)
@@ -99,9 +99,9 @@ static void dice_proc_read(struct snd_info_entry *entry,
                } tx;
                struct {
                        u32 iso;
+                       u32 seq_start;
                        u32 number_audio;
                        u32 number_midi;
-                       u32 seq_start;
                        char names[RX_NAMES_SIZE];
                        u32 ac3_caps;
                        u32 ac3_enable;
@@ -204,10 +204,10 @@ static void dice_proc_read(struct snd_info_entry *entry,
                        break;
                snd_iprintf(buffer, "rx %u:\n", stream);
                snd_iprintf(buffer, "  iso channel: %d\n", (int)buf.rx.iso);
+               snd_iprintf(buffer, "  sequence start: %u\n", buf.rx.seq_start);
                snd_iprintf(buffer, "  audio channels: %u\n",
                            buf.rx.number_audio);
                snd_iprintf(buffer, "  midi ports: %u\n", buf.rx.number_midi);
-               snd_iprintf(buffer, "  sequence start: %u\n", buf.rx.seq_start);
                if (quadlets >= 68) {
                        dice_proc_fixup_string(buf.rx.names, RX_NAMES_SIZE);
                        snd_iprintf(buffer, "  names: %s\n", buf.rx.names);
index 5f17b77..f0e4d50 100644 (file)
@@ -26,7 +26,7 @@
 int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit)
 {
        r->channels_mask = ~0uLL;
-       r->unit = fw_unit_get(unit);
+       r->unit = unit;
        mutex_init(&r->mutex);
        r->allocated = false;
 
@@ -42,7 +42,6 @@ void fw_iso_resources_destroy(struct fw_iso_resources *r)
 {
        WARN_ON(r->allocated);
        mutex_destroy(&r->mutex);
-       fw_unit_put(r->unit);
 }
 EXPORT_SYMBOL(fw_iso_resources_destroy);
 
index a2ce773..17c2637 100644 (file)
@@ -1164,7 +1164,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
                }
        }
 
-       if (!bus->no_response_fallback)
+       if (bus->no_response_fallback)
                return -1;
 
        if (!chip->polling_mode && chip->poll_count < 2) {
index b680b4e..8ec5289 100644 (file)
@@ -687,12 +687,45 @@ static int get_amp_val_to_activate(struct hda_codec *codec, hda_nid_t nid,
        return val;
 }
 
+/* is this a stereo widget or a stereo-to-mono mix? */
+static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid, int dir)
+{
+       unsigned int wcaps = get_wcaps(codec, nid);
+       hda_nid_t conn;
+
+       if (wcaps & AC_WCAP_STEREO)
+               return true;
+       if (dir != HDA_INPUT || get_wcaps_type(wcaps) != AC_WID_AUD_MIX)
+               return false;
+       if (snd_hda_get_num_conns(codec, nid) != 1)
+               return false;
+       if (snd_hda_get_connections(codec, nid, &conn, 1) < 0)
+               return false;
+       return !!(get_wcaps(codec, conn) & AC_WCAP_STEREO);
+}
+
 /* initialize the amp value (only at the first time) */
 static void init_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx)
 {
        unsigned int caps = query_amp_caps(codec, nid, dir);
        int val = get_amp_val_to_activate(codec, nid, dir, caps, false);
-       snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val);
+
+       if (is_stereo_amps(codec, nid, dir))
+               snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val);
+       else
+               snd_hda_codec_amp_init(codec, nid, 0, dir, idx, 0xff, val);
+}
+
+/* update the amp, doing in stereo or mono depending on NID */
+static int update_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx,
+                     unsigned int mask, unsigned int val)
+{
+       if (is_stereo_amps(codec, nid, dir))
+               return snd_hda_codec_amp_stereo(codec, nid, dir, idx,
+                                               mask, val);
+       else
+               return snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
+                                               mask, val);
 }
 
 /* calculate amp value mask we can modify;
@@ -732,7 +765,7 @@ static void activate_amp(struct hda_codec *codec, hda_nid_t nid, int dir,
                return;
 
        val &= mask;
-       snd_hda_codec_amp_stereo(codec, nid, dir, idx, mask, val);
+       update_amp(codec, nid, dir, idx, mask, val);
 }
 
 static void activate_amp_out(struct hda_codec *codec, struct nid_path *path,
@@ -4424,13 +4457,11 @@ static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix)
        has_amp = nid_has_mute(codec, mix, HDA_INPUT);
        for (i = 0; i < nums; i++) {
                if (has_amp)
-                       snd_hda_codec_amp_stereo(codec, mix,
-                                                HDA_INPUT, i,
-                                                0xff, HDA_AMP_MUTE);
+                       update_amp(codec, mix, HDA_INPUT, i,
+                                  0xff, HDA_AMP_MUTE);
                else if (nid_has_volume(codec, conn[i], HDA_OUTPUT))
-                       snd_hda_codec_amp_stereo(codec, conn[i],
-                                                HDA_OUTPUT, 0,
-                                                0xff, HDA_AMP_MUTE);
+                       update_amp(codec, conn[i], HDA_OUTPUT, 0,
+                                  0xff, HDA_AMP_MUTE);
        }
 }
 
index ce5a6da..05e19f7 100644 (file)
@@ -134,13 +134,38 @@ static void print_amp_caps(struct snd_info_buffer *buffer,
                    (caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT);
 }
 
+/* is this a stereo widget or a stereo-to-mono mix? */
+static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid,
+                          int dir, unsigned int wcaps, int indices)
+{
+       hda_nid_t conn;
+
+       if (wcaps & AC_WCAP_STEREO)
+               return true;
+       /* check for a stereo-to-mono mix; it must be:
+        * only a single connection, only for input, and only a mixer widget
+        */
+       if (indices != 1 || dir != HDA_INPUT ||
+           get_wcaps_type(wcaps) != AC_WID_AUD_MIX)
+               return false;
+
+       if (snd_hda_get_raw_connections(codec, nid, &conn, 1) < 0)
+               return false;
+       /* the connection source is a stereo? */
+       wcaps = snd_hda_param_read(codec, conn, AC_PAR_AUDIO_WIDGET_CAP);
+       return !!(wcaps & AC_WCAP_STEREO);
+}
+
 static void print_amp_vals(struct snd_info_buffer *buffer,
                           struct hda_codec *codec, hda_nid_t nid,
-                          int dir, int stereo, int indices)
+                          int dir, unsigned int wcaps, int indices)
 {
        unsigned int val;
+       bool stereo;
        int i;
 
+       stereo = is_stereo_amps(codec, nid, dir, wcaps, indices);
+
        dir = dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
        for (i = 0; i < indices; i++) {
                snd_iprintf(buffer, " [");
@@ -757,12 +782,10 @@ static void print_codec_info(struct snd_info_entry *entry,
                            (codec->single_adc_amp &&
                             wid_type == AC_WID_AUD_IN))
                                print_amp_vals(buffer, codec, nid, HDA_INPUT,
-                                              wid_caps & AC_WCAP_STEREO,
-                                              1);
+                                              wid_caps, 1);
                        else
                                print_amp_vals(buffer, codec, nid, HDA_INPUT,
-                                              wid_caps & AC_WCAP_STEREO,
-                                              conn_len);
+                                              wid_caps, conn_len);
                }
                if (wid_caps & AC_WCAP_OUT_AMP) {
                        snd_iprintf(buffer, "  Amp-Out caps: ");
@@ -771,11 +794,10 @@ static void print_codec_info(struct snd_info_entry *entry,
                        if (wid_type == AC_WID_PIN &&
                            codec->pin_amp_workaround)
                                print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
-                                              wid_caps & AC_WCAP_STEREO,
-                                              conn_len);
+                                              wid_caps, conn_len);
                        else
                                print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
-                                              wid_caps & AC_WCAP_STEREO, 1);
+                                              wid_caps, 1);
                }
 
                switch (wid_type) {
index 1589c9b..dd2b3d9 100644 (file)
@@ -393,6 +393,7 @@ static const struct snd_pci_quirk cs420x_fixup_tbl[] = {
        SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81),
        SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122),
        SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101),
+       SND_PCI_QUIRK(0x106b, 0x5600, "MacBookAir 5,2", CS420X_MBP81),
        SND_PCI_QUIRK(0x106b, 0x5b00, "MacBookAir 4,2", CS420X_MBA42),
        SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE),
        {} /* terminator */
@@ -584,6 +585,7 @@ static int patch_cs420x(struct hda_codec *codec)
                return -ENOMEM;
 
        spec->gen.automute_hook = cs_automute;
+       codec->single_adc_amp = 1;
 
        snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl,
                           cs420x_fixups);
index fd3ed18..da67ea8 100644 (file)
@@ -223,6 +223,7 @@ enum {
        CXT_PINCFG_LENOVO_TP410,
        CXT_PINCFG_LEMOTE_A1004,
        CXT_PINCFG_LEMOTE_A1205,
+       CXT_PINCFG_COMPAQ_CQ60,
        CXT_FIXUP_STEREO_DMIC,
        CXT_FIXUP_INC_MIC_BOOST,
        CXT_FIXUP_HEADPHONE_MIC_PIN,
@@ -660,6 +661,15 @@ static const struct hda_fixup cxt_fixups[] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = cxt_pincfg_lemote,
        },
+       [CXT_PINCFG_COMPAQ_CQ60] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       /* 0x17 was falsely set up as a mic, it should 0x1d */
+                       { 0x17, 0x400001f0 },
+                       { 0x1d, 0x97a70120 },
+                       { }
+               }
+       },
        [CXT_FIXUP_STEREO_DMIC] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = cxt_fixup_stereo_dmic,
@@ -769,6 +779,7 @@ static const struct hda_model_fixup cxt5047_fixup_models[] = {
 };
 
 static const struct snd_pci_quirk cxt5051_fixups[] = {
+       SND_PCI_QUIRK(0x103c, 0x360b, "Compaq CQ60", CXT_PINCFG_COMPAQ_CQ60),
        SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
        {}
 };
index b67480f..4373ada 100644 (file)
@@ -317,7 +317,7 @@ static int adav80x_put_deemph(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
-       unsigned int deemph = ucontrol->value.enumerated.item[0];
+       unsigned int deemph = ucontrol->value.integer.value[0];
 
        if (deemph > 1)
                return -EINVAL;
@@ -333,7 +333,7 @@ static int adav80x_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
 
-       ucontrol->value.enumerated.item[0] = adav80x->deemph;
+       ucontrol->value.integer.value[0] = adav80x->deemph;
        return 0;
 };
 
index 70861c7..81b54a2 100644 (file)
@@ -76,7 +76,7 @@ static int ak4641_put_deemph(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
-       int deemph = ucontrol->value.enumerated.item[0];
+       int deemph = ucontrol->value.integer.value[0];
 
        if (deemph > 1)
                return -EINVAL;
@@ -92,7 +92,7 @@ static int ak4641_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
 
-       ucontrol->value.enumerated.item[0] = ak4641->deemph;
+       ucontrol->value.integer.value[0] = ak4641->deemph;
        return 0;
 };
 
index 632e89f..2a58b1d 100644 (file)
@@ -343,25 +343,25 @@ static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = {
 };
 
 static const struct snd_soc_dapm_route ak4671_intercon[] = {
-       {"DAC Left", "NULL", "PMPLL"},
-       {"DAC Right", "NULL", "PMPLL"},
-       {"ADC Left", "NULL", "PMPLL"},
-       {"ADC Right", "NULL", "PMPLL"},
+       {"DAC Left", NULL, "PMPLL"},
+       {"DAC Right", NULL, "PMPLL"},
+       {"ADC Left", NULL, "PMPLL"},
+       {"ADC Right", NULL, "PMPLL"},
 
        /* Outputs */
-       {"LOUT1", "NULL", "LOUT1 Mixer"},
-       {"ROUT1", "NULL", "ROUT1 Mixer"},
-       {"LOUT2", "NULL", "LOUT2 Mix Amp"},
-       {"ROUT2", "NULL", "ROUT2 Mix Amp"},
-       {"LOUT3", "NULL", "LOUT3 Mixer"},
-       {"ROUT3", "NULL", "ROUT3 Mixer"},
+       {"LOUT1", NULL, "LOUT1 Mixer"},
+       {"ROUT1", NULL, "ROUT1 Mixer"},
+       {"LOUT2", NULL, "LOUT2 Mix Amp"},
+       {"ROUT2", NULL, "ROUT2 Mix Amp"},
+       {"LOUT3", NULL, "LOUT3 Mixer"},
+       {"ROUT3", NULL, "ROUT3 Mixer"},
 
        {"LOUT1 Mixer", "DACL", "DAC Left"},
        {"ROUT1 Mixer", "DACR", "DAC Right"},
        {"LOUT2 Mixer", "DACHL", "DAC Left"},
        {"ROUT2 Mixer", "DACHR", "DAC Right"},
-       {"LOUT2 Mix Amp", "NULL", "LOUT2 Mixer"},
-       {"ROUT2 Mix Amp", "NULL", "ROUT2 Mixer"},
+       {"LOUT2 Mix Amp", NULL, "LOUT2 Mixer"},
+       {"ROUT2 Mix Amp", NULL, "ROUT2 Mixer"},
        {"LOUT3 Mixer", "DACSL", "DAC Left"},
        {"ROUT3 Mixer", "DACSR", "DAC Right"},
 
@@ -381,18 +381,18 @@ static const struct snd_soc_dapm_route ak4671_intercon[] = {
        {"LIN2", NULL, "Mic Bias"},
        {"RIN2", NULL, "Mic Bias"},
 
-       {"ADC Left", "NULL", "LIN MUX"},
-       {"ADC Right", "NULL", "RIN MUX"},
+       {"ADC Left", NULL, "LIN MUX"},
+       {"ADC Right", NULL, "RIN MUX"},
 
        /* Analog Loops */
-       {"LIN1 Mixing Circuit", "NULL", "LIN1"},
-       {"RIN1 Mixing Circuit", "NULL", "RIN1"},
-       {"LIN2 Mixing Circuit", "NULL", "LIN2"},
-       {"RIN2 Mixing Circuit", "NULL", "RIN2"},
-       {"LIN3 Mixing Circuit", "NULL", "LIN3"},
-       {"RIN3 Mixing Circuit", "NULL", "RIN3"},
-       {"LIN4 Mixing Circuit", "NULL", "LIN4"},
-       {"RIN4 Mixing Circuit", "NULL", "RIN4"},
+       {"LIN1 Mixing Circuit", NULL, "LIN1"},
+       {"RIN1 Mixing Circuit", NULL, "RIN1"},
+       {"LIN2 Mixing Circuit", NULL, "LIN2"},
+       {"RIN2 Mixing Circuit", NULL, "RIN2"},
+       {"LIN3 Mixing Circuit", NULL, "LIN3"},
+       {"RIN3 Mixing Circuit", NULL, "RIN3"},
+       {"LIN4 Mixing Circuit", NULL, "LIN4"},
+       {"RIN4 Mixing Circuit", NULL, "RIN4"},
 
        {"LOUT1 Mixer", "LINL1", "LIN1 Mixing Circuit"},
        {"ROUT1 Mixer", "RINR1", "RIN1 Mixing Circuit"},
index 79a4efc..7d3a6ac 100644 (file)
@@ -286,7 +286,7 @@ static int cs4271_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
 
-       ucontrol->value.enumerated.item[0] = cs4271->deemph;
+       ucontrol->value.integer.value[0] = cs4271->deemph;
        return 0;
 }
 
@@ -296,7 +296,7 @@ static int cs4271_put_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
 
-       cs4271->deemph = ucontrol->value.enumerated.item[0];
+       cs4271->deemph = ucontrol->value.integer.value[0];
        return cs4271_set_deemph(codec);
 }
 
index ffe9617..911c26c 100644 (file)
@@ -876,11 +876,11 @@ static const struct snd_soc_dapm_widget da732x_dapm_widgets[] = {
 
 static const struct snd_soc_dapm_route da732x_dapm_routes[] = {
        /* Inputs */
-       {"AUX1L PGA", "NULL", "AUX1L"},
-       {"AUX1R PGA", "NULL", "AUX1R"},
+       {"AUX1L PGA", NULL, "AUX1L"},
+       {"AUX1R PGA", NULL, "AUX1R"},
        {"MIC1 PGA", NULL, "MIC1"},
-       {"MIC2 PGA", "NULL", "MIC2"},
-       {"MIC3 PGA", "NULL", "MIC3"},
+       {"MIC2 PGA", NULL, "MIC2"},
+       {"MIC3 PGA", NULL, "MIC3"},
 
        /* Capture Path */
        {"ADC1 Left MUX", "MIC1", "MIC1 PGA"},
index f273251..c5f35a0 100644 (file)
@@ -120,7 +120,7 @@ static int es8328_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
 
-       ucontrol->value.enumerated.item[0] = es8328->deemph;
+       ucontrol->value.integer.value[0] = es8328->deemph;
        return 0;
 }
 
@@ -129,7 +129,7 @@ static int es8328_put_deemph(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
-       int deemph = ucontrol->value.enumerated.item[0];
+       int deemph = ucontrol->value.integer.value[0];
        int ret;
 
        if (deemph > 1)
index a722a02..477e13d 100644 (file)
@@ -118,7 +118,7 @@ static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
 
-       ucontrol->value.enumerated.item[0] = priv->deemph;
+       ucontrol->value.integer.value[0] = priv->deemph;
 
        return 0;
 }
@@ -129,7 +129,7 @@ static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
 
-       priv->deemph = ucontrol->value.enumerated.item[0];
+       priv->deemph = ucontrol->value.integer.value[0];
 
        return pcm1681_set_deemph(codec);
 }
index f374840..9b541e5 100644 (file)
@@ -1198,7 +1198,7 @@ static struct dmi_system_id dmi_dell_dino[] = {
                .ident = "Dell Dino",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_BOARD_NAME, "0144P8")
+                       DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343")
                }
        },
        { }
index e182e65..3593a14 100644 (file)
@@ -1151,13 +1151,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
                /* Enable VDDC charge pump */
                ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP;
        } else if (vddio >= 3100 && vdda >= 3100) {
-               /*
-                * if vddio and vddd > 3.1v,
-                * charge pump should be clean before set ana_pwr
-                */
-               snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
-                               SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
-
+               ana_pwr &= ~SGTL5000_VDDC_CHRGPMP_POWERUP;
                /* VDDC use VDDIO rail */
                lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
                lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO <<
index 47b257e..82095d6 100644 (file)
@@ -538,8 +538,8 @@ static const struct snd_soc_dapm_route sn95031_audio_map[] = {
        /* speaker map */
        { "IHFOUTL", NULL, "Speaker Rail"},
        { "IHFOUTR", NULL, "Speaker Rail"},
-       { "IHFOUTL", "NULL", "Speaker Left Playback"},
-       { "IHFOUTR", "NULL", "Speaker Right Playback"},
+       { "IHFOUTL", NULL, "Speaker Left Playback"},
+       { "IHFOUTR", NULL, "Speaker Right Playback"},
        { "Speaker Left Playback", NULL, "Speaker Left Filter"},
        { "Speaker Right Playback", NULL, "Speaker Right Filter"},
        { "Speaker Left Filter", NULL, "IHFDAC Left"},
index 249ef5c..32942be 100644 (file)
@@ -281,7 +281,7 @@ static int tas5086_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
 
-       ucontrol->value.enumerated.item[0] = priv->deemph;
+       ucontrol->value.integer.value[0] = priv->deemph;
 
        return 0;
 }
@@ -292,7 +292,7 @@ static int tas5086_put_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
 
-       priv->deemph = ucontrol->value.enumerated.item[0];
+       priv->deemph = ucontrol->value.integer.value[0];
 
        return tas5086_set_deemph(codec);
 }
index 8d9de49..21d5402 100644 (file)
@@ -610,7 +610,7 @@ static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
 
-       ucontrol->value.enumerated.item[0] = wm2000->anc_active;
+       ucontrol->value.integer.value[0] = wm2000->anc_active;
 
        return 0;
 }
@@ -620,7 +620,7 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
-       int anc_active = ucontrol->value.enumerated.item[0];
+       int anc_active = ucontrol->value.integer.value[0];
        int ret;
 
        if (anc_active > 1)
@@ -643,7 +643,7 @@ static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
 
-       ucontrol->value.enumerated.item[0] = wm2000->spk_ena;
+       ucontrol->value.integer.value[0] = wm2000->spk_ena;
 
        return 0;
 }
@@ -653,7 +653,7 @@ static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
-       int val = ucontrol->value.enumerated.item[0];
+       int val = ucontrol->value.integer.value[0];
        int ret;
 
        if (val > 1)
index 098c143..c6d1053 100644 (file)
@@ -125,7 +125,7 @@ static int wm8731_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
 
-       ucontrol->value.enumerated.item[0] = wm8731->deemph;
+       ucontrol->value.integer.value[0] = wm8731->deemph;
 
        return 0;
 }
@@ -135,7 +135,7 @@ static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
-       int deemph = ucontrol->value.enumerated.item[0];
+       int deemph = ucontrol->value.integer.value[0];
        int ret = 0;
 
        if (deemph > 1)
index dde462c..04b04f8 100644 (file)
@@ -442,7 +442,7 @@ static int wm8903_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
 
-       ucontrol->value.enumerated.item[0] = wm8903->deemph;
+       ucontrol->value.integer.value[0] = wm8903->deemph;
 
        return 0;
 }
@@ -452,7 +452,7 @@ static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
-       int deemph = ucontrol->value.enumerated.item[0];
+       int deemph = ucontrol->value.integer.value[0];
        int ret = 0;
 
        if (deemph > 1)
index d3b3f57..215e93c 100644 (file)
@@ -525,7 +525,7 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
 
-       ucontrol->value.enumerated.item[0] = wm8904->deemph;
+       ucontrol->value.integer.value[0] = wm8904->deemph;
        return 0;
 }
 
@@ -534,7 +534,7 @@ static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
-       int deemph = ucontrol->value.enumerated.item[0];
+       int deemph = ucontrol->value.integer.value[0];
 
        if (deemph > 1)
                return -EINVAL;
index 1ab2d46..00bec91 100644 (file)
@@ -393,7 +393,7 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
 
-       ucontrol->value.enumerated.item[0] = wm8955->deemph;
+       ucontrol->value.integer.value[0] = wm8955->deemph;
        return 0;
 }
 
@@ -402,7 +402,7 @@ static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
-       int deemph = ucontrol->value.enumerated.item[0];
+       int deemph = ucontrol->value.integer.value[0];
 
        if (deemph > 1)
                return -EINVAL;
index cf8fecf..3035d98 100644 (file)
@@ -184,7 +184,7 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
 
-       ucontrol->value.enumerated.item[0] = wm8960->deemph;
+       ucontrol->value.integer.value[0] = wm8960->deemph;
        return 0;
 }
 
@@ -193,7 +193,7 @@ static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
        struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
-       int deemph = ucontrol->value.enumerated.item[0];
+       int deemph = ucontrol->value.integer.value[0];
 
        if (deemph > 1)
                return -EINVAL;
index 9517571..98c9525 100644 (file)
@@ -180,7 +180,7 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol,
        struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
        struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
        struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
-       unsigned int val = ucontrol->value.enumerated.item[0];
+       unsigned int val = ucontrol->value.integer.value[0];
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        unsigned int mixer, mask, shift, old;
@@ -193,7 +193,7 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol,
 
        mutex_lock(&wm9712->lock);
        old = wm9712->hp_mixer[mixer];
-       if (ucontrol->value.enumerated.item[0])
+       if (ucontrol->value.integer.value[0])
                wm9712->hp_mixer[mixer] |= mask;
        else
                wm9712->hp_mixer[mixer] &= ~mask;
@@ -231,7 +231,7 @@ static int wm9712_hp_mixer_get(struct snd_kcontrol *kcontrol,
        mixer = mc->shift >> 8;
        shift = mc->shift & 0xff;
 
-       ucontrol->value.enumerated.item[0] =
+       ucontrol->value.integer.value[0] =
                (wm9712->hp_mixer[mixer] >> shift) & 1;
 
        return 0;
index 6822291..7955295 100644 (file)
@@ -255,7 +255,7 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol,
        struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
        struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
        struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
-       unsigned int val = ucontrol->value.enumerated.item[0];
+       unsigned int val = ucontrol->value.integer.value[0];
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        unsigned int mixer, mask, shift, old;
@@ -268,7 +268,7 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol,
 
        mutex_lock(&wm9713->lock);
        old = wm9713->hp_mixer[mixer];
-       if (ucontrol->value.enumerated.item[0])
+       if (ucontrol->value.integer.value[0])
                wm9713->hp_mixer[mixer] |= mask;
        else
                wm9713->hp_mixer[mixer] &= ~mask;
@@ -306,7 +306,7 @@ static int wm9713_hp_mixer_get(struct snd_kcontrol *kcontrol,
        mixer = mc->shift >> 8;
        shift = mc->shift & 0xff;
 
-       ucontrol->value.enumerated.item[0] =
+       ucontrol->value.integer.value[0] =
                (wm9713->hp_mixer[mixer] >> shift) & 1;
 
        return 0;
index 75870c0..91eb3ae 100644 (file)
@@ -1049,7 +1049,7 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
                                enum spdif_txrate index, bool round)
 {
        const u32 rate[] = { 32000, 44100, 48000, 96000, 192000 };
-       bool is_sysclk = clk == spdif_priv->sysclk;
+       bool is_sysclk = clk_is_match(clk, spdif_priv->sysclk);
        u64 rate_ideal, rate_actual, sub;
        u32 sysclk_dfmin, sysclk_dfmax;
        u32 txclk_df, sysclk_df, arate;
@@ -1143,7 +1143,7 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv,
                        spdif_priv->txclk_src[index], rate[index]);
        dev_dbg(&pdev->dev, "use txclk df %d for %dHz sample rate\n",
                        spdif_priv->txclk_df[index], rate[index]);
-       if (spdif_priv->txclk[index] == spdif_priv->sysclk)
+       if (clk_is_match(spdif_priv->txclk[index], spdif_priv->sysclk))
                dev_dbg(&pdev->dev, "use sysclk df %d for %dHz sample rate\n",
                                spdif_priv->sysclk_df[index], rate[index]);
        dev_dbg(&pdev->dev, "the best rate for %dHz sample rate is %dHz\n",
index b9fabbf..6b0c8f7 100644 (file)
@@ -603,7 +603,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
        factor = (div2 + 1) * (7 * psr + 1) * 2;
 
        for (i = 0; i < 255; i++) {
-               tmprate = freq * factor * (i + 2);
+               tmprate = freq * factor * (i + 1);
 
                if (baudclk_is_used)
                        clkrate = clk_get_rate(ssi_private->baudclk);
@@ -1227,7 +1227,7 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
        ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0;
        ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + CCSR_SSI_SRX0;
 
-       ret = !of_property_read_u32_array(np, "dmas", dmas, 4);
+       ret = of_property_read_u32_array(np, "dmas", dmas, 4);
        if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
                ssi_private->use_dual_fifo = true;
                /* When using dual fifo mode, we need to keep watermark
index c42ffae..402b728 100644 (file)
@@ -207,9 +207,6 @@ static int hsw_parse_fw_image(struct sst_fw *sst_fw)
                module = (void *)module + sizeof(*module) + module->mod_size;
        }
 
-       /* allocate scratch mem regions */
-       sst_block_alloc_scratch(dsp);
-
        return 0;
 }
 
index 394af56..863a9ca 100644 (file)
@@ -1732,6 +1732,7 @@ static void sst_hsw_drop_all(struct sst_hsw *hsw)
 int sst_hsw_dsp_load(struct sst_hsw *hsw)
 {
        struct sst_dsp *dsp = hsw->dsp;
+       struct sst_fw *sst_fw, *t;
        int ret;
 
        dev_dbg(hsw->dev, "loading audio DSP....");
@@ -1748,12 +1749,17 @@ int sst_hsw_dsp_load(struct sst_hsw *hsw)
                return ret;
        }
 
-       ret = sst_fw_reload(hsw->sst_fw);
-       if (ret < 0) {
-               dev_err(hsw->dev, "error: SST FW reload failed\n");
-               sst_dsp_dma_put_channel(dsp);
-               return -ENOMEM;
+       list_for_each_entry_safe_reverse(sst_fw, t, &dsp->fw_list, list) {
+               ret = sst_fw_reload(sst_fw);
+               if (ret < 0) {
+                       dev_err(hsw->dev, "error: SST FW reload failed\n");
+                       sst_dsp_dma_put_channel(dsp);
+                       return -ENOMEM;
+               }
        }
+       ret = sst_block_alloc_scratch(hsw->dsp);
+       if (ret < 0)
+               return -EINVAL;
 
        sst_dsp_dma_put_channel(dsp);
        return 0;
@@ -1809,12 +1815,17 @@ int sst_hsw_dsp_runtime_suspend(struct sst_hsw *hsw)
 
 int sst_hsw_dsp_runtime_sleep(struct sst_hsw *hsw)
 {
-       sst_fw_unload(hsw->sst_fw);
-       sst_block_free_scratch(hsw->dsp);
+       struct sst_fw *sst_fw, *t;
+       struct sst_dsp *dsp = hsw->dsp;
+
+       list_for_each_entry_safe(sst_fw, t, &dsp->fw_list, list) {
+               sst_fw_unload(sst_fw);
+       }
+       sst_block_free_scratch(dsp);
 
        hsw->boot_complete = false;
 
-       sst_dsp_sleep(hsw->dsp);
+       sst_dsp_sleep(dsp);
 
        return 0;
 }
@@ -1943,6 +1954,11 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
                goto fw_err;
        }
 
+       /* allocate scratch mem regions */
+       ret = sst_block_alloc_scratch(hsw->dsp);
+       if (ret < 0)
+               goto boot_err;
+
        /* wait for DSP boot completion */
        sst_dsp_boot(hsw->dsp);
        ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete,
index def7d82..d194830 100644 (file)
@@ -579,7 +579,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
                if (PTR_ERR(priv->extclk) == -EPROBE_DEFER)
                        return -EPROBE_DEFER;
        } else {
-               if (priv->extclk == priv->clk) {
+               if (clk_is_match(priv->extclk, priv->clk)) {
                        devm_clk_put(&pdev->dev, priv->extclk);
                        priv->extclk = ERR_PTR(-EINVAL);
                } else {
index 30579ca..e5c9908 100644 (file)
@@ -347,6 +347,8 @@ static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
        if (!buf)
                return -ENOMEM;
 
+       mutex_lock(&client_mutex);
+
        list_for_each_entry(codec, &codec_list, list) {
                len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
                               codec->component.name);
@@ -358,6 +360,8 @@ static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
                }
        }
 
+       mutex_unlock(&client_mutex);
+
        if (ret >= 0)
                ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
 
@@ -382,6 +386,8 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf,
        if (!buf)
                return -ENOMEM;
 
+       mutex_lock(&client_mutex);
+
        list_for_each_entry(component, &component_list, list) {
                list_for_each_entry(dai, &component->dai_list, list) {
                        len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
@@ -395,6 +401,8 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf,
                }
        }
 
+       mutex_unlock(&client_mutex);
+
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
 
        kfree(buf);
@@ -418,6 +426,8 @@ static ssize_t platform_list_read_file(struct file *file,
        if (!buf)
                return -ENOMEM;
 
+       mutex_lock(&client_mutex);
+
        list_for_each_entry(platform, &platform_list, list) {
                len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n",
                               platform->component.name);
@@ -429,6 +439,8 @@ static ssize_t platform_list_read_file(struct file *file,
                }
        }
 
+       mutex_unlock(&client_mutex);
+
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
 
        kfree(buf);
@@ -836,6 +848,8 @@ static struct snd_soc_component *soc_find_component(
 {
        struct snd_soc_component *component;
 
+       lockdep_assert_held(&client_mutex);
+
        list_for_each_entry(component, &component_list, list) {
                if (of_node) {
                        if (component->dev->of_node == of_node)
@@ -854,6 +868,8 @@ static struct snd_soc_dai *snd_soc_find_dai(
        struct snd_soc_component *component;
        struct snd_soc_dai *dai;
 
+       lockdep_assert_held(&client_mutex);
+
        /* Find CPU DAI from registered DAIs*/
        list_for_each_entry(component, &component_list, list) {
                if (dlc->of_node && component->dev->of_node != dlc->of_node)
@@ -1508,6 +1524,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
        struct snd_soc_codec *codec;
        int ret, i, order;
 
+       mutex_lock(&client_mutex);
        mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
 
        /* bind DAIs */
@@ -1662,6 +1679,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
        card->instantiated = 1;
        snd_soc_dapm_sync(&card->dapm);
        mutex_unlock(&card->mutex);
+       mutex_unlock(&client_mutex);
 
        return 0;
 
@@ -1680,6 +1698,7 @@ card_probe_error:
 
 base_error:
        mutex_unlock(&card->mutex);
+       mutex_unlock(&client_mutex);
 
        return ret;
 }
@@ -2713,13 +2732,6 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component)
        list_del(&component->list);
 }
 
-static void snd_soc_component_del(struct snd_soc_component *component)
-{
-       mutex_lock(&client_mutex);
-       snd_soc_component_del_unlocked(component);
-       mutex_unlock(&client_mutex);
-}
-
 int snd_soc_register_component(struct device *dev,
                               const struct snd_soc_component_driver *cmpnt_drv,
                               struct snd_soc_dai_driver *dai_drv,
@@ -2767,14 +2779,17 @@ void snd_soc_unregister_component(struct device *dev)
 {
        struct snd_soc_component *cmpnt;
 
+       mutex_lock(&client_mutex);
        list_for_each_entry(cmpnt, &component_list, list) {
                if (dev == cmpnt->dev && cmpnt->registered_as_component)
                        goto found;
        }
+       mutex_unlock(&client_mutex);
        return;
 
 found:
-       snd_soc_component_del(cmpnt);
+       snd_soc_component_del_unlocked(cmpnt);
+       mutex_unlock(&client_mutex);
        snd_soc_component_cleanup(cmpnt);
        kfree(cmpnt);
 }
@@ -2882,10 +2897,14 @@ struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev)
 {
        struct snd_soc_platform *platform;
 
+       mutex_lock(&client_mutex);
        list_for_each_entry(platform, &platform_list, list) {
-               if (dev == platform->dev)
+               if (dev == platform->dev) {
+                       mutex_unlock(&client_mutex);
                        return platform;
+               }
        }
+       mutex_unlock(&client_mutex);
 
        return NULL;
 }
@@ -3090,15 +3109,15 @@ void snd_soc_unregister_codec(struct device *dev)
 {
        struct snd_soc_codec *codec;
 
+       mutex_lock(&client_mutex);
        list_for_each_entry(codec, &codec_list, list) {
                if (dev == codec->dev)
                        goto found;
        }
+       mutex_unlock(&client_mutex);
        return;
 
 found:
-
-       mutex_lock(&client_mutex);
        list_del(&codec->list);
        snd_soc_component_del_unlocked(&codec->component);
        mutex_unlock(&client_mutex);
index 67d4765..07f984d 100644 (file)
@@ -1773,6 +1773,36 @@ YAMAHA_DEVICE(0x7010, "UB99"),
                }
        }
 },
+{
+       USB_DEVICE(0x0582, 0x0159),
+       .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+               /* .vendor_name = "Roland", */
+               /* .product_name = "UA-22", */
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_COMPOSITE,
+               .data = (const struct snd_usb_audio_quirk[]) {
+                       {
+                               .ifnum = 0,
+                               .type = QUIRK_AUDIO_STANDARD_INTERFACE
+                       },
+                       {
+                               .ifnum = 1,
+                               .type = QUIRK_AUDIO_STANDARD_INTERFACE
+                       },
+                       {
+                               .ifnum = 2,
+                               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+                               .data = & (const struct snd_usb_midi_endpoint_info) {
+                                       .out_cables = 0x0001,
+                                       .in_cables = 0x0001
+                               }
+                       },
+                       {
+                               .ifnum = -1
+                       }
+               }
+       }
+},
 /* this catches most recent vendor-specific Roland devices */
 {
        .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
index 61bf912..9d9db3b 100644 (file)
@@ -30,6 +30,8 @@ static int disasm_line__parse(char *line, char **namep, char **rawp);
 
 static void ins__delete(struct ins_operands *ops)
 {
+       if (ops == NULL)
+               return;
        zfree(&ops->source.raw);
        zfree(&ops->source.name);
        zfree(&ops->target.raw);
index 3ed7c04..2e2ba2e 100644 (file)
@@ -209,7 +209,7 @@ $(OUTPUT)%.o: %.c
 
 $(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ)
        $(ECHO) "  CC      " $@
-       $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -Wl,-rpath=./ -lrt -lpci -L$(OUTPUT) -o $@
+       $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -lrt -lpci -L$(OUTPUT) -o $@
        $(QUIET) $(STRIPCMD) $@
 
 $(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC)
index e238c95..8d5d1d2 100644 (file)
@@ -30,7 +30,7 @@ static int execveat_(int fd, const char *path, char **argv, char **envp,
 #ifdef __NR_execveat
        return syscall(__NR_execveat, fd, path, argv, envp, flags);
 #else
-       errno = -ENOSYS;
+       errno = ENOSYS;
        return -1;
 #endif
 }
@@ -234,6 +234,14 @@ static int run_tests(void)
        int fd_cloexec = open_or_die("execveat", O_RDONLY|O_CLOEXEC);
        int fd_script_cloexec = open_or_die("script", O_RDONLY|O_CLOEXEC);
 
+       /* Check if we have execveat at all, and bail early if not */
+       errno = 0;
+       execveat_(-1, NULL, NULL, NULL, 0);
+       if (errno == ENOSYS) {
+               printf("[FAIL] ENOSYS calling execveat - no kernel support?\n");
+               return 1;
+       }
+
        /* Change file position to confirm it doesn't affect anything */
        lseek(fd, 10, SEEK_SET);
 
index a0a7b5d..f9b9c7c 100644 (file)
@@ -72,6 +72,8 @@ static void vgic_v2_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
 {
        if (!(lr_desc.state & LR_STATE_MASK))
                vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr |= (1ULL << lr);
+       else
+               vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr &= ~(1ULL << lr);
 }
 
 static u64 vgic_v2_get_elrsr(const struct kvm_vcpu *vcpu)
@@ -84,6 +86,11 @@ static u64 vgic_v2_get_eisr(const struct kvm_vcpu *vcpu)
        return vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr;
 }
 
+static void vgic_v2_clear_eisr(struct kvm_vcpu *vcpu)
+{
+       vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr = 0;
+}
+
 static u32 vgic_v2_get_interrupt_status(const struct kvm_vcpu *vcpu)
 {
        u32 misr = vcpu->arch.vgic_cpu.vgic_v2.vgic_misr;
@@ -148,6 +155,7 @@ static const struct vgic_ops vgic_v2_ops = {
        .sync_lr_elrsr          = vgic_v2_sync_lr_elrsr,
        .get_elrsr              = vgic_v2_get_elrsr,
        .get_eisr               = vgic_v2_get_eisr,
+       .clear_eisr             = vgic_v2_clear_eisr,
        .get_interrupt_status   = vgic_v2_get_interrupt_status,
        .enable_underflow       = vgic_v2_enable_underflow,
        .disable_underflow      = vgic_v2_disable_underflow,
index 3a62d8a..dff0602 100644 (file)
@@ -104,6 +104,8 @@ static void vgic_v3_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
 {
        if (!(lr_desc.state & LR_STATE_MASK))
                vcpu->arch.vgic_cpu.vgic_v3.vgic_elrsr |= (1U << lr);
+       else
+               vcpu->arch.vgic_cpu.vgic_v3.vgic_elrsr &= ~(1U << lr);
 }
 
 static u64 vgic_v3_get_elrsr(const struct kvm_vcpu *vcpu)
@@ -116,6 +118,11 @@ static u64 vgic_v3_get_eisr(const struct kvm_vcpu *vcpu)
        return vcpu->arch.vgic_cpu.vgic_v3.vgic_eisr;
 }
 
+static void vgic_v3_clear_eisr(struct kvm_vcpu *vcpu)
+{
+       vcpu->arch.vgic_cpu.vgic_v3.vgic_eisr = 0;
+}
+
 static u32 vgic_v3_get_interrupt_status(const struct kvm_vcpu *vcpu)
 {
        u32 misr = vcpu->arch.vgic_cpu.vgic_v3.vgic_misr;
@@ -192,6 +199,7 @@ static const struct vgic_ops vgic_v3_ops = {
        .sync_lr_elrsr          = vgic_v3_sync_lr_elrsr,
        .get_elrsr              = vgic_v3_get_elrsr,
        .get_eisr               = vgic_v3_get_eisr,
+       .clear_eisr             = vgic_v3_clear_eisr,
        .get_interrupt_status   = vgic_v3_get_interrupt_status,
        .enable_underflow       = vgic_v3_enable_underflow,
        .disable_underflow      = vgic_v3_disable_underflow,
index 0cc6ab6..c9f60f5 100644 (file)
@@ -883,6 +883,11 @@ static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu)
        return vgic_ops->get_eisr(vcpu);
 }
 
+static inline void vgic_clear_eisr(struct kvm_vcpu *vcpu)
+{
+       vgic_ops->clear_eisr(vcpu);
+}
+
 static inline u32 vgic_get_interrupt_status(struct kvm_vcpu *vcpu)
 {
        return vgic_ops->get_interrupt_status(vcpu);
@@ -922,6 +927,7 @@ static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
        vgic_set_lr(vcpu, lr_nr, vlr);
        clear_bit(lr_nr, vgic_cpu->lr_used);
        vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
+       vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
 }
 
 /*
@@ -978,6 +984,7 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
                        BUG_ON(!test_bit(lr, vgic_cpu->lr_used));
                        vlr.state |= LR_STATE_PENDING;
                        vgic_set_lr(vcpu, lr, vlr);
+                       vgic_sync_lr_elrsr(vcpu, lr, vlr);
                        return true;
                }
        }
@@ -999,6 +1006,7 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
                vlr.state |= LR_EOI_INT;
 
        vgic_set_lr(vcpu, lr, vlr);
+       vgic_sync_lr_elrsr(vcpu, lr, vlr);
 
        return true;
 }
@@ -1136,6 +1144,14 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
        if (status & INT_STATUS_UNDERFLOW)
                vgic_disable_underflow(vcpu);
 
+       /*
+        * In the next iterations of the vcpu loop, if we sync the vgic state
+        * after flushing it, but before entering the guest (this happens for
+        * pending signals and vmid rollovers), then make sure we don't pick
+        * up any old maintenance interrupts here.
+        */
+       vgic_clear_eisr(vcpu);
+
        return level_pending;
 }
 
@@ -1583,8 +1599,10 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
         * emulation. So check this here again. KVM_CREATE_DEVICE does
         * the proper checks already.
         */
-       if (type == KVM_DEV_TYPE_ARM_VGIC_V2 && !vgic->can_emulate_gicv2)
-               return -ENODEV;
+       if (type == KVM_DEV_TYPE_ARM_VGIC_V2 && !vgic->can_emulate_gicv2) {
+               ret = -ENODEV;
+               goto out;
+       }
 
        /*
         * Any time a vcpu is run, vcpu_load is called which tries to grab the
index a109370..a2214d9 100644 (file)
@@ -2492,6 +2492,7 @@ static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
        case KVM_CAP_SIGNAL_MSI:
 #endif
 #ifdef CONFIG_HAVE_KVM_IRQFD
+       case KVM_CAP_IRQFD:
        case KVM_CAP_IRQFD_RESAMPLE:
 #endif
        case KVM_CAP_CHECK_EXTENSION_VM: