Kyle McMartin 0c652ad
git clone ssh://git.fedorahosted.org/git/kernel-arm64.git
Kyle McMartin 0c652ad
git diff -p master...origin/devel >kernel-arm64.patch
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 0555d24c0fb9ce825a0eb16f1b8b4a73f5014408
Kyle McMartin 0c652ad
Author: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
Date:   Tue Jun 24 23:16:45 2014 -0400
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    perf: fix arm64 build error
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    I'm seeing the following build error on arm64:
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
      In file included from util/event.c:3:0:
Kyle McMartin 0c652ad
      util/event.h:95:17: error: 'PERF_REGS_MAX' undeclared here (not in a function)
Kyle McMartin 0c652ad
        u64 cache_regs[PERF_REGS_MAX];
Kyle McMartin 0c652ad
                     ^
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    This patch adds a PEFF_REGS_MAX definition for arm64.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit ab1e5ae69aa0c7461a305c1f161229f8a22aff2b
Kyle McMartin 0c652ad
Author: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
Date:   Mon Jun 23 00:34:17 2014 -0400
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    arm64: fix CONFIG_ZONE_DMA on systems with no 32-bit addressable DRAM
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Commit 2d5a5612bc (arm64: Limit the CMA buffer to 32-bit if ZONE_DMA)
Kyle McMartin 0c652ad
    forces the CMA buffer to be 32-bit addressable if CONFIG_ZONE_DMA is
Kyle McMartin 0c652ad
    defined. This breaks CMA on platforms with no 32-bit addressable DRAM.
Kyle McMartin 0c652ad
    This patch checks to make sure there is 32-bit addressable DRAM before
Kyle McMartin 0c652ad
    setting the 32-bit limit. If there is none, no limit is placed on the
Kyle McMartin 0c652ad
    CMA buffer. This allows a single kernel (with CONFIG_ZONE_DMA defined)
Kyle McMartin 0c652ad
    to support platforms requiring the 32-bit limit and platforms with no
Kyle McMartin 0c652ad
    32-bit limit.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit e1651b99e0dc0f1e92dbe9ef34ff33496dce94b2
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:43 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    arm64: KVM: vgic: add GICv3 world switch
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Introduce the GICv3 world switch code and helper functions, enabling
Kyle McMartin 0c652ad
    GICv2 emulation on GICv3 hardware.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit a0806e54bfb522e50530e356abe1108e108a1430
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:42 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    KVM: ARM: vgic: add the GICv3 backend
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Introduce the support code for emulating a GICv2 on top of GICv3
Kyle McMartin 0c652ad
    hardware.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 813813c877235d7a4499546913e360ca958e57a7
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:41 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    arm64: KVM: move HCR_EL2.{IMO, FMO} manipulation into the vgic switch code
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    GICv3 requires the IMO and FMO bits to be tightly coupled with some
Kyle McMartin 0c652ad
    of the interrupt controller's register switch.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    In order to have similar code paths, move the manipulation of these
Kyle McMartin 0c652ad
    bits to the GICv2 switch code.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 298ecc28f3f58453e56c2e5b6891679480fe32f9
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:40 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    arm64: KVM: split GICv2 world switch from hyp code
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Move the GICv2 world switch code into its own file, and add the
Kyle McMartin 0c652ad
    necessary indirection to the arm64 switch code.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Also introduce a new type field to the vgic_params structure.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 701b0fd0ac4c260fbe364248710bf37bdffde360
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:39 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    arm64: KVM: remove __kvm_hyp_code_{start, end} from hyp.S
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    We already have __hyp_text_{start,end} to express the boundaries
Kyle McMartin 0c652ad
    of the HYP text section, and __kvm_hyp_code_{start,end} are getting
Kyle McMartin 0c652ad
    in the way of a more modular world switch code.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Just turn __kvm_hyp_code_{start,end} into #defines mapping the
Kyle McMartin 0c652ad
    linker-emited symbols.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 54f2e57b90ce894bb7312968344faf16624e7546
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:38 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    KVM: ARM: vgic: revisit implementation of irqchip_in_kernel
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    So far, irqchip_in_kernel() was implemented by testing the value of
Kyle McMartin 0c652ad
    vctrl_base, which worked fine with GICv2.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    With GICv3, this field is useless, as we're using system registers
Kyle McMartin 0c652ad
    instead of a emmory mapped interface. To solve this, add a boolean
Kyle McMartin 0c652ad
    flag indicating if the we're using a vgic or not.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 758dbee6188c8313ca4787e7f49d3959666229de
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:37 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    KVM: ARM: vgic: split GICv2 backend from the main vgic code
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Brutally hack the innocent vgic code, and move the GICv2 specific code
Kyle McMartin 0c652ad
    to its own file, using vgic_ops and vgic_params as a way to pass
Kyle McMartin 0c652ad
    information between the two blocks.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 1b35a44bd60fb52bd919705b98d3ab5f5f2e0e7a
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:36 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    KVM: ARM: introduce vgic_params structure
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Move all the data specific to a given GIC implementation into its own
Kyle McMartin 0c652ad
    little structure.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 33b5df2e6295cec0a2666b0e6f5d55778bdebd1e
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:35 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    KVM: ARM: vgic: introduce vgic_enable
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Move the code dealing with enabling the VGIC on to vgic_ops.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit b5113a5f316d899b8fde3ac8025715bb15582347
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:34 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    KVM: ARM: vgic: abstract VMCR access
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Instead of directly messing with with the GICH_VMCR bits for the CPU
Kyle McMartin 0c652ad
    interface save/restore code, add accessors that encode/decode the
Kyle McMartin 0c652ad
    entire set of registers exposed by VMCR.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Not the most efficient thing, but given that this code is only used
Kyle McMartin 0c652ad
    by the save/restore code, performance is far from being critical.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit f32f60e78a61c7f1878e8576a944820db713d6bf
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:33 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    KVM: ARM: vgic: move underflow handling to vgic_ops
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Move the code dealing with LR underflow handling to its own functions,
Kyle McMartin 0c652ad
    and make them accessible through vgic_ops.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 1c377524d163ce244e0567db0987b501307750bb
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:32 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    KVM: ARM: vgic: abstract MISR decoding
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Instead of directly dealing with the GICH_MISR bits, move the code to
Kyle McMartin 0c652ad
    its own function and use a couple of public flags to represent the
Kyle McMartin 0c652ad
    actual state.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit cf16a437bb41f188a24142bef17ccc96f54ee29a
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:31 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    KVM: ARM: vgic: abstract EISR bitmap access
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Move the GICH_EISR access to its own function.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 8e35c914d0fee0ed9334336590f72df618c42d44
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:30 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    KVM: ARM: vgic: abstract access to the ELRSR bitmap
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Move the GICH_ELRSR access to its own functions, and add them to
Kyle McMartin 0c652ad
    the vgic_ops structure.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 5e74572029116124aba6e057aba2f7106b651661
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:29 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    KVM: ARM: vgic: introduce vgic_ops and LR manipulation primitives
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    In order to split the various register manipulation from the main vgic
Kyle McMartin 0c652ad
    code, introduce a vgic_ops structure, and start by abstracting the
Kyle McMartin 0c652ad
    LR manipulation code with a couple of accessors.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 840d3614b64ad26e0f510bd2ef78bf427d91f778
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:28 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    KVM: arm/arm64: vgic: move GICv2 registers to their own structure
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    In order to make way for the GICv3 registers, move the v2-specific
Kyle McMartin 0c652ad
    registers to their own structure.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 07a7980c0ca48f940b97a7be30db7700317813de
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:27 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    arm64: boot protocol documentation update for GICv3
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Linux has some requirements that must be satisfied in order to boot
Kyle McMartin 0c652ad
    on a system built with a GICv3.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit fb16d46188b56559112b10eb9d4cc10ff2d85c12
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:26 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    arm64: GICv3 device tree binding documentation
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Add the necessary documentation to support GICv3.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Cc: Thomas Gleixner <tglx@linutronix.de>
Kyle McMartin 0c652ad
    Cc: Mark Rutland <mark.rutland@arm.com>
Kyle McMartin 0c652ad
    Cc: Jason Cooper <jason@lakedaemon.net>
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Acked-by: Rob Herring <robh@kernel.org>
Kyle McMartin 0c652ad
    Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 06fca8017fe75cffdae40a9de3b1a864b649a308
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:25 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    arm64: initial support for GICv3
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    The Generic Interrupt Controller (version 3) offers services that are
Kyle McMartin 0c652ad
    similar to GICv2, with a number of additional features:
Kyle McMartin 0c652ad
    - Affinity routing based on the CPU MPIDR (ARE)
Kyle McMartin 0c652ad
    - System register for the CPU interfaces (SRE)
Kyle McMartin 0c652ad
    - Support for more that 8 CPUs
Kyle McMartin 0c652ad
    - Locality-specific Peripheral Interrupts (LPIs)
Kyle McMartin 0c652ad
    - Interrupt Translation Services (ITS)
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    This patch adds preliminary support for GICv3 with ARE and SRE,
Kyle McMartin 0c652ad
    non-secure mode only. It relies on higher exception levels to grant ARE
Kyle McMartin 0c652ad
    and SRE access.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Support for LPI and ITS will be added at a later time.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Cc: Thomas Gleixner <tglx@linutronix.de>
Kyle McMartin 0c652ad
    Cc: Jason Cooper <jason@lakedaemon.net>
Kyle McMartin 0c652ad
    Reviewed-by: Zi Shen Lim <zlim@broadcom.com>
Kyle McMartin 0c652ad
    Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Reviewed-by: Tirumalesh Chalamarla <tchalamarla@cavium.com>
Kyle McMartin 0c652ad
    Reviewed-by: Yun Wu <wuyun.wu@huawei.com>
Kyle McMartin 0c652ad
    Reviewed-by: Zhen Lei <thunder.leizhen@huawei.com>
Kyle McMartin 0c652ad
    Tested-by: Tirumalesh Chalamarla<tchalamarla@cavium.com>
Kyle McMartin 0c652ad
    Tested-by: Radha Mohan Chintakuntla <rchintakuntla@cavium.com>
Kyle McMartin 0c652ad
    Acked-by: Radha Mohan Chintakuntla <rchintakuntla@cavium.com>
Kyle McMartin 0c652ad
    Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 9e8004797a703dbcfd57b240119b350727887c43
Kyle McMartin 0c652ad
Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 10:19:24 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    ARM: GIC: move some bits of GICv2 to a library-type file
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    A few GICv2 low-level function are actually very useful to GICv3,
Kyle McMartin 0c652ad
    and it makes some sense to share them across the two drivers.
Kyle McMartin 0c652ad
    They end-up in their own file, with an additional parameter used
Kyle McMartin 0c652ad
    to ensure an optional synchronization (unused on GICv2).
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Cc: Thomas Gleixner <tglx@linutronix.de>
Kyle McMartin 0c652ad
    Cc: Jason Cooper <jason@lakedaemon.net>
Kyle McMartin 0c652ad
    Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Kyle McMartin 0c652ad
    Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit b4e6d74b54b13bb69b5d31a44ce1ae0118e7b9c7
Kyle McMartin 0c652ad
Author: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 12 15:10:22 2014 -0400
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    rtc: ia64: allow other architectures to use EFI RTC
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Currently, the rtc-efi driver is restricted to ia64 only.
Kyle McMartin 0c652ad
    Newer architectures with EFI support may want to also use
Kyle McMartin 0c652ad
    that driver. This patch moves the platform device setup
Kyle McMartin 0c652ad
    from ia64 into drivers/rtc and allow any architecture with
Kyle McMartin 0c652ad
    CONFIG_EFI=y to use the rtc-efi driver.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 7362bb3ff47a277d57e2547b463dac40c51ee09b
Kyle McMartin 0c652ad
Author: Don Dutile <ddutile@redhat.com>
Kyle McMartin 0c652ad
Date:   Tue Mar 25 20:22:26 2014 -0400
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    pmu: Adding support for Xgene PMUs
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Message-id: <1395778948-47814-2-git-send-email-ddutile@redhat.com>
Kyle McMartin 0c652ad
    Patchwork-id: 78602
Kyle McMartin 0c652ad
    O-Subject: [PATCH 1/3] pmu: Adding support for Xgene PMUs
Kyle McMartin 0c652ad
    Bugzilla: 1079110
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Backport of these two posted (but not upstream) patches.
Kyle McMartin 0c652ad
    Combined into single patch due to gic-patch dependency.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Donald Dutile <ddutile@redhat.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit fa07a775e9c349106913e3931ad8c79a629d52a6
Kyle McMartin 0c652ad
Author: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
Date:   Sun Jun 15 09:06:55 2014 -0400
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    arm64: fix up APM Mustang devicetree
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    These are changes needed when loading device tree blob built with
Kyle McMartin 0c652ad
    kernel. i.e. with grub. These are not needed when using devicetree
Kyle McMartin 0c652ad
    from Tianocore which will be fixed up at tianocore runtime.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 039c600b601646a609356c379f9180499bc1fc06
Kyle McMartin 0c652ad
Author: Kyle McMartin <kmcmarti@redhat.com>
Kyle McMartin 0c652ad
Date:   Tue May 13 22:25:26 2014 -0400
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    arm64: don't set READ_IMPLIES_EXEC for EM_AARCH64 ELF objects
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Message-id: <20140513222526.GC26038@redacted.bos.redhat.com>
Kyle McMartin 0c652ad
    Patchwork-id: 79789
Kyle McMartin 0c652ad
    O-Subject: [ACADIA PATCH] arm64: don't set READ_IMPLIES_EXEC for EM_AARCH64 ELF objects
Kyle McMartin 0c652ad
    Bugzilla: 1085528
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1085528
Kyle McMartin 0c652ad
    Upstream: submitted soon
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    [Sadly this isn't (yet) sufficient... but it fixes at least one issue
Kyle McMartin 0c652ad
     here... cat /proc/$$/personality shows READ_IMPLIES_EXEC before. I'll
Kyle McMartin 0c652ad
     try to figure the rest out tomorrow.]
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Currently, we're accidentally ending up with executable stacks on
Kyle McMartin 0c652ad
    AArch64 when the ABI says we shouldn't be, and relying on glibc to fix
Kyle McMartin 0c652ad
    things up for us when we're loaded. However, SELinux will deny us
Kyle McMartin 0c652ad
    mucking with the stack, and hit us with execmem AVCs.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    The reason this is happening is somewhat complex:
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    fs/binfmt_elf.c:load_elf_binary()
Kyle McMartin 0c652ad
     - initializes executable_stack = EXSTACK_DEFAULT implying the
Kyle McMartin 0c652ad
       architecture should make up its mind.
Kyle McMartin 0c652ad
     - does a pile of loading goo
Kyle McMartin 0c652ad
     - runs through the program headers, looking for PT_GNU_STACK
Kyle McMartin 0c652ad
       and setting (or unsetting) executable_stack if it finds it.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
       This is our first problem, we won't generate these unless an
Kyle McMartin 0c652ad
       executable stack is explicitly requested.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
     - more ELF loading goo
Kyle McMartin 0c652ad
     - sets whether we're a compat task or not (TIF_32BIT) based on compat.h
Kyle McMartin 0c652ad
     - for compat reasons (pre-GNU_STACK) checks if the READ_IMPLIES_EXEC
Kyle McMartin 0c652ad
       flag should be set for ancient toolchains
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
       Here's our second problem, we test if read_implies_exec based on
Kyle McMartin 0c652ad
       stk != EXSTACK_DISABLE_X, which is true since stk == EXSTACK_DEFAULT.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
       So we set current->personality |= READ_IMPLIES_EXEC like a broken
Kyle McMartin 0c652ad
       legacy toolchain would want.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
     - Now we call setup_arg_pages to set up the stack...
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    fs/exec.c:setup_arg_pages()
Kyle McMartin 0c652ad
     - lots of magic happens here
Kyle McMartin 0c652ad
     - vm_flags gets initialized to VM_STACK_FLAGS
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
       Here's our third problem, VM_STACK_FLAGS on arm64 is
Kyle McMartin 0c652ad
       VM_DEFAULT_DATA_FLAG which tests READ_IMPLIES_EXEC and sets VM_EXEC
Kyle McMartin 0c652ad
       if it's true. So we end up with an executable stack mapping, since we
Kyle McMartin 0c652ad
       don't have executable_stack set (it's still EXSTACK_DEFAULT at this
Kyle McMartin 0c652ad
       point) to unset it anywhere.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Bang. execstack AVC when the program starts running.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    The easiest way I can see to fix this is to test if we're a legacy task
Kyle McMartin 0c652ad
    and fix it up there. But that's not as simple as it sounds, because
Kyle McMartin 0c652ad
    the 32-bit ABI depends on what revision of the CPU we've enabled (not
Kyle McMartin 0c652ad
    that it matters since we're ARMv8...) Regardless, in the compat case,
Kyle McMartin 0c652ad
    set READ_IMPLIES_EXEC if we've found a GNU_STACK header which explicitly
Kyle McMartin 0c652ad
    requested it as in arch/arm/kernel/elf.c:arm_elf_read_implies_exec().
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Kyle McMartin <kmcmarti@redhat.com>
Kyle McMartin 0c652ad
    Signed-off-by: Donald Dutile <ddutile@redhat.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 36988493876f40bfcde0f3ed20c7386792297d6e
Kyle McMartin 0c652ad
Author: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
Date:   Fri Jun 13 00:37:11 2014 -0400
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    arm64: fix soft lockup due to large tlb flush range
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Under certain loads, this soft lockup has been observed:
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
       BUG: soft lockup - CPU#2 stuck for 22s! [ip6tables:1016]
Kyle McMartin 0c652ad
       Modules linked in: ip6t_rpfilter ip6t_REJECT cfg80211 rfkill xt_conntrack ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw vfat fat efivarfs xfs libcrc32c
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
       CPU: 2 PID: 1016 Comm: ip6tables Not tainted 3.13.0-0.rc7.30.sa2.aarch64 #1
Kyle McMartin 0c652ad
       task: fffffe03e81d1400 ti: fffffe03f01f8000 task.ti: fffffe03f01f8000
Kyle McMartin 0c652ad
       PC is at __cpu_flush_kern_tlb_range+0xc/0x40
Kyle McMartin 0c652ad
       LR is at __purge_vmap_area_lazy+0x28c/0x3ac
Kyle McMartin 0c652ad
       pc : [<fffffe000009c5cc>] lr : [<fffffe0000182710>] pstate: 80000145
Kyle McMartin 0c652ad
       sp : fffffe03f01fbb70
Kyle McMartin 0c652ad
       x29: fffffe03f01fbb70 x28: fffffe03f01f8000
Kyle McMartin 0c652ad
       x27: fffffe0000b19000 x26: 00000000000000d0
Kyle McMartin 0c652ad
       x25: 000000000000001c x24: fffffe03f01fbc50
Kyle McMartin 0c652ad
       x23: fffffe03f01fbc58 x22: fffffe03f01fbc10
Kyle McMartin 0c652ad
       x21: fffffe0000b2a3f8 x20: 0000000000000802
Kyle McMartin 0c652ad
       x19: fffffe0000b2a3c8 x18: 000003fffdf52710
Kyle McMartin 0c652ad
       x17: 000003ff9d8bb910 x16: fffffe000050fbfc
Kyle McMartin 0c652ad
       x15: 0000000000005735 x14: 000003ff9d7e1a5c
Kyle McMartin 0c652ad
       x13: 0000000000000000 x12: 000003ff9d7e1a5c
Kyle McMartin 0c652ad
       x11: 0000000000000007 x10: fffffe0000c09af0
Kyle McMartin 0c652ad
       x9 : fffffe0000ad1000 x8 : 000000000000005c
Kyle McMartin 0c652ad
       x7 : fffffe03e8624000 x6 : 0000000000000000
Kyle McMartin 0c652ad
       x5 : 0000000000000000 x4 : 0000000000000000
Kyle McMartin 0c652ad
       x3 : fffffe0000c09cc8 x2 : 0000000000000000
Kyle McMartin 0c652ad
       x1 : 000fffffdfffca80 x0 : 000fffffcd742150
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    The __cpu_flush_kern_tlb_range() function looks like:
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
      ENTRY(__cpu_flush_kern_tlb_range)
Kyle McMartin 0c652ad
    	dsb	sy
Kyle McMartin 0c652ad
    	lsr	x0, x0, #12
Kyle McMartin 0c652ad
    	lsr	x1, x1, #12
Kyle McMartin 0c652ad
      1:	tlbi	vaae1is, x0
Kyle McMartin 0c652ad
    	add	x0, x0, #1
Kyle McMartin 0c652ad
    	cmp	x0, x1
Kyle McMartin 0c652ad
    	b.lo	1b
Kyle McMartin 0c652ad
    	dsb	sy
Kyle McMartin 0c652ad
    	isb
Kyle McMartin 0c652ad
    	ret
Kyle McMartin 0c652ad
      ENDPROC(__cpu_flush_kern_tlb_range)
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    The above soft lockup shows the PC at tlbi insn with:
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
      x0 = 0x000fffffcd742150
Kyle McMartin 0c652ad
      x1 = 0x000fffffdfffca80
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    So __cpu_flush_kern_tlb_range has 0x128ba930 tlbi flushes left
Kyle McMartin 0c652ad
    after it has already been looping for 23 seconds!.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Looking up one frame at __purge_vmap_area_lazy(), there is:
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    	...
Kyle McMartin 0c652ad
    	list_for_each_entry_rcu(va, &vmap_area_list, list) {
Kyle McMartin 0c652ad
    		if (va->flags & VM_LAZY_FREE) {
Kyle McMartin 0c652ad
    			if (va->va_start < *start)
Kyle McMartin 0c652ad
    				*start = va->va_start;
Kyle McMartin 0c652ad
    			if (va->va_end > *end)
Kyle McMartin 0c652ad
    				*end = va->va_end;
Kyle McMartin 0c652ad
    			nr += (va->va_end - va->va_start) >> PAGE_SHIFT;
Kyle McMartin 0c652ad
    			list_add_tail(&va->purge_list, &valist);
Kyle McMartin 0c652ad
    			va->flags |= VM_LAZY_FREEING;
Kyle McMartin 0c652ad
    			va->flags &= ~VM_LAZY_FREE;
Kyle McMartin 0c652ad
    		}
Kyle McMartin 0c652ad
    	}
Kyle McMartin 0c652ad
    	...
Kyle McMartin 0c652ad
    	if (nr || force_flush)
Kyle McMartin 0c652ad
    		flush_tlb_kernel_range(*start, *end);
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    So if two areas are being freed, the range passed to
Kyle McMartin 0c652ad
    flush_tlb_kernel_range() may be as large as the vmalloc
Kyle McMartin 0c652ad
    space. For arm64, this is ~240GB for 4k pagesize and ~2TB
Kyle McMartin 0c652ad
    for 64kpage size.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    This patch works around this problem by adding a loop limit.
Kyle McMartin 0c652ad
    If the range is larger than the limit, use flush_tlb_all()
Kyle McMartin 0c652ad
    rather than flushing based on individual pages. The limit
Kyle McMartin 0c652ad
    chosen is arbitrary and would be better if based on the
Kyle McMartin 0c652ad
    actual size of the tlb. I looked through the ARM ARM but
Kyle McMartin 0c652ad
    didn't see any easy way to get the actual tlb size, so for
Kyle McMartin 0c652ad
    now the arbitrary limit is better than the soft lockup.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 6443ca61dca1a50a86bb3a1678799a9227a83335
Kyle McMartin 0c652ad
Author: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
Date:   Tue Jun 24 09:50:28 2014 -0400
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    arm64: use EFI as last resort for reboot and poweroff
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Wire in support for EFI reboot and poweroff functions. We use these
Kyle McMartin 0c652ad
    only if no other mechanism has been registered with arm_pm_reboot
Kyle McMartin 0c652ad
    and/or pm_power_off respectively.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 06191eb6c796a0678be663ce77e3abeb18b0b3f7
Kyle McMartin 0c652ad
Author: Matt Fleming <matt.fleming@intel.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 14:40:25 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    x86/reboot: Add EFI reboot quirk for ACPI Hardware Reduced flag
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    It appears that the BayTrail-T class of hardware requires EFI in order
Kyle McMartin 0c652ad
    to powerdown and reboot and no other reliable method exists.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    This quirk is generally applicable to all hardware that has the ACPI
Kyle McMartin 0c652ad
    Hardware Reduced bit set, since usually ACPI would be the preferred
Kyle McMartin 0c652ad
    method.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Cc: Len Brown <len.brown@intel.com>
Kyle McMartin 0c652ad
    Cc: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
    Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Kyle McMartin 0c652ad
    Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit f9fbfac6e78f4772e9ea83fe98b9d65a04b66d7b
Kyle McMartin 0c652ad
Author: Matt Fleming <matt.fleming@intel.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 14:40:24 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    efi/reboot: Allow powering off machines using EFI
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Not only can EfiResetSystem() be used to reboot, it can also be used to
Kyle McMartin 0c652ad
    power down machines.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    By and large, this functionality doesn't work very well across the range
Kyle McMartin 0c652ad
    of EFI machines in the wild, so it should definitely only be used as a
Kyle McMartin 0c652ad
    last resort. In an ideal world, this wouldn't be needed at all.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Unfortunately, we're starting to see machines where EFI is the *only*
Kyle McMartin 0c652ad
    reliable way to power down, and nothing else, not PCI, not ACPI, works.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    efi_poweroff_required() should be implemented on a per-architecture
Kyle McMartin 0c652ad
    basis, since exactly when we should be using EFI runtime services is a
Kyle McMartin 0c652ad
    platform-specific decision. There's no analogue for reboot because each
Kyle McMartin 0c652ad
    architecture handles reboot very differently - the x86 code in
Kyle McMartin 0c652ad
    particular is pretty complex.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Patches to enable this for specific classes of hardware will be
Kyle McMartin 0c652ad
    submitted separately.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Cc: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
    Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 3ab8d8d210f5e819438e197bc95d44aeb216a772
Kyle McMartin 0c652ad
Author: Matt Fleming <matt.fleming@intel.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 14:40:23 2014 +0100
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    efi/reboot: Add generic wrapper around EfiResetSystem()
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Implement efi_reboot(), which is really just a wrapper around the
Kyle McMartin 0c652ad
    EfiResetSystem() EFI runtime service, but it does at least allow us to
Kyle McMartin 0c652ad
    funnel all callers through a single location.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    It also simplifies the callsites since users no longer need to check to
Kyle McMartin 0c652ad
    see whether EFI_RUNTIME_SERVICES are enabled.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Cc: Tony Luck <tony.luck@intel.com>
Kyle McMartin 0c652ad
    Cc: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
    Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 42218bfddcbe38f0b92674723ebd9de2fb7e8c4e
Kyle McMartin 0c652ad
Author: Michal Nazarewicz <mina86@mina86.com>
Kyle McMartin 0c652ad
Date:   Mon Jun 23 21:40:47 2014 +0200
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    mm: page_alloc: fix CMA area initialisation when pageblock > MAX_ORDER
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    With a kernel configured with ARM64_64K_PAGES && !TRANSPARENT_HUGEPAGE,
Kyle McMartin 0c652ad
    the following is triggered at early boot:
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
      SMP: Total of 8 processors activated.
Kyle McMartin 0c652ad
      devtmpfs: initialized
Kyle McMartin 0c652ad
      Unable to handle kernel NULL pointer dereference at virtual address 00000008
Kyle McMartin 0c652ad
      pgd = fffffe0000050000
Kyle McMartin 0c652ad
      [00000008] *pgd=00000043fba00003, *pmd=00000043fba00003, *pte=00e0000078010407
Kyle McMartin 0c652ad
      Internal error: Oops: 96000006 [#1] SMP
Kyle McMartin 0c652ad
      Modules linked in:
Kyle McMartin 0c652ad
      CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.15.0-rc864k+ #44
Kyle McMartin 0c652ad
      task: fffffe03bc040000 ti: fffffe03bc080000 task.ti: fffffe03bc080000
Kyle McMartin 0c652ad
      PC is at __list_add+0x10/0xd4
Kyle McMartin 0c652ad
      LR is at free_one_page+0x270/0x638
Kyle McMartin 0c652ad
      ...
Kyle McMartin 0c652ad
      Call trace:
Kyle McMartin 0c652ad
      [<fffffe00003ee970>] __list_add+0x10/0xd4
Kyle McMartin 0c652ad
      [<fffffe000019c478>] free_one_page+0x26c/0x638
Kyle McMartin 0c652ad
      [<fffffe000019c8c8>] __free_pages_ok.part.52+0x84/0xbc
Kyle McMartin 0c652ad
      [<fffffe000019d5e8>] __free_pages+0x74/0xbc
Kyle McMartin 0c652ad
      [<fffffe0000c01350>] init_cma_reserved_pageblock+0xe8/0x104
Kyle McMartin 0c652ad
      [<fffffe0000c24de0>] cma_init_reserved_areas+0x190/0x1e4
Kyle McMartin 0c652ad
      [<fffffe0000090418>] do_one_initcall+0xc4/0x154
Kyle McMartin 0c652ad
      [<fffffe0000bf0a50>] kernel_init_freeable+0x204/0x2a8
Kyle McMartin 0c652ad
      [<fffffe00007520a0>] kernel_init+0xc/0xd4
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    This happens because init_cma_reserved_pageblock() calls
Kyle McMartin 0c652ad
    __free_one_page() with pageblock_order as page order but it is bigger
Kyle McMartin 0c652ad
    han MAX_ORDER.  This in turn causes accesses past zone->free_list[].
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Fix the problem by changing init_cma_reserved_pageblock() such that it
Kyle McMartin 0c652ad
    splits pageblock into individual MAX_ORDER pages if pageblock is
Kyle McMartin 0c652ad
    bigger than a MAX_ORDER page.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    In cases where !CONFIG_HUGETLB_PAGE_SIZE_VARIABLE, which is all
Kyle McMartin 0c652ad
    architectures expect for ia64, powerpc and tile at the moment, the
Kyle McMartin 0c652ad
    “pageblock_order > MAX_ORDER” condition will be optimised out since
Kyle McMartin 0c652ad
    both sides of the operator are constants.  In cases where pageblock
Kyle McMartin 0c652ad
    size is variable, the performance degradation should not be
Kyle McMartin 0c652ad
    significant anyway since init_cma_reserved_pageblock() is called
Kyle McMartin 0c652ad
    only at boot time at most MAX_CMA_AREAS times which by default is
Kyle McMartin 0c652ad
    eight.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Cc: stable@vger.kernel.org
Kyle McMartin 0c652ad
    Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
Kyle McMartin 0c652ad
    Reported-by: Mark Salter <msalter@redhat.com>
Kyle McMartin 0c652ad
    Tested-by: Christopher Covington <cov@codeaurora.org>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 7e20b29ffff9de89d22779bcf8891b2a6bf3ab63
Kyle McMartin 0c652ad
Author: Suman Tripathi <stripathi@apm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 06:51:32 2014 -0400
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    ata: Fix the dma state machine lockup for the IDENTIFY DEVICE PIO mode command.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    This patch fixes the dma state machine lockup due to the processing
Kyle McMartin 0c652ad
    of IDENTIFY DEVICE PIO mode command. The X-Gene AHCI controller
Kyle McMartin 0c652ad
    has an errata in which it cannot clear the BSY bit after
Kyle McMartin 0c652ad
    receiving the PIO setup FIS and results the dma state machine to go
Kyle McMartin 0c652ad
    into the CMFatalErrorUpdate state resulting in the dma state
Kyle McMartin 0c652ad
    machine lockup. This patch also removes the dma restart workaround
Kyle McMartin 0c652ad
    from the read_id function as the read_id function is only called by
Kyle McMartin 0c652ad
    libata layer for ATA_INTERNAL commands. But for somecases eg:
Kyle McMartin 0c652ad
    PORT MULTIPLIER and udev, the framework will enumerate using SCSI
Kyle McMartin 0c652ad
    commands and it will not call read_id function.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Loc Ho <lho@apm.com>
Kyle McMartin 0c652ad
    Signed-off-by: Suman Tripathi <stripathi@apm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 2494fae7825c244a6f173241c52e8ab7a38006e6
Kyle McMartin 0c652ad
Author: Suman Tripathi <stripathi@apm.com>
Kyle McMartin 0c652ad
Date:   Thu Jun 19 06:50:08 2014 -0400
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    libahci: Implement the function ahci_restart_engine to restart the port dma engine.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    This patch adds an function to restart the port dma engine.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Loc Ho <lho@apm.com>
Kyle McMartin 0c652ad
    Signed-off-by: Suman Tripathi <stripathi@apm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 3b3bef5b10473f9986de45022ae8cc528bfc8464
Kyle McMartin 0c652ad
Author: Iyappan Subramanian <isubramanian@apm.com>
Kyle McMartin 0c652ad
Date:   Fri Jun 20 16:18:16 2014 -0700
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    drivers: net: Add APM X-Gene SoC ethernet driver support.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    This patch adds network driver for APM X-Gene SoC ethernet.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Kyle McMartin 0c652ad
    Signed-off-by: Ravi Patel <rapatel@apm.com>
Kyle McMartin 0c652ad
    Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit b4ef14e44cda920313a6fa63382b82e2bd1964e1
Kyle McMartin 0c652ad
Author: Iyappan Subramanian <isubramanian@apm.com>
Kyle McMartin 0c652ad
Date:   Fri Jun 20 16:18:15 2014 -0700
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    dts: Add bindings for APM X-Gene SoC ethernet driver
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    This patch adds bindings for APM X-Gene SoC ethernet driver.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Kyle McMartin 0c652ad
    Signed-off-by: Ravi Patel <rapatel@apm.com>
Kyle McMartin 0c652ad
    Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 1173f314654d6edb5072d4f47908520cf7fcc9c4
Kyle McMartin 0c652ad
Author: Iyappan Subramanian <isubramanian@apm.com>
Kyle McMartin 0c652ad
Date:   Fri Jun 20 16:18:14 2014 -0700
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    Documentation: dts: Add bindings for APM X-Gene SoC ethernet driver
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    This patch adds documentation for APM X-Gene SoC ethernet DTS binding.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Kyle McMartin 0c652ad
    Signed-off-by: Ravi Patel <rapatel@apm.com>
Kyle McMartin 0c652ad
    Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
commit 0931546a1d4a3e89072fcb9f3a3755adf49fb99c
Kyle McMartin 0c652ad
Author: Iyappan Subramanian <isubramanian@apm.com>
Kyle McMartin 0c652ad
Date:   Fri Jun 20 16:18:13 2014 -0700
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
    MAINTAINERS: Add entry for APM X-Gene SoC ethernet driver
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    This patch adds a MAINTAINERS entry for APM X-Gene SoC
Kyle McMartin 0c652ad
    ethernet driver.
Kyle McMartin 0c652ad
    
Kyle McMartin 0c652ad
    Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Kyle McMartin 0c652ad
    Signed-off-by: Ravi Patel <rapatel@apm.com>
Kyle McMartin 0c652ad
    Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
Kyle McMartin 0c652ad
Kyle McMartin 0c652ad
diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
Kyle McMartin 0c652ad
index 37fc4f6..e28ccec 100644
Kyle McMartin 0c652ad
--- a/Documentation/arm64/booting.txt
Kyle McMartin 0c652ad
+++ b/Documentation/arm64/booting.txt
Kyle McMartin 0c652ad
@@ -141,6 +141,12 @@ Before jumping into the kernel, the following conditions must be met:
Kyle McMartin 0c652ad
   the kernel image will be entered must be initialised by software at a
Kyle McMartin 0c652ad
   higher exception level to prevent execution in an UNKNOWN state.
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
+  For systems with a GICv3 interrupt controller, it is expected that:
Kyle McMartin 0c652ad
+  - If EL3 is present, it must program ICC_SRE_EL3.Enable (bit 3) to
Kyle McMartin 0c652ad
+    0b1 and ICC_SRE_EL3.SRE (bit 0) to 0b1.
Kyle McMartin 0c652ad
+  - If the kernel is entered at EL1, EL2 must set ICC_SRE_EL2.Enable
Kyle McMartin 0c652ad
+    (bit 3) to 0b1 and ICC_SRE_EL2.SRE (bit 0) to 0b1.
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 The requirements described above for CPU mode, caches, MMUs, architected
Kyle McMartin 0c652ad
 timers, coherency and system registers apply to all CPUs.  All CPUs must
Kyle McMartin 0c652ad
 enter the kernel in the same exception level.
Kyle McMartin 0c652ad
diff --git a/Documentation/devicetree/bindings/arm/gic-v3.txt b/Documentation/devicetree/bindings/arm/gic-v3.txt
Kyle McMartin 0c652ad
new file mode 100644
Kyle McMartin 0c652ad
index 0000000..33cd05e
Kyle McMartin 0c652ad
--- /dev/null
Kyle McMartin 0c652ad
+++ b/Documentation/devicetree/bindings/arm/gic-v3.txt
Kyle McMartin 0c652ad
@@ -0,0 +1,79 @@
Kyle McMartin 0c652ad
+* ARM Generic Interrupt Controller, version 3
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+AArch64 SMP cores are often associated with a GICv3, providing Private
Kyle McMartin 0c652ad
+Peripheral Interrupts (PPI), Shared Peripheral Interrupts (SPI),
Kyle McMartin 0c652ad
+Software Generated Interrupts (SGI), and Locality-specific Peripheral
Kyle McMartin 0c652ad
+Interrupts (LPI).
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+Main node required properties:
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+- compatible : should at least contain  "arm,gic-v3".
Kyle McMartin 0c652ad
+- interrupt-controller : Identifies the node as an interrupt controller
Kyle McMartin 0c652ad
+- #interrupt-cells : Specifies the number of cells needed to encode an
Kyle McMartin 0c652ad
+  interrupt source. Must be a single cell with a value of at least 3.
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+  The 1st cell is the interrupt type; 0 for SPI interrupts, 1 for PPI
Kyle McMartin 0c652ad
+  interrupts. Other values are reserved for future use.
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+  The 2nd cell contains the interrupt number for the interrupt type.
Kyle McMartin 0c652ad
+  SPI interrupts are in the range [0-987]. PPI interrupts are in the
Kyle McMartin 0c652ad
+  range [0-15].
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+  The 3rd cell is the flags, encoded as follows:
Kyle McMartin 0c652ad
+	bits[3:0] trigger type and level flags.
Kyle McMartin 0c652ad
+		1 = edge triggered
Kyle McMartin 0c652ad
+		4 = level triggered
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+  Cells 4 and beyond are reserved for future use. When the 1st cell
Kyle McMartin 0c652ad
+  has a value of 0 or 1, cells 4 and beyond act as padding, and may be
Kyle McMartin 0c652ad
+  ignored. It is recommended that padding cells have a value of 0.
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+- reg : Specifies base physical address(s) and size of the GIC
Kyle McMartin 0c652ad
+  registers, in the following order:
Kyle McMartin 0c652ad
+  - GIC Distributor interface (GICD)
Kyle McMartin 0c652ad
+  - GIC Redistributors (GICR), one range per redistributor region
Kyle McMartin 0c652ad
+  - GIC CPU interface (GICC)
Kyle McMartin 0c652ad
+  - GIC Hypervisor interface (GICH)
Kyle McMartin 0c652ad
+  - GIC Virtual CPU interface (GICV)
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+  GICC, GICH and GICV are optional.
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+- interrupts : Interrupt source of the VGIC maintenance interrupt.
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+Optional
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+- redistributor-stride : If using padding pages, specifies the stride
Kyle McMartin 0c652ad
+  of consecutive redistributors. Must be a multiple of 64kB.
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+- #redistributor-regions: The number of independent contiguous regions
Kyle McMartin 0c652ad
+  occupied by the redistributors. Required if more than one such
Kyle McMartin 0c652ad
+  region is present.
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+Examples:
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	gic: interrupt-controller@2cf00000 {
Kyle McMartin 0c652ad
+		compatible = "arm,gic-v3";
Kyle McMartin 0c652ad
+		#interrupt-cells = <3>;
Kyle McMartin 0c652ad
+		interrupt-controller;
Kyle McMartin 0c652ad
+		reg = <0x0 0x2f000000 0 0x10000>,	// GICD
Kyle McMartin 0c652ad
+		      <0x0 0x2f100000 0 0x200000>,	// GICR
Kyle McMartin 0c652ad
+		      <0x0 0x2c000000 0 0x2000>,	// GICC
Kyle McMartin 0c652ad
+		      <0x0 0x2c010000 0 0x2000>,	// GICH
Kyle McMartin 0c652ad
+		      <0x0 0x2c020000 0 0x2000>;	// GICV
Kyle McMartin 0c652ad
+		interrupts = <1 9 4>;
Kyle McMartin 0c652ad
+	};
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	gic: interrupt-controller@2c010000 {
Kyle McMartin 0c652ad
+		compatible = "arm,gic-v3";
Kyle McMartin 0c652ad
+		#interrupt-cells = <3>;
Kyle McMartin 0c652ad
+		interrupt-controller;
Kyle McMartin 0c652ad
+		redistributor-stride = <0x0 0x40000>;	// 256kB stride
Kyle McMartin 0c652ad
+		#redistributor-regions = <2>;
Kyle McMartin 0c652ad
+		reg = <0x0 0x2c010000 0 0x10000>,	// GICD
Kyle McMartin 0c652ad
+		      <0x0 0x2d000000 0 0x800000>,	// GICR 1: CPUs 0-31
Kyle McMartin 0c652ad
+		      <0x0 0x2e000000 0 0x800000>;	// GICR 2: CPUs 32-63
Kyle McMartin 0c652ad
+		      <0x0 0x2c040000 0 0x2000>,	// GICC
Kyle McMartin 0c652ad
+		      <0x0 0x2c060000 0 0x2000>,	// GICH
Kyle McMartin 0c652ad
+		      <0x0 0x2c080000 0 0x2000>;	// GICV
Kyle McMartin 0c652ad
+		interrupts = <1 9 4>;
Kyle McMartin 0c652ad
+	};
Kyle McMartin 0c652ad
diff --git a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
Kyle McMartin 0c652ad
new file mode 100644
Kyle McMartin 0c652ad
index 0000000..3e2a295
Kyle McMartin 0c652ad
--- /dev/null
Kyle McMartin 0c652ad
+++ b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
Kyle McMartin 0c652ad
@@ -0,0 +1,72 @@
Kyle McMartin 0c652ad
+APM X-Gene SoC Ethernet nodes
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+Ethernet nodes are defined to describe on-chip ethernet interfaces in
Kyle McMartin 0c652ad
+APM X-Gene SoC.
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+Required properties:
Kyle McMartin 0c652ad
+- compatible:		Should be "apm,xgene-enet"
Kyle McMartin 0c652ad
+- reg: Address and length of the register set for the device. It contains the
Kyle McMartin 0c652ad
+       information of registers in the same order as described by reg-names
Kyle McMartin 0c652ad
+- reg-names: Should contain the register set names
Kyle McMartin 0c652ad
+  "enet_csr":		Ethernet control and status register address space
Kyle McMartin 0c652ad
+  "ring_csr":		Descriptor ring control and status register address space
Kyle McMartin 0c652ad
+  "ring_cmd":		Descriptor ring command register address space
Kyle McMartin 0c652ad
+- interrupts:		Ethernet main interrupt
Kyle McMartin 0c652ad
+- clocks:		Reference to the clock entry.
Kyle McMartin 0c652ad
+- local-mac-address:	MAC address assigned to this device
Kyle McMartin 0c652ad
+- phy-connection-type:	Interface type between ethernet device and PHY device
Kyle McMartin 0c652ad
+- phy-handle:		Reference to a PHY node connected to this device
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+- mdio: 		Device tree subnode with the following required
Kyle McMartin 0c652ad
+			properties:
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	- compatible: Must be "apm,xgene-mdio".
Kyle McMartin 0c652ad
+	- #address-cells: Must be <1>.
Kyle McMartin 0c652ad
+	- #size-cells: Must be <0>.
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	For the phy on the mdio bus, there must be a node with the following
Kyle McMartin 0c652ad
+	fields:
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	- compatible: PHY identifier.  Please refer ./phy.txt for the format.
Kyle McMartin 0c652ad
+	- reg: The ID number for the phy.
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+Optional properties:
Kyle McMartin 0c652ad
+- status		: Should be "ok" or "disabled" for enabled/disabled.
Kyle McMartin 0c652ad
+			  Default is "ok".
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+Example:
Kyle McMartin 0c652ad
+	menetclk: menetclk {
Kyle McMartin 0c652ad
+		compatible = "apm,xgene-device-clock";
Kyle McMartin 0c652ad
+		clock-output-names = "menetclk";
Kyle McMartin 0c652ad
+		status = "ok";
Kyle McMartin 0c652ad
+	};
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	menet: ethernet@17020000 {
Kyle McMartin 0c652ad
+		compatible = "apm,xgene-enet";
Kyle McMartin 0c652ad
+		status = "disabled";
Kyle McMartin 0c652ad
+		reg = <0x0 0x17020000 0x0 0xd100>,
Kyle McMartin 0c652ad
+		      <0x0 0X17030000 0x0 0X400>,
Kyle McMartin 0c652ad
+		      <0x0 0X10000000 0x0 0X200>;
Kyle McMartin 0c652ad
+		reg-names = "enet_csr", "ring_csr", "ring_cmd";
Kyle McMartin 0c652ad
+		interrupts = <0x0 0x3c 0x4>;
Kyle McMartin 0c652ad
+		clocks = <&menetclk 0>;
Kyle McMartin 0c652ad
+		local-mac-address = [00 01 73 00 00 01];
Kyle McMartin 0c652ad
+		phy-connection-type = "rgmii";
Kyle McMartin 0c652ad
+		phy-handle = <&menetphy>;
Kyle McMartin 0c652ad
+		mdio {
Kyle McMartin 0c652ad
+			compatible = "apm,xgene-mdio";
Kyle McMartin 0c652ad
+			#address-cells = <1>;
Kyle McMartin 0c652ad
+			#size-cells = <0>;
Kyle McMartin 0c652ad
+			menetphy: menetphy@3 {
Kyle McMartin 0c652ad
+				compatible = "ethernet-phy-id001c.c915";
Kyle McMartin 0c652ad
+				reg = <0x3>;
Kyle McMartin 0c652ad
+			};
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+		};
Kyle McMartin 0c652ad
+	};
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+/* Board-specific peripheral configurations */
Kyle McMartin 0c652ad
+&menet {
Kyle McMartin 0c652ad
+        status = "ok";
Kyle McMartin 0c652ad
+};
Kyle McMartin 0c652ad
diff --git a/MAINTAINERS b/MAINTAINERS
Kyle McMartin 0c652ad
index 3cc94ff..45a142e 100644
Kyle McMartin 0c652ad
--- a/MAINTAINERS
Kyle McMartin 0c652ad
+++ b/MAINTAINERS
Kyle McMartin 0c652ad
@@ -700,6 +700,14 @@ S:	Maintained
Kyle McMartin 0c652ad
 F:	drivers/net/appletalk/
Kyle McMartin 0c652ad
 F:	net/appletalk/
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
+APPLIED MICRO (APM) X-GENE SOC ETHERNET DRIVER
Kyle McMartin 0c652ad
+M:	Iyappan Subramanian <isubramanian@apm.com>
Kyle McMartin 0c652ad
+M:	Keyur Chudgar <kchudgar@apm.com>
Kyle McMartin 0c652ad
+M:	Ravi Patel <rapatel@apm.com>
Kyle McMartin 0c652ad
+S:	Supported
Kyle McMartin 0c652ad
+F:	drivers/net/ethernet/apm/xgene/
Kyle McMartin 0c652ad
+F:	Documentation/devicetree/bindings/net/apm-xgene-enet.txt
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 APTINA CAMERA SENSOR PLL
Kyle McMartin 0c652ad
 M:	Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Kyle McMartin 0c652ad
 L:	linux-media@vger.kernel.org
Kyle McMartin 0c652ad
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
Kyle McMartin 0c652ad
index 193ceaf..d6d5227 100644
Kyle McMartin 0c652ad
--- a/arch/arm/include/asm/kvm_host.h
Kyle McMartin 0c652ad
+++ b/arch/arm/include/asm/kvm_host.h
Kyle McMartin 0c652ad
@@ -225,6 +225,11 @@ static inline int kvm_arch_dev_ioctl_check_extension(long ext)
Kyle McMartin 0c652ad
 	return 0;
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
+static inline void vgic_arch_setup(const struct vgic_params *vgic)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	BUG_ON(vgic->type != VGIC_V2);
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 int kvm_perf_init(void);
Kyle McMartin 0c652ad
 int kvm_perf_teardown(void);
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
Kyle McMartin 0c652ad
index 85598b5..713e807 100644
Kyle McMartin 0c652ad
--- a/arch/arm/kernel/asm-offsets.c
Kyle McMartin 0c652ad
+++ b/arch/arm/kernel/asm-offsets.c
Kyle McMartin 0c652ad
@@ -182,13 +182,13 @@ int main(void)
Kyle McMartin 0c652ad
   DEFINE(VCPU_HYP_PC,		offsetof(struct kvm_vcpu, arch.fault.hyp_pc));
Kyle McMartin 0c652ad
 #ifdef CONFIG_KVM_ARM_VGIC
Kyle McMartin 0c652ad
   DEFINE(VCPU_VGIC_CPU,		offsetof(struct kvm_vcpu, arch.vgic_cpu));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_HCR,		offsetof(struct vgic_cpu, vgic_hcr));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_VMCR,		offsetof(struct vgic_cpu, vgic_vmcr));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_MISR,		offsetof(struct vgic_cpu, vgic_misr));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_EISR,		offsetof(struct vgic_cpu, vgic_eisr));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_ELRSR,	offsetof(struct vgic_cpu, vgic_elrsr));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_APR,		offsetof(struct vgic_cpu, vgic_apr));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_LR,		offsetof(struct vgic_cpu, vgic_lr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_HCR,	offsetof(struct vgic_cpu, vgic_v2.vgic_hcr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_VMCR,	offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_MISR,	offsetof(struct vgic_cpu, vgic_v2.vgic_misr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_EISR,	offsetof(struct vgic_cpu, vgic_v2.vgic_eisr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_ELRSR,	offsetof(struct vgic_cpu, vgic_v2.vgic_elrsr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_APR,	offsetof(struct vgic_cpu, vgic_v2.vgic_apr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_LR,	offsetof(struct vgic_cpu, vgic_v2.vgic_lr));
Kyle McMartin 0c652ad
   DEFINE(VGIC_CPU_NR_LR,	offsetof(struct vgic_cpu, nr_lr));
Kyle McMartin 0c652ad
 #ifdef CONFIG_KVM_ARM_TIMER
Kyle McMartin 0c652ad
   DEFINE(VCPU_TIMER_CNTV_CTL,	offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl));
Kyle McMartin 0c652ad
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
Kyle McMartin 0c652ad
index 789bca9..f7057ed 100644
Kyle McMartin 0c652ad
--- a/arch/arm/kvm/Makefile
Kyle McMartin 0c652ad
+++ b/arch/arm/kvm/Makefile
Kyle McMartin 0c652ad
@@ -21,4 +21,5 @@ obj-y += kvm-arm.o init.o interrupts.o
Kyle McMartin 0c652ad
 obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o
Kyle McMartin 0c652ad
 obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o
Kyle McMartin 0c652ad
 obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o
Kyle McMartin 0c652ad
+obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o
Kyle McMartin 0c652ad
 obj-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o
Kyle McMartin 0c652ad
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
Kyle McMartin 0c652ad
index 76af9302..e4eaf30 100644
Kyle McMartin 0c652ad
--- a/arch/arm/kvm/interrupts_head.S
Kyle McMartin 0c652ad
+++ b/arch/arm/kvm/interrupts_head.S
Kyle McMartin 0c652ad
@@ -421,14 +421,14 @@ vcpu	.req	r0		@ vcpu pointer always in r0
Kyle McMartin 0c652ad
 	ldr	r9, [r2, #GICH_ELRSR1]
Kyle McMartin 0c652ad
 	ldr	r10, [r2, #GICH_APR]
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
-	str	r3, [r11, #VGIC_CPU_HCR]
Kyle McMartin 0c652ad
-	str	r4, [r11, #VGIC_CPU_VMCR]
Kyle McMartin 0c652ad
-	str	r5, [r11, #VGIC_CPU_MISR]
Kyle McMartin 0c652ad
-	str	r6, [r11, #VGIC_CPU_EISR]
Kyle McMartin 0c652ad
-	str	r7, [r11, #(VGIC_CPU_EISR + 4)]
Kyle McMartin 0c652ad
-	str	r8, [r11, #VGIC_CPU_ELRSR]
Kyle McMartin 0c652ad
-	str	r9, [r11, #(VGIC_CPU_ELRSR + 4)]
Kyle McMartin 0c652ad
-	str	r10, [r11, #VGIC_CPU_APR]
Kyle McMartin 0c652ad
+	str	r3, [r11, #VGIC_V2_CPU_HCR]
Kyle McMartin 0c652ad
+	str	r4, [r11, #VGIC_V2_CPU_VMCR]
Kyle McMartin 0c652ad
+	str	r5, [r11, #VGIC_V2_CPU_MISR]
Kyle McMartin 0c652ad
+	str	r6, [r11, #VGIC_V2_CPU_EISR]
Kyle McMartin 0c652ad
+	str	r7, [r11, #(VGIC_V2_CPU_EISR + 4)]
Kyle McMartin 0c652ad
+	str	r8, [r11, #VGIC_V2_CPU_ELRSR]
Kyle McMartin 0c652ad
+	str	r9, [r11, #(VGIC_V2_CPU_ELRSR + 4)]
Kyle McMartin 0c652ad
+	str	r10, [r11, #VGIC_V2_CPU_APR]
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 	/* Clear GICH_HCR */
Kyle McMartin 0c652ad
 	mov	r5, #0
Kyle McMartin 0c652ad
@@ -436,7 +436,7 @@ vcpu	.req	r0		@ vcpu pointer always in r0
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 	/* Save list registers */
Kyle McMartin 0c652ad
 	add	r2, r2, #GICH_LR0
Kyle McMartin 0c652ad
-	add	r3, r11, #VGIC_CPU_LR
Kyle McMartin 0c652ad
+	add	r3, r11, #VGIC_V2_CPU_LR
Kyle McMartin 0c652ad
 	ldr	r4, [r11, #VGIC_CPU_NR_LR]
Kyle McMartin 0c652ad
 1:	ldr	r6, [r2], #4
Kyle McMartin 0c652ad
 	str	r6, [r3], #4
Kyle McMartin 0c652ad
@@ -463,9 +463,9 @@ vcpu	.req	r0		@ vcpu pointer always in r0
Kyle McMartin 0c652ad
 	add	r11, vcpu, #VCPU_VGIC_CPU
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 	/* We only restore a minimal set of registers */
Kyle McMartin 0c652ad
-	ldr	r3, [r11, #VGIC_CPU_HCR]
Kyle McMartin 0c652ad
-	ldr	r4, [r11, #VGIC_CPU_VMCR]
Kyle McMartin 0c652ad
-	ldr	r8, [r11, #VGIC_CPU_APR]
Kyle McMartin 0c652ad
+	ldr	r3, [r11, #VGIC_V2_CPU_HCR]
Kyle McMartin 0c652ad
+	ldr	r4, [r11, #VGIC_V2_CPU_VMCR]
Kyle McMartin 0c652ad
+	ldr	r8, [r11, #VGIC_V2_CPU_APR]
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 	str	r3, [r2, #GICH_HCR]
Kyle McMartin 0c652ad
 	str	r4, [r2, #GICH_VMCR]
Kyle McMartin 0c652ad
@@ -473,7 +473,7 @@ vcpu	.req	r0		@ vcpu pointer always in r0
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 	/* Restore list registers */
Kyle McMartin 0c652ad
 	add	r2, r2, #GICH_LR0
Kyle McMartin 0c652ad
-	add	r3, r11, #VGIC_CPU_LR
Kyle McMartin 0c652ad
+	add	r3, r11, #VGIC_V2_CPU_LR
Kyle McMartin 0c652ad
 	ldr	r4, [r11, #VGIC_CPU_NR_LR]
Kyle McMartin 0c652ad
 1:	ldr	r6, [r3], #4
Kyle McMartin 0c652ad
 	str	r6, [r2], #4
Kyle McMartin 0c652ad
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
Kyle McMartin 0c652ad
index a474de34..7fc6e2e 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/Kconfig
Kyle McMartin 0c652ad
+++ b/arch/arm64/Kconfig
Kyle McMartin 0c652ad
@@ -10,6 +10,7 @@ config ARM64
Kyle McMartin 0c652ad
 	select ARM_AMBA
Kyle McMartin 0c652ad
 	select ARM_ARCH_TIMER
Kyle McMartin 0c652ad
 	select ARM_GIC
Kyle McMartin 0c652ad
+	select ARM_GIC_V3
Kyle McMartin 0c652ad
 	select BUILDTIME_EXTABLE_SORT
Kyle McMartin 0c652ad
 	select CLONE_BACKWARDS
Kyle McMartin 0c652ad
 	select COMMON_CLK
Kyle McMartin 0c652ad
diff --git a/arch/arm64/boot/dts/apm-mustang.dts b/arch/arm64/boot/dts/apm-mustang.dts
Kyle McMartin 0c652ad
index 6541962..b2f5622 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/boot/dts/apm-mustang.dts
Kyle McMartin 0c652ad
+++ b/arch/arm64/boot/dts/apm-mustang.dts
Kyle McMartin 0c652ad
@@ -28,3 +28,7 @@
Kyle McMartin 0c652ad
 &serial0 {
Kyle McMartin 0c652ad
 	status = "ok";
Kyle McMartin 0c652ad
 };
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+&menet {
Kyle McMartin 0c652ad
+	status = "ok";
Kyle McMartin 0c652ad
+};
Kyle McMartin 0c652ad
diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi
Kyle McMartin 0c652ad
index 40aa96c..846ee3a 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/boot/dts/apm-storm.dtsi
Kyle McMartin 0c652ad
+++ b/arch/arm64/boot/dts/apm-storm.dtsi
Kyle McMartin 0c652ad
@@ -24,56 +24,56 @@
Kyle McMartin 0c652ad
 			compatible = "apm,potenza", "arm,armv8";
Kyle McMartin 0c652ad
 			reg = <0x0 0x000>;
Kyle McMartin 0c652ad
 			enable-method = "spin-table";
Kyle McMartin 0c652ad
-			cpu-release-addr = <0x1 0x0000fff8>;
Kyle McMartin 0c652ad
+			cpu-release-addr = <0x40 0x0000f000>;
Kyle McMartin 0c652ad
 		};
Kyle McMartin 0c652ad
 		cpu@001 {
Kyle McMartin 0c652ad
 			device_type = "cpu";
Kyle McMartin 0c652ad
 			compatible = "apm,potenza", "arm,armv8";
Kyle McMartin 0c652ad
 			reg = <0x0 0x001>;
Kyle McMartin 0c652ad
 			enable-method = "spin-table";
Kyle McMartin 0c652ad
-			cpu-release-addr = <0x1 0x0000fff8>;
Kyle McMartin 0c652ad
+			cpu-release-addr = <0x40 0x0000f000>;
Kyle McMartin 0c652ad
 		};
Kyle McMartin 0c652ad
 		cpu@100 {
Kyle McMartin 0c652ad
 			device_type = "cpu";
Kyle McMartin 0c652ad
 			compatible = "apm,potenza", "arm,armv8";
Kyle McMartin 0c652ad
 			reg = <0x0 0x100>;
Kyle McMartin 0c652ad
 			enable-method = "spin-table";
Kyle McMartin 0c652ad
-			cpu-release-addr = <0x1 0x0000fff8>;
Kyle McMartin 0c652ad
+			cpu-release-addr = <0x40 0x0000f000>;
Kyle McMartin 0c652ad
 		};
Kyle McMartin 0c652ad
 		cpu@101 {
Kyle McMartin 0c652ad
 			device_type = "cpu";
Kyle McMartin 0c652ad
 			compatible = "apm,potenza", "arm,armv8";
Kyle McMartin 0c652ad
 			reg = <0x0 0x101>;
Kyle McMartin 0c652ad
 			enable-method = "spin-table";
Kyle McMartin 0c652ad
-			cpu-release-addr = <0x1 0x0000fff8>;
Kyle McMartin 0c652ad
+			cpu-release-addr = <0x40 0x0000f000>;
Kyle McMartin 0c652ad
 		};
Kyle McMartin 0c652ad
 		cpu@200 {
Kyle McMartin 0c652ad
 			device_type = "cpu";
Kyle McMartin 0c652ad
 			compatible = "apm,potenza", "arm,armv8";
Kyle McMartin 0c652ad
 			reg = <0x0 0x200>;
Kyle McMartin 0c652ad
 			enable-method = "spin-table";
Kyle McMartin 0c652ad
-			cpu-release-addr = <0x1 0x0000fff8>;
Kyle McMartin 0c652ad
+			cpu-release-addr = <0x40 0x0000f000>;
Kyle McMartin 0c652ad
 		};
Kyle McMartin 0c652ad
 		cpu@201 {
Kyle McMartin 0c652ad
 			device_type = "cpu";
Kyle McMartin 0c652ad
 			compatible = "apm,potenza", "arm,armv8";
Kyle McMartin 0c652ad
 			reg = <0x0 0x201>;
Kyle McMartin 0c652ad
 			enable-method = "spin-table";
Kyle McMartin 0c652ad
-			cpu-release-addr = <0x1 0x0000fff8>;
Kyle McMartin 0c652ad
+			cpu-release-addr = <0x40 0x0000f000>;
Kyle McMartin 0c652ad
 		};
Kyle McMartin 0c652ad
 		cpu@300 {
Kyle McMartin 0c652ad
 			device_type = "cpu";
Kyle McMartin 0c652ad
 			compatible = "apm,potenza", "arm,armv8";
Kyle McMartin 0c652ad
 			reg = <0x0 0x300>;
Kyle McMartin 0c652ad
 			enable-method = "spin-table";
Kyle McMartin 0c652ad
-			cpu-release-addr = <0x1 0x0000fff8>;
Kyle McMartin 0c652ad
+			cpu-release-addr = <0x40 0x0000f000>;
Kyle McMartin 0c652ad
 		};
Kyle McMartin 0c652ad
 		cpu@301 {
Kyle McMartin 0c652ad
 			device_type = "cpu";
Kyle McMartin 0c652ad
 			compatible = "apm,potenza", "arm,armv8";
Kyle McMartin 0c652ad
 			reg = <0x0 0x301>;
Kyle McMartin 0c652ad
 			enable-method = "spin-table";
Kyle McMartin 0c652ad
-			cpu-release-addr = <0x1 0x0000fff8>;
Kyle McMartin 0c652ad
+			cpu-release-addr = <0x40 0x0000f000>;
Kyle McMartin 0c652ad
 		};
Kyle McMartin 0c652ad
 	};
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
@@ -97,6 +97,11 @@
Kyle McMartin 0c652ad
 		clock-frequency = <50000000>;
Kyle McMartin 0c652ad
 	};
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
+	pmu {
Kyle McMartin 0c652ad
+		compatible = "arm,armv8-pmuv3";
Kyle McMartin 0c652ad
+		interrupts = <1 12 0xff04>;
Kyle McMartin 0c652ad
+	};
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 	soc {
Kyle McMartin 0c652ad
 		compatible = "simple-bus";
Kyle McMartin 0c652ad
 		#address-cells = <2>;
Kyle McMartin 0c652ad
@@ -167,14 +172,13 @@
Kyle McMartin 0c652ad
 				clock-output-names = "ethclk";
Kyle McMartin 0c652ad
 			};
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
-			eth8clk: eth8clk {
Kyle McMartin 0c652ad
+			menetclk: menetclk {
Kyle McMartin 0c652ad
 				compatible = "apm,xgene-device-clock";
Kyle McMartin 0c652ad
 				#clock-cells = <1>;
Kyle McMartin 0c652ad
 				clocks = <&ethclk 0>;
Kyle McMartin 0c652ad
-				clock-names = "eth8clk";
Kyle McMartin 0c652ad
 				reg = <0x0 0x1702C000 0x0 0x1000>;
Kyle McMartin 0c652ad
 				reg-names = "csr-reg";
Kyle McMartin 0c652ad
-				clock-output-names = "eth8clk";
Kyle McMartin 0c652ad
+				clock-output-names = "menetclk";
Kyle McMartin 0c652ad
 			};
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 			sataphy1clk: sataphy1clk@1f21c000 {
Kyle McMartin 0c652ad
@@ -278,7 +282,7 @@
Kyle McMartin 0c652ad
 			compatible = "ns16550a";
Kyle McMartin 0c652ad
 			reg = <0 0x1c020000 0x0 0x1000>;
Kyle McMartin 0c652ad
 			reg-shift = <2>;
Kyle McMartin 0c652ad
-			clock-frequency = <10000000>; /* Updated by bootloader */
Kyle McMartin 0c652ad
+			clock-frequency = <50000000>; /* Updated by bootloader */
Kyle McMartin 0c652ad
 			interrupt-parent = <&gic;;
Kyle McMartin 0c652ad
 			interrupts = <0x0 0x4c 0x4>;
Kyle McMartin 0c652ad
 		};
Kyle McMartin 0c652ad
@@ -397,5 +401,30 @@
Kyle McMartin 0c652ad
 			#clock-cells = <1>;
Kyle McMartin 0c652ad
 			clocks = <&rtcclk 0>;
Kyle McMartin 0c652ad
 		};
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+		menet: ethernet@17020000 {
Kyle McMartin 0c652ad
+			compatible = "apm,xgene-enet";
Kyle McMartin 0c652ad
+			status = "disabled";
Kyle McMartin 0c652ad
+			reg = <0x0 0x17020000 0x0 0xd100>,
Kyle McMartin 0c652ad
+			      <0x0 0X17030000 0x0 0X400>,
Kyle McMartin 0c652ad
+			      <0x0 0X10000000 0x0 0X200>;
Kyle McMartin 0c652ad
+			reg-names = "enet_csr", "ring_csr", "ring_cmd";
Kyle McMartin 0c652ad
+			interrupts = <0x0 0x3c 0x4>;
Kyle McMartin 0c652ad
+			dma-coherent;
Kyle McMartin 0c652ad
+			clocks = <&menetclk 0>;
Kyle McMartin 0c652ad
+			local-mac-address = [00 00 00 00 00 00];
Kyle McMartin 0c652ad
+			phy-connection-type = "rgmii";
Kyle McMartin 0c652ad
+			phy-handle = <&menetphy>;
Kyle McMartin 0c652ad
+			mdio {
Kyle McMartin 0c652ad
+				compatible = "apm,xgene-mdio";
Kyle McMartin 0c652ad
+				#address-cells = <1>;
Kyle McMartin 0c652ad
+				#size-cells = <0>;
Kyle McMartin 0c652ad
+				menetphy: menetphy@3 {
Kyle McMartin 0c652ad
+					compatible = "ethernet-phy-id001c.c915";
Kyle McMartin 0c652ad
+					reg = <0x3>;
Kyle McMartin 0c652ad
+				};
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+			};
Kyle McMartin 0c652ad
+		};
Kyle McMartin 0c652ad
 	};
Kyle McMartin 0c652ad
 };
Kyle McMartin 0c652ad
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
Kyle McMartin 0c652ad
index 01d3aab..8186df6 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/include/asm/elf.h
Kyle McMartin 0c652ad
+++ b/arch/arm64/include/asm/elf.h
Kyle McMartin 0c652ad
@@ -114,7 +114,8 @@ typedef struct user_fpsimd_state elf_fpregset_t;
Kyle McMartin 0c652ad
  */
Kyle McMartin 0c652ad
 #define elf_check_arch(x)		((x)->e_machine == EM_AARCH64)
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
-#define elf_read_implies_exec(ex,stk)	(stk != EXSTACK_DISABLE_X)
Kyle McMartin 0c652ad
+#define elf_read_implies_exec(ex,stk)	(test_thread_flag(TIF_32BIT) \
Kyle McMartin 0c652ad
+					 ? (stk == EXSTACK_ENABLE_X) : 0)
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 #define CORE_DUMP_USE_REGSET
Kyle McMartin 0c652ad
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE
Kyle McMartin 0c652ad
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
Kyle McMartin 0c652ad
index 3d69030..cc83520 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/include/asm/kvm_arm.h
Kyle McMartin 0c652ad
+++ b/arch/arm64/include/asm/kvm_arm.h
Kyle McMartin 0c652ad
@@ -76,9 +76,10 @@
Kyle McMartin 0c652ad
  */
Kyle McMartin 0c652ad
 #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \
Kyle McMartin 0c652ad
 			 HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \
Kyle McMartin 0c652ad
-			 HCR_AMO | HCR_IMO | HCR_FMO | \
Kyle McMartin 0c652ad
-			 HCR_SWIO | HCR_TIDCP | HCR_RW)
Kyle McMartin 0c652ad
+			 HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW)
Kyle McMartin 0c652ad
 #define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF)
Kyle McMartin 0c652ad
+#define HCR_INT_OVERRIDE   (HCR_FMO | HCR_IMO)
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 /* Hyp System Control Register (SCTLR_EL2) bits */
Kyle McMartin 0c652ad
 #define SCTLR_EL2_EE	(1 << 25)
Kyle McMartin 0c652ad
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
Kyle McMartin 0c652ad
index 9fcd54b..a28c35b 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/include/asm/kvm_asm.h
Kyle McMartin 0c652ad
+++ b/arch/arm64/include/asm/kvm_asm.h
Kyle McMartin 0c652ad
@@ -18,6 +18,8 @@
Kyle McMartin 0c652ad
 #ifndef __ARM_KVM_ASM_H__
Kyle McMartin 0c652ad
 #define __ARM_KVM_ASM_H__
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
+#include <asm/virt.h>
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 /*
Kyle McMartin 0c652ad
  * 0 is reserved as an invalid value.
Kyle McMartin 0c652ad
  * Order *must* be kept in sync with the hyp switch code.
Kyle McMartin 0c652ad
@@ -96,13 +98,21 @@ extern char __kvm_hyp_init_end[];
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 extern char __kvm_hyp_vector[];
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
-extern char __kvm_hyp_code_start[];
Kyle McMartin 0c652ad
-extern char __kvm_hyp_code_end[];
Kyle McMartin 0c652ad
+#define	__kvm_hyp_code_start	__hyp_text_start
Kyle McMartin 0c652ad
+#define	__kvm_hyp_code_end	__hyp_text_end
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 extern void __kvm_flush_vm_context(void);
Kyle McMartin 0c652ad
 extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+extern u64 __vgic_v3_get_ich_vtr_el2(void);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+extern char __save_vgic_v2_state[];
Kyle McMartin 0c652ad
+extern char __restore_vgic_v2_state[];
Kyle McMartin 0c652ad
+extern char __save_vgic_v3_state[];
Kyle McMartin 0c652ad
+extern char __restore_vgic_v3_state[];
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 #endif
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 #endif /* __ARM_KVM_ASM_H__ */
Kyle McMartin 0c652ad
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
Kyle McMartin 0c652ad
index 92242ce..4ae9213 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/include/asm/kvm_host.h
Kyle McMartin 0c652ad
+++ b/arch/arm64/include/asm/kvm_host.h
Kyle McMartin 0c652ad
@@ -200,4 +200,32 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
Kyle McMartin 0c652ad
 		     hyp_stack_ptr, vector_ptr);
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
+struct vgic_sr_vectors {
Kyle McMartin 0c652ad
+	void	*save_vgic;
Kyle McMartin 0c652ad
+	void	*restore_vgic;
Kyle McMartin 0c652ad
+};
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static inline void vgic_arch_setup(const struct vgic_params *vgic)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	extern struct vgic_sr_vectors __vgic_sr_vectors;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	switch(vgic->type)
Kyle McMartin 0c652ad
+	{
Kyle McMartin 0c652ad
+	case VGIC_V2:
Kyle McMartin 0c652ad
+		__vgic_sr_vectors.save_vgic	= __save_vgic_v2_state;
Kyle McMartin 0c652ad
+		__vgic_sr_vectors.restore_vgic	= __restore_vgic_v2_state;
Kyle McMartin 0c652ad
+		break;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#ifdef CONFIG_ARM_GIC_V3
Kyle McMartin 0c652ad
+	case VGIC_V3:
Kyle McMartin 0c652ad
+		__vgic_sr_vectors.save_vgic	= __save_vgic_v3_state;
Kyle McMartin 0c652ad
+		__vgic_sr_vectors.restore_vgic	= __restore_vgic_v3_state;
Kyle McMartin 0c652ad
+		break;
Kyle McMartin 0c652ad
+#endif
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	default:
Kyle McMartin 0c652ad
+		BUG();
Kyle McMartin 0c652ad
+	}
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 #endif /* __ARM64_KVM_HOST_H__ */
Kyle McMartin 0c652ad
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
Kyle McMartin 0c652ad
index b9349c4..e0f37ef 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/include/asm/tlbflush.h
Kyle McMartin 0c652ad
+++ b/arch/arm64/include/asm/tlbflush.h
Kyle McMartin 0c652ad
@@ -98,8 +98,8 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,
Kyle McMartin 0c652ad
 	dsb(ish);
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
-static inline void flush_tlb_range(struct vm_area_struct *vma,
Kyle McMartin 0c652ad
-					unsigned long start, unsigned long end)
Kyle McMartin 0c652ad
+static inline void __flush_tlb_range(struct vm_area_struct *vma,
Kyle McMartin 0c652ad
+				     unsigned long start, unsigned long end)
Kyle McMartin 0c652ad
 {
Kyle McMartin 0c652ad
 	unsigned long asid = (unsigned long)ASID(vma->vm_mm) << 48;
Kyle McMartin 0c652ad
 	unsigned long addr;
Kyle McMartin 0c652ad
@@ -112,7 +112,9 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
Kyle McMartin 0c652ad
 	dsb(ish);
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
-static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
Kyle McMartin 0c652ad
+#define MAX_TLB_LOOP 128
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static inline void __flush_tlb_kernel_range(unsigned long start, unsigned long end)
Kyle McMartin 0c652ad
 {
Kyle McMartin 0c652ad
 	unsigned long addr;
Kyle McMartin 0c652ad
 	start >>= 12;
Kyle McMartin 0c652ad
@@ -124,6 +126,23 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
Kyle McMartin 0c652ad
 	dsb(ish);
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
+static inline void flush_tlb_range(struct vm_area_struct *vma,
Kyle McMartin 0c652ad
+				   unsigned long start, unsigned long end)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	if (((end - start) >> PAGE_SHIFT) < MAX_TLB_LOOP)
Kyle McMartin 0c652ad
+		__flush_tlb_range(vma, start, end);
Kyle McMartin 0c652ad
+	else
Kyle McMartin 0c652ad
+		flush_tlb_mm(vma->vm_mm);
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	if (((end - start) >> PAGE_SHIFT) < MAX_TLB_LOOP)
Kyle McMartin 0c652ad
+		__flush_tlb_kernel_range(start, end);
Kyle McMartin 0c652ad
+	else
Kyle McMartin 0c652ad
+		flush_tlb_all();
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 /*
Kyle McMartin 0c652ad
  * On AArch64, the cache coherency is handled via the set_pte_at() function.
Kyle McMartin 0c652ad
  */
Kyle McMartin 0c652ad
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
Kyle McMartin 0c652ad
index 215ad46..7a5df52 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/include/asm/virt.h
Kyle McMartin 0c652ad
+++ b/arch/arm64/include/asm/virt.h
Kyle McMartin 0c652ad
@@ -50,6 +50,10 @@ static inline bool is_hyp_mode_mismatched(void)
Kyle McMartin 0c652ad
 	return __boot_cpu_mode[0] != __boot_cpu_mode[1];
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
+/* The section containing the hypervisor text */
Kyle McMartin 0c652ad
+extern char __hyp_text_start[];
Kyle McMartin 0c652ad
+extern char __hyp_text_end[];
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 #endif /* __ASSEMBLY__ */
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 #endif /* ! __ASM__VIRT_H */
Kyle McMartin 0c652ad
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
Kyle McMartin 0c652ad
index 646f888..e74654c 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/kernel/asm-offsets.c
Kyle McMartin 0c652ad
+++ b/arch/arm64/kernel/asm-offsets.c
Kyle McMartin 0c652ad
@@ -129,13 +129,24 @@ int main(void)
Kyle McMartin 0c652ad
   DEFINE(KVM_TIMER_ENABLED,	offsetof(struct kvm, arch.timer.enabled));
Kyle McMartin 0c652ad
   DEFINE(VCPU_KVM,		offsetof(struct kvm_vcpu, kvm));
Kyle McMartin 0c652ad
   DEFINE(VCPU_VGIC_CPU,		offsetof(struct kvm_vcpu, arch.vgic_cpu));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_HCR,		offsetof(struct vgic_cpu, vgic_hcr));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_VMCR,		offsetof(struct vgic_cpu, vgic_vmcr));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_MISR,		offsetof(struct vgic_cpu, vgic_misr));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_EISR,		offsetof(struct vgic_cpu, vgic_eisr));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_ELRSR,	offsetof(struct vgic_cpu, vgic_elrsr));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_APR,		offsetof(struct vgic_cpu, vgic_apr));
Kyle McMartin 0c652ad
-  DEFINE(VGIC_CPU_LR,		offsetof(struct vgic_cpu, vgic_lr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_SAVE_FN,		offsetof(struct vgic_sr_vectors, save_vgic));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_RESTORE_FN,	offsetof(struct vgic_sr_vectors, restore_vgic));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_SR_VECTOR_SZ,	sizeof(struct vgic_sr_vectors));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_HCR,	offsetof(struct vgic_cpu, vgic_v2.vgic_hcr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_VMCR,	offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_MISR,	offsetof(struct vgic_cpu, vgic_v2.vgic_misr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_EISR,	offsetof(struct vgic_cpu, vgic_v2.vgic_eisr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_ELRSR,	offsetof(struct vgic_cpu, vgic_v2.vgic_elrsr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_APR,	offsetof(struct vgic_cpu, vgic_v2.vgic_apr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V2_CPU_LR,	offsetof(struct vgic_cpu, vgic_v2.vgic_lr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V3_CPU_HCR,	offsetof(struct vgic_cpu, vgic_v3.vgic_hcr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V3_CPU_VMCR,	offsetof(struct vgic_cpu, vgic_v3.vgic_vmcr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V3_CPU_MISR,	offsetof(struct vgic_cpu, vgic_v3.vgic_misr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V3_CPU_EISR,	offsetof(struct vgic_cpu, vgic_v3.vgic_eisr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V3_CPU_ELRSR,	offsetof(struct vgic_cpu, vgic_v3.vgic_elrsr));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V3_CPU_AP0R,	offsetof(struct vgic_cpu, vgic_v3.vgic_ap0r));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V3_CPU_AP1R,	offsetof(struct vgic_cpu, vgic_v3.vgic_ap1r));
Kyle McMartin 0c652ad
+  DEFINE(VGIC_V3_CPU_LR,	offsetof(struct vgic_cpu, vgic_v3.vgic_lr));
Kyle McMartin 0c652ad
   DEFINE(VGIC_CPU_NR_LR,	offsetof(struct vgic_cpu, nr_lr));
Kyle McMartin 0c652ad
   DEFINE(KVM_VTTBR,		offsetof(struct kvm, arch.vttbr));
Kyle McMartin 0c652ad
   DEFINE(KVM_VGIC_VCTRL,	offsetof(struct kvm, arch.vgic.vctrl_base));
Kyle McMartin 0c652ad
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
Kyle McMartin 0c652ad
index 14db1f6..453b7f8 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/kernel/efi.c
Kyle McMartin 0c652ad
+++ b/arch/arm64/kernel/efi.c
Kyle McMartin 0c652ad
@@ -467,3 +467,14 @@ static int __init arm64_enter_virtual_mode(void)
Kyle McMartin 0c652ad
 	return 0;
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 early_initcall(arm64_enter_virtual_mode);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * If nothing else is handling pm_power_off, use EFI
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * This is called from a late_initcall after other mechanisms
Kyle McMartin 0c652ad
+ * have had a chance to register a handler.
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+bool efi_poweroff_required(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	return pm_power_off == NULL;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
Kyle McMartin 0c652ad
index a96d3a6..871b4ee 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/kernel/head.S
Kyle McMartin 0c652ad
+++ b/arch/arm64/kernel/head.S
Kyle McMartin 0c652ad
@@ -22,6 +22,7 @@
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 #include <linux/linkage.h>
Kyle McMartin 0c652ad
 #include <linux/init.h>
Kyle McMartin 0c652ad
+#include <linux/irqchip/arm-gic-v3.h>
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 #include <asm/assembler.h>
Kyle McMartin 0c652ad
 #include <asm/ptrace.h>
Kyle McMartin 0c652ad
@@ -296,6 +297,23 @@ CPU_LE(	bic	x0, x0, #(3 << 24)	)	// Clear the EE and E0E bits for EL1
Kyle McMartin 0c652ad
 	msr	cnthctl_el2, x0
Kyle McMartin 0c652ad
 	msr	cntvoff_el2, xzr		// Clear virtual offset
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
+#ifdef CONFIG_ARM_GIC_V3
Kyle McMartin 0c652ad
+	/* GICv3 system register access */
Kyle McMartin 0c652ad
+	mrs	x0, id_aa64pfr0_el1
Kyle McMartin 0c652ad
+	ubfx	x0, x0, #24, #4
Kyle McMartin 0c652ad
+	cmp	x0, #1
Kyle McMartin 0c652ad
+	b.ne	3f
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	mrs	x0, ICC_SRE_EL2
Kyle McMartin 0c652ad
+	orr	x0, x0, #1			// Set ICC_SRE_EL2.SRE==1
Kyle McMartin 0c652ad
+	orr	x0, x0, #(1 << 3)		// Set ICC_SRE_EL2.Enable==1
Kyle McMartin 0c652ad
+	msr	ICC_SRE_EL2, x0
Kyle McMartin 0c652ad
+	isb					// Make sure SRE is now 1
Kyle McMartin 0c652ad
+	msr	ICH_HCR_EL2, xzr		// Reset ICC_HCR_EL2 to defaults
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+3:
Kyle McMartin 0c652ad
+#endif
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 	/* Populate ID registers. */
Kyle McMartin 0c652ad
 	mrs	x0, midr_el1
Kyle McMartin 0c652ad
 	mrs	x1, mpidr_el1
Kyle McMartin 0c652ad
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
Kyle McMartin 0c652ad
index 0959611..a272f33 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/kernel/hyp-stub.S
Kyle McMartin 0c652ad
+++ b/arch/arm64/kernel/hyp-stub.S
Kyle McMartin 0c652ad
@@ -19,6 +19,7 @@
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 #include <linux/init.h>
Kyle McMartin 0c652ad
 #include <linux/linkage.h>
Kyle McMartin 0c652ad
+#include <linux/irqchip/arm-gic-v3.h>
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 #include <asm/assembler.h>
Kyle McMartin 0c652ad
 #include <asm/ptrace.h>
Kyle McMartin 0c652ad
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
Kyle McMartin 0c652ad
index 43b7c34..ec5cbbe 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/kernel/process.c
Kyle McMartin 0c652ad
+++ b/arch/arm64/kernel/process.c
Kyle McMartin 0c652ad
@@ -43,6 +43,7 @@
Kyle McMartin 0c652ad
 #include <linux/hw_breakpoint.h>
Kyle McMartin 0c652ad
 #include <linux/personality.h>
Kyle McMartin 0c652ad
 #include <linux/notifier.h>
Kyle McMartin 0c652ad
+#include <linux/efi.h>
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 #include <asm/compat.h>
Kyle McMartin 0c652ad
 #include <asm/cacheflush.h>
Kyle McMartin 0c652ad
@@ -176,6 +177,11 @@ void machine_restart(char *cmd)
Kyle McMartin 0c652ad
 		arm_pm_restart(reboot_mode, cmd);
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 	/*
Kyle McMartin 0c652ad
+	 * If all else fails, try EFI
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	efi_reboot(reboot_mode, cmd);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
 	 * Whoops - the architecture was unable to reboot.
Kyle McMartin 0c652ad
 	 */
Kyle McMartin 0c652ad
 	printk("Reboot failed -- System halted\n");
Kyle McMartin 0c652ad
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
Kyle McMartin 0c652ad
index 72a9fd5..32a0961 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/kvm/Makefile
Kyle McMartin 0c652ad
+++ b/arch/arm64/kvm/Makefile
Kyle McMartin 0c652ad
@@ -20,4 +20,8 @@ kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o
Kyle McMartin 0c652ad
 kvm-$(CONFIG_KVM_ARM_HOST) += guest.o reset.o sys_regs.o sys_regs_generic_v8.o
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o
Kyle McMartin 0c652ad
+kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o
Kyle McMartin 0c652ad
+kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v2-switch.o
Kyle McMartin 0c652ad
+kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v3.o
Kyle McMartin 0c652ad
+kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v3-switch.o
Kyle McMartin 0c652ad
 kvm-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o
Kyle McMartin 0c652ad
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
Kyle McMartin 0c652ad
index b0d1512..5945f3b 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/kvm/hyp.S
Kyle McMartin 0c652ad
+++ b/arch/arm64/kvm/hyp.S
Kyle McMartin 0c652ad
@@ -16,7 +16,6 @@
Kyle McMartin 0c652ad
  */
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 #include <linux/linkage.h>
Kyle McMartin 0c652ad
-#include <linux/irqchip/arm-gic.h>
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 #include <asm/assembler.h>
Kyle McMartin 0c652ad
 #include <asm/memory.h>
Kyle McMartin 0c652ad
@@ -36,9 +35,6 @@
Kyle McMartin 0c652ad
 	.pushsection	.hyp.text, "ax"
Kyle McMartin 0c652ad
 	.align	PAGE_SHIFT
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
-__kvm_hyp_code_start:
Kyle McMartin 0c652ad
-	.globl __kvm_hyp_code_start
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
 .macro save_common_regs
Kyle McMartin 0c652ad
 	// x2: base address for cpu context
Kyle McMartin 0c652ad
 	// x3: tmp register
Kyle McMartin 0c652ad
@@ -339,11 +335,8 @@ __kvm_hyp_code_start:
Kyle McMartin 0c652ad
 .endm
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 .macro activate_traps
Kyle McMartin 0c652ad
-	ldr	x2, [x0, #VCPU_IRQ_LINES]
Kyle McMartin 0c652ad
-	ldr	x1, [x0, #VCPU_HCR_EL2]
Kyle McMartin 0c652ad
-	orr	x2, x2, x1
Kyle McMartin 0c652ad
-	msr	hcr_el2, x2
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
+	ldr     x2, [x0, #VCPU_HCR_EL2]
Kyle McMartin 0c652ad
+	msr     hcr_el2, x2
Kyle McMartin 0c652ad
 	ldr	x2, =(CPTR_EL2_TTA)
Kyle McMartin 0c652ad
 	msr	cptr_el2, x2
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
@@ -379,100 +372,33 @@ __kvm_hyp_code_start:
Kyle McMartin 0c652ad
 .endm
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 /*
Kyle McMartin 0c652ad
- * Save the VGIC CPU state into memory
Kyle McMartin 0c652ad
- * x0: Register pointing to VCPU struct
Kyle McMartin 0c652ad
- * Do not corrupt x1!!!
Kyle McMartin 0c652ad
+ * Call into the vgic backend for state saving
Kyle McMartin 0c652ad
  */
Kyle McMartin 0c652ad
 .macro save_vgic_state
Kyle McMartin 0c652ad
-	/* Get VGIC VCTRL base into x2 */
Kyle McMartin 0c652ad
-	ldr	x2, [x0, #VCPU_KVM]
Kyle McMartin 0c652ad
-	kern_hyp_va	x2
Kyle McMartin 0c652ad
-	ldr	x2, [x2, #KVM_VGIC_VCTRL]
Kyle McMartin 0c652ad
-	kern_hyp_va	x2
Kyle McMartin 0c652ad
-	cbz	x2, 2f		// disabled
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
-	/* Compute the address of struct vgic_cpu */
Kyle McMartin 0c652ad
-	add	x3, x0, #VCPU_VGIC_CPU
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
-	/* Save all interesting registers */
Kyle McMartin 0c652ad
-	ldr	w4, [x2, #GICH_HCR]
Kyle McMartin 0c652ad
-	ldr	w5, [x2, #GICH_VMCR]
Kyle McMartin 0c652ad
-	ldr	w6, [x2, #GICH_MISR]
Kyle McMartin 0c652ad
-	ldr	w7, [x2, #GICH_EISR0]
Kyle McMartin 0c652ad
-	ldr	w8, [x2, #GICH_EISR1]
Kyle McMartin 0c652ad
-	ldr	w9, [x2, #GICH_ELRSR0]
Kyle McMartin 0c652ad
-	ldr	w10, [x2, #GICH_ELRSR1]
Kyle McMartin 0c652ad
-	ldr	w11, [x2, #GICH_APR]
Kyle McMartin 0c652ad
-CPU_BE(	rev	w4,  w4  )
Kyle McMartin 0c652ad
-CPU_BE(	rev	w5,  w5  )
Kyle McMartin 0c652ad
-CPU_BE(	rev	w6,  w6  )
Kyle McMartin 0c652ad
-CPU_BE(	rev	w7,  w7  )
Kyle McMartin 0c652ad
-CPU_BE(	rev	w8,  w8  )
Kyle McMartin 0c652ad
-CPU_BE(	rev	w9,  w9  )
Kyle McMartin 0c652ad
-CPU_BE(	rev	w10, w10 )
Kyle McMartin 0c652ad
-CPU_BE(	rev	w11, w11 )
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
-	str	w4, [x3, #VGIC_CPU_HCR]
Kyle McMartin 0c652ad
-	str	w5, [x3, #VGIC_CPU_VMCR]
Kyle McMartin 0c652ad
-	str	w6, [x3, #VGIC_CPU_MISR]
Kyle McMartin 0c652ad
-	str	w7, [x3, #VGIC_CPU_EISR]
Kyle McMartin 0c652ad
-	str	w8, [x3, #(VGIC_CPU_EISR + 4)]
Kyle McMartin 0c652ad
-	str	w9, [x3, #VGIC_CPU_ELRSR]
Kyle McMartin 0c652ad
-	str	w10, [x3, #(VGIC_CPU_ELRSR + 4)]
Kyle McMartin 0c652ad
-	str	w11, [x3, #VGIC_CPU_APR]
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
-	/* Clear GICH_HCR */
Kyle McMartin 0c652ad
-	str	wzr, [x2, #GICH_HCR]
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
-	/* Save list registers */
Kyle McMartin 0c652ad
-	add	x2, x2, #GICH_LR0
Kyle McMartin 0c652ad
-	ldr	w4, [x3, #VGIC_CPU_NR_LR]
Kyle McMartin 0c652ad
-	add	x3, x3, #VGIC_CPU_LR
Kyle McMartin 0c652ad
-1:	ldr	w5, [x2], #4
Kyle McMartin 0c652ad
-CPU_BE(	rev	w5, w5 )
Kyle McMartin 0c652ad
-	str	w5, [x3], #4
Kyle McMartin 0c652ad
-	sub	w4, w4, #1
Kyle McMartin 0c652ad
-	cbnz	w4, 1b
Kyle McMartin 0c652ad
-2:
Kyle McMartin 0c652ad
+	adr	x24, __vgic_sr_vectors
Kyle McMartin 0c652ad
+	ldr	x24, [x24, VGIC_SAVE_FN]
Kyle McMartin 0c652ad
+	kern_hyp_va	x24
Kyle McMartin 0c652ad
+	blr	x24
Kyle McMartin 0c652ad
+	mrs	x24, hcr_el2
Kyle McMartin 0c652ad
+	mov	x25, #HCR_INT_OVERRIDE
Kyle McMartin 0c652ad
+	neg	x25, x25
Kyle McMartin 0c652ad
+	and	x24, x24, x25
Kyle McMartin 0c652ad
+	msr	hcr_el2, x24
Kyle McMartin 0c652ad
 .endm
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 /*
Kyle McMartin 0c652ad
- * Restore the VGIC CPU state from memory
Kyle McMartin 0c652ad
- * x0: Register pointing to VCPU struct
Kyle McMartin 0c652ad
+ * Call into the vgic backend for state restoring
Kyle McMartin 0c652ad
  */
Kyle McMartin 0c652ad
 .macro restore_vgic_state
Kyle McMartin 0c652ad
-	/* Get VGIC VCTRL base into x2 */
Kyle McMartin 0c652ad
-	ldr	x2, [x0, #VCPU_KVM]
Kyle McMartin 0c652ad
-	kern_hyp_va	x2
Kyle McMartin 0c652ad
-	ldr	x2, [x2, #KVM_VGIC_VCTRL]
Kyle McMartin 0c652ad
-	kern_hyp_va	x2
Kyle McMartin 0c652ad
-	cbz	x2, 2f		// disabled
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
-	/* Compute the address of struct vgic_cpu */
Kyle McMartin 0c652ad
-	add	x3, x0, #VCPU_VGIC_CPU
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
-	/* We only restore a minimal set of registers */
Kyle McMartin 0c652ad
-	ldr	w4, [x3, #VGIC_CPU_HCR]
Kyle McMartin 0c652ad
-	ldr	w5, [x3, #VGIC_CPU_VMCR]
Kyle McMartin 0c652ad
-	ldr	w6, [x3, #VGIC_CPU_APR]
Kyle McMartin 0c652ad
-CPU_BE(	rev	w4, w4 )
Kyle McMartin 0c652ad
-CPU_BE(	rev	w5, w5 )
Kyle McMartin 0c652ad
-CPU_BE(	rev	w6, w6 )
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
-	str	w4, [x2, #GICH_HCR]
Kyle McMartin 0c652ad
-	str	w5, [x2, #GICH_VMCR]
Kyle McMartin 0c652ad
-	str	w6, [x2, #GICH_APR]
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
-	/* Restore list registers */
Kyle McMartin 0c652ad
-	add	x2, x2, #GICH_LR0
Kyle McMartin 0c652ad
-	ldr	w4, [x3, #VGIC_CPU_NR_LR]
Kyle McMartin 0c652ad
-	add	x3, x3, #VGIC_CPU_LR
Kyle McMartin 0c652ad
-1:	ldr	w5, [x3], #4
Kyle McMartin 0c652ad
-CPU_BE(	rev	w5, w5 )
Kyle McMartin 0c652ad
-	str	w5, [x2], #4
Kyle McMartin 0c652ad
-	sub	w4, w4, #1
Kyle McMartin 0c652ad
-	cbnz	w4, 1b
Kyle McMartin 0c652ad
-2:
Kyle McMartin 0c652ad
+	mrs	x24, hcr_el2
Kyle McMartin 0c652ad
+	ldr	x25, [x0, #VCPU_IRQ_LINES]
Kyle McMartin 0c652ad
+	orr	x24, x24, #HCR_INT_OVERRIDE
Kyle McMartin 0c652ad
+	orr	x24, x24, x25
Kyle McMartin 0c652ad
+	msr	hcr_el2, x24
Kyle McMartin 0c652ad
+	adr	x24, __vgic_sr_vectors
Kyle McMartin 0c652ad
+	ldr	x24, [x24, #VGIC_RESTORE_FN]
Kyle McMartin 0c652ad
+	kern_hyp_va	x24
Kyle McMartin 0c652ad
+	blr	x24
Kyle McMartin 0c652ad
 .endm
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 .macro save_timer_state
Kyle McMartin 0c652ad
@@ -653,6 +579,12 @@ ENTRY(__kvm_flush_vm_context)
Kyle McMartin 0c652ad
 	ret
Kyle McMartin 0c652ad
 ENDPROC(__kvm_flush_vm_context)
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
+	// struct vgic_sr_vectors __vgi_sr_vectors;
Kyle McMartin 0c652ad
+	.align 3
Kyle McMartin 0c652ad
+ENTRY(__vgic_sr_vectors)
Kyle McMartin 0c652ad
+	.skip	VGIC_SR_VECTOR_SZ
Kyle McMartin 0c652ad
+ENDPROC(__vgic_sr_vectors)
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 __kvm_hyp_panic:
Kyle McMartin 0c652ad
 	// Guess the context by looking at VTTBR:
Kyle McMartin 0c652ad
 	// If zero, then we're already a host.
Kyle McMartin 0c652ad
@@ -880,7 +812,4 @@ ENTRY(__kvm_hyp_vector)
Kyle McMartin 0c652ad
 	ventry	el1_error_invalid		// Error 32-bit EL1
Kyle McMartin 0c652ad
 ENDPROC(__kvm_hyp_vector)
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
-__kvm_hyp_code_end:
Kyle McMartin 0c652ad
-	.globl	__kvm_hyp_code_end
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
 	.popsection
Kyle McMartin 0c652ad
diff --git a/arch/arm64/kvm/vgic-v2-switch.S b/arch/arm64/kvm/vgic-v2-switch.S
Kyle McMartin 0c652ad
new file mode 100644
Kyle McMartin 0c652ad
index 0000000..ae21177
Kyle McMartin 0c652ad
--- /dev/null
Kyle McMartin 0c652ad
+++ b/arch/arm64/kvm/vgic-v2-switch.S
Kyle McMartin 0c652ad
@@ -0,0 +1,133 @@
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * Copyright (C) 2012,2013 - ARM Ltd
Kyle McMartin 0c652ad
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * This program is free software; you can redistribute it and/or modify
Kyle McMartin 0c652ad
+ * it under the terms of the GNU General Public License version 2 as
Kyle McMartin 0c652ad
+ * published by the Free Software Foundation.
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * This program is distributed in the hope that it will be useful,
Kyle McMartin 0c652ad
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
Kyle McMartin 0c652ad
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Kyle McMartin 0c652ad
+ * GNU General Public License for more details.
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * You should have received a copy of the GNU General Public License
Kyle McMartin 0c652ad
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#include <linux/linkage.h>
Kyle McMartin 0c652ad
+#include <linux/irqchip/arm-gic.h>
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#include <asm/assembler.h>
Kyle McMartin 0c652ad
+#include <asm/memory.h>
Kyle McMartin 0c652ad
+#include <asm/asm-offsets.h>
Kyle McMartin 0c652ad
+#include <asm/kvm.h>
Kyle McMartin 0c652ad
+#include <asm/kvm_asm.h>
Kyle McMartin 0c652ad
+#include <asm/kvm_arm.h>
Kyle McMartin 0c652ad
+#include <asm/kvm_mmu.h>
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	.text
Kyle McMartin 0c652ad
+	.pushsection	.hyp.text, "ax"
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * Save the VGIC CPU state into memory
Kyle McMartin 0c652ad
+ * x0: Register pointing to VCPU struct
Kyle McMartin 0c652ad
+ * Do not corrupt x1!!!
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+ENTRY(__save_vgic_v2_state)
Kyle McMartin 0c652ad
+__save_vgic_v2_state:
Kyle McMartin 0c652ad
+	/* Get VGIC VCTRL base into x2 */
Kyle McMartin 0c652ad
+	ldr	x2, [x0, #VCPU_KVM]
Kyle McMartin 0c652ad
+	kern_hyp_va	x2
Kyle McMartin 0c652ad
+	ldr	x2, [x2, #KVM_VGIC_VCTRL]
Kyle McMartin 0c652ad
+	kern_hyp_va	x2
Kyle McMartin 0c652ad
+	cbz	x2, 2f		// disabled
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Compute the address of struct vgic_cpu */
Kyle McMartin 0c652ad
+	add	x3, x0, #VCPU_VGIC_CPU
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Save all interesting registers */
Kyle McMartin 0c652ad
+	ldr	w4, [x2, #GICH_HCR]
Kyle McMartin 0c652ad
+	ldr	w5, [x2, #GICH_VMCR]
Kyle McMartin 0c652ad
+	ldr	w6, [x2, #GICH_MISR]
Kyle McMartin 0c652ad
+	ldr	w7, [x2, #GICH_EISR0]
Kyle McMartin 0c652ad
+	ldr	w8, [x2, #GICH_EISR1]
Kyle McMartin 0c652ad
+	ldr	w9, [x2, #GICH_ELRSR0]
Kyle McMartin 0c652ad
+	ldr	w10, [x2, #GICH_ELRSR1]
Kyle McMartin 0c652ad
+	ldr	w11, [x2, #GICH_APR]
Kyle McMartin 0c652ad
+CPU_BE(	rev	w4,  w4  )
Kyle McMartin 0c652ad
+CPU_BE(	rev	w5,  w5  )
Kyle McMartin 0c652ad
+CPU_BE(	rev	w6,  w6  )
Kyle McMartin 0c652ad
+CPU_BE(	rev	w7,  w7  )
Kyle McMartin 0c652ad
+CPU_BE(	rev	w8,  w8  )
Kyle McMartin 0c652ad
+CPU_BE(	rev	w9,  w9  )
Kyle McMartin 0c652ad
+CPU_BE(	rev	w10, w10 )
Kyle McMartin 0c652ad
+CPU_BE(	rev	w11, w11 )
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	str	w4, [x3, #VGIC_V2_CPU_HCR]
Kyle McMartin 0c652ad
+	str	w5, [x3, #VGIC_V2_CPU_VMCR]
Kyle McMartin 0c652ad
+	str	w6, [x3, #VGIC_V2_CPU_MISR]
Kyle McMartin 0c652ad
+	str	w7, [x3, #VGIC_V2_CPU_EISR]
Kyle McMartin 0c652ad
+	str	w8, [x3, #(VGIC_V2_CPU_EISR + 4)]
Kyle McMartin 0c652ad
+	str	w9, [x3, #VGIC_V2_CPU_ELRSR]
Kyle McMartin 0c652ad
+	str	w10, [x3, #(VGIC_V2_CPU_ELRSR + 4)]
Kyle McMartin 0c652ad
+	str	w11, [x3, #VGIC_V2_CPU_APR]
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Clear GICH_HCR */
Kyle McMartin 0c652ad
+	str	wzr, [x2, #GICH_HCR]
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Save list registers */
Kyle McMartin 0c652ad
+	add	x2, x2, #GICH_LR0
Kyle McMartin 0c652ad
+	ldr	w4, [x3, #VGIC_CPU_NR_LR]
Kyle McMartin 0c652ad
+	add	x3, x3, #VGIC_V2_CPU_LR
Kyle McMartin 0c652ad
+1:	ldr	w5, [x2], #4
Kyle McMartin 0c652ad
+CPU_BE(	rev	w5, w5 )
Kyle McMartin 0c652ad
+	str	w5, [x3], #4
Kyle McMartin 0c652ad
+	sub	w4, w4, #1
Kyle McMartin 0c652ad
+	cbnz	w4, 1b
Kyle McMartin 0c652ad
+2:
Kyle McMartin 0c652ad
+	ret
Kyle McMartin 0c652ad
+ENDPROC(__save_vgic_v2_state)
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * Restore the VGIC CPU state from memory
Kyle McMartin 0c652ad
+ * x0: Register pointing to VCPU struct
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+ENTRY(__restore_vgic_v2_state)
Kyle McMartin 0c652ad
+__restore_vgic_v2_state:
Kyle McMartin 0c652ad
+	/* Get VGIC VCTRL base into x2 */
Kyle McMartin 0c652ad
+	ldr	x2, [x0, #VCPU_KVM]
Kyle McMartin 0c652ad
+	kern_hyp_va	x2
Kyle McMartin 0c652ad
+	ldr	x2, [x2, #KVM_VGIC_VCTRL]
Kyle McMartin 0c652ad
+	kern_hyp_va	x2
Kyle McMartin 0c652ad
+	cbz	x2, 2f		// disabled
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Compute the address of struct vgic_cpu */
Kyle McMartin 0c652ad
+	add	x3, x0, #VCPU_VGIC_CPU
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* We only restore a minimal set of registers */
Kyle McMartin 0c652ad
+	ldr	w4, [x3, #VGIC_V2_CPU_HCR]
Kyle McMartin 0c652ad
+	ldr	w5, [x3, #VGIC_V2_CPU_VMCR]
Kyle McMartin 0c652ad
+	ldr	w6, [x3, #VGIC_V2_CPU_APR]
Kyle McMartin 0c652ad
+CPU_BE(	rev	w4, w4 )
Kyle McMartin 0c652ad
+CPU_BE(	rev	w5, w5 )
Kyle McMartin 0c652ad
+CPU_BE(	rev	w6, w6 )
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	str	w4, [x2, #GICH_HCR]
Kyle McMartin 0c652ad
+	str	w5, [x2, #GICH_VMCR]
Kyle McMartin 0c652ad
+	str	w6, [x2, #GICH_APR]
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Restore list registers */
Kyle McMartin 0c652ad
+	add	x2, x2, #GICH_LR0
Kyle McMartin 0c652ad
+	ldr	w4, [x3, #VGIC_CPU_NR_LR]
Kyle McMartin 0c652ad
+	add	x3, x3, #VGIC_V2_CPU_LR
Kyle McMartin 0c652ad
+1:	ldr	w5, [x3], #4
Kyle McMartin 0c652ad
+CPU_BE(	rev	w5, w5 )
Kyle McMartin 0c652ad
+	str	w5, [x2], #4
Kyle McMartin 0c652ad
+	sub	w4, w4, #1
Kyle McMartin 0c652ad
+	cbnz	w4, 1b
Kyle McMartin 0c652ad
+2:
Kyle McMartin 0c652ad
+	ret
Kyle McMartin 0c652ad
+ENDPROC(__restore_vgic_v2_state)
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	.popsection
Kyle McMartin 0c652ad
diff --git a/arch/arm64/kvm/vgic-v3-switch.S b/arch/arm64/kvm/vgic-v3-switch.S
Kyle McMartin 0c652ad
new file mode 100644
Kyle McMartin 0c652ad
index 0000000..4ede9d8
Kyle McMartin 0c652ad
--- /dev/null
Kyle McMartin 0c652ad
+++ b/arch/arm64/kvm/vgic-v3-switch.S
Kyle McMartin 0c652ad
@@ -0,0 +1,266 @@
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * Copyright (C) 2012,2013 - ARM Ltd
Kyle McMartin 0c652ad
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * This program is free software; you can redistribute it and/or modify
Kyle McMartin 0c652ad
+ * it under the terms of the GNU General Public License version 2 as
Kyle McMartin 0c652ad
+ * published by the Free Software Foundation.
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * This program is distributed in the hope that it will be useful,
Kyle McMartin 0c652ad
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
Kyle McMartin 0c652ad
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Kyle McMartin 0c652ad
+ * GNU General Public License for more details.
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * You should have received a copy of the GNU General Public License
Kyle McMartin 0c652ad
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#include <linux/linkage.h>
Kyle McMartin 0c652ad
+#include <linux/irqchip/arm-gic-v3.h>
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#include <asm/assembler.h>
Kyle McMartin 0c652ad
+#include <asm/memory.h>
Kyle McMartin 0c652ad
+#include <asm/asm-offsets.h>
Kyle McMartin 0c652ad
+#include <asm/kvm.h>
Kyle McMartin 0c652ad
+#include <asm/kvm_asm.h>
Kyle McMartin 0c652ad
+#include <asm/kvm_arm.h>
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	.text
Kyle McMartin 0c652ad
+	.pushsection	.hyp.text, "ax"
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * We store LRs in reverse order to let the CPU deal with streaming
Kyle McMartin 0c652ad
+ * access. Use this macro to make it look saner...
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+#define LR_OFFSET(n)	(VGIC_V3_CPU_LR + (15 - n) * 8)
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * Save the VGIC CPU state into memory
Kyle McMartin 0c652ad
+ * x0: Register pointing to VCPU struct
Kyle McMartin 0c652ad
+ * Do not corrupt x1!!!
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+.macro	save_vgic_v3_state
Kyle McMartin 0c652ad
+	// Compute the address of struct vgic_cpu
Kyle McMartin 0c652ad
+	add	x3, x0, #VCPU_VGIC_CPU
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	// Make sure stores to the GIC via the memory mapped interface
Kyle McMartin 0c652ad
+	// are now visible to the system register interface
Kyle McMartin 0c652ad
+	dsb	st
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	// Save all interesting registers
Kyle McMartin 0c652ad
+	mrs	x4, ICH_HCR_EL2
Kyle McMartin 0c652ad
+	mrs	x5, ICH_VMCR_EL2
Kyle McMartin 0c652ad
+	mrs	x6, ICH_MISR_EL2
Kyle McMartin 0c652ad
+	mrs	x7, ICH_EISR_EL2
Kyle McMartin 0c652ad
+	mrs	x8, ICH_ELSR_EL2
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	str	w4, [x3, #VGIC_V3_CPU_HCR]
Kyle McMartin 0c652ad
+	str	w5, [x3, #VGIC_V3_CPU_VMCR]
Kyle McMartin 0c652ad
+	str	w6, [x3, #VGIC_V3_CPU_MISR]
Kyle McMartin 0c652ad
+	str	w7, [x3, #VGIC_V3_CPU_EISR]
Kyle McMartin 0c652ad
+	str	w8, [x3, #VGIC_V3_CPU_ELRSR]
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	msr	ICH_HCR_EL2, xzr
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	mrs	x21, ICH_VTR_EL2
Kyle McMartin 0c652ad
+	mvn	w22, w21
Kyle McMartin 0c652ad
+	ubfiz	w23, w22, 2, 4	// w23 = (15 - ListRegs) * 4
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	adr	x24, 1f
Kyle McMartin 0c652ad
+	add	x24, x24, x23
Kyle McMartin 0c652ad
+	br	x24
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+1:
Kyle McMartin 0c652ad
+	mrs	x20, ICH_LR15_EL2
Kyle McMartin 0c652ad
+	mrs	x19, ICH_LR14_EL2
Kyle McMartin 0c652ad
+	mrs	x18, ICH_LR13_EL2
Kyle McMartin 0c652ad
+	mrs	x17, ICH_LR12_EL2
Kyle McMartin 0c652ad
+	mrs	x16, ICH_LR11_EL2
Kyle McMartin 0c652ad
+	mrs	x15, ICH_LR10_EL2
Kyle McMartin 0c652ad
+	mrs	x14, ICH_LR9_EL2
Kyle McMartin 0c652ad
+	mrs	x13, ICH_LR8_EL2
Kyle McMartin 0c652ad
+	mrs	x12, ICH_LR7_EL2
Kyle McMartin 0c652ad
+	mrs	x11, ICH_LR6_EL2
Kyle McMartin 0c652ad
+	mrs	x10, ICH_LR5_EL2
Kyle McMartin 0c652ad
+	mrs	x9, ICH_LR4_EL2
Kyle McMartin 0c652ad
+	mrs	x8, ICH_LR3_EL2
Kyle McMartin 0c652ad
+	mrs	x7, ICH_LR2_EL2
Kyle McMartin 0c652ad
+	mrs	x6, ICH_LR1_EL2
Kyle McMartin 0c652ad
+	mrs	x5, ICH_LR0_EL2
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	adr	x24, 1f
Kyle McMartin 0c652ad
+	add	x24, x24, x23
Kyle McMartin 0c652ad
+	br	x24
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+1:
Kyle McMartin 0c652ad
+	str	x20, [x3, #LR_OFFSET(15)]
Kyle McMartin 0c652ad
+	str	x19, [x3, #LR_OFFSET(14)]
Kyle McMartin 0c652ad
+	str	x18, [x3, #LR_OFFSET(13)]
Kyle McMartin 0c652ad
+	str	x17, [x3, #LR_OFFSET(12)]
Kyle McMartin 0c652ad
+	str	x16, [x3, #LR_OFFSET(11)]
Kyle McMartin 0c652ad
+	str	x15, [x3, #LR_OFFSET(10)]
Kyle McMartin 0c652ad
+	str	x14, [x3, #LR_OFFSET(9)]
Kyle McMartin 0c652ad
+	str	x13, [x3, #LR_OFFSET(8)]
Kyle McMartin 0c652ad
+	str	x12, [x3, #LR_OFFSET(7)]
Kyle McMartin 0c652ad
+	str	x11, [x3, #LR_OFFSET(6)]
Kyle McMartin 0c652ad
+	str	x10, [x3, #LR_OFFSET(5)]
Kyle McMartin 0c652ad
+	str	x9, [x3, #LR_OFFSET(4)]
Kyle McMartin 0c652ad
+	str	x8, [x3, #LR_OFFSET(3)]
Kyle McMartin 0c652ad
+	str	x7, [x3, #LR_OFFSET(2)]
Kyle McMartin 0c652ad
+	str	x6, [x3, #LR_OFFSET(1)]
Kyle McMartin 0c652ad
+	str	x5, [x3, #LR_OFFSET(0)]
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	tbnz	w21, #29, 6f	// 6 bits
Kyle McMartin 0c652ad
+	tbz	w21, #30, 5f	// 5 bits
Kyle McMartin 0c652ad
+				// 7 bits
Kyle McMartin 0c652ad
+	mrs	x20, ICH_AP0R3_EL2
Kyle McMartin 0c652ad
+	str	w20, [x3, #(VGIC_V3_CPU_AP0R + 3*4)]
Kyle McMartin 0c652ad
+	mrs	x19, ICH_AP0R2_EL2
Kyle McMartin 0c652ad
+	str	w19, [x3, #(VGIC_V3_CPU_AP0R + 2*4)]
Kyle McMartin 0c652ad
+6:	mrs	x18, ICH_AP0R1_EL2
Kyle McMartin 0c652ad
+	str	w18, [x3, #(VGIC_V3_CPU_AP0R + 1*4)]
Kyle McMartin 0c652ad
+5:	mrs	x17, ICH_AP0R0_EL2
Kyle McMartin 0c652ad
+	str	w17, [x3, #VGIC_V3_CPU_AP0R]
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	tbnz	w21, #29, 6f	// 6 bits
Kyle McMartin 0c652ad
+	tbz	w21, #30, 5f	// 5 bits
Kyle McMartin 0c652ad
+				// 7 bits
Kyle McMartin 0c652ad
+	mrs	x20, ICH_AP1R3_EL2
Kyle McMartin 0c652ad
+	str	w20, [x3, #(VGIC_V3_CPU_AP1R + 3*4)]
Kyle McMartin 0c652ad
+	mrs	x19, ICH_AP1R2_EL2
Kyle McMartin 0c652ad
+	str	w19, [x3, #(VGIC_V3_CPU_AP1R + 2*4)]
Kyle McMartin 0c652ad
+6:	mrs	x18, ICH_AP1R1_EL2
Kyle McMartin 0c652ad
+	str	w18, [x3, #(VGIC_V3_CPU_AP1R + 1*4)]
Kyle McMartin 0c652ad
+5:	mrs	x17, ICH_AP1R0_EL2
Kyle McMartin 0c652ad
+	str	w17, [x3, #VGIC_V3_CPU_AP1R]
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	// Restore SRE_EL1 access and re-enable SRE at EL1.
Kyle McMartin 0c652ad
+	mrs	x5, ICC_SRE_EL2
Kyle McMartin 0c652ad
+	orr	x5, x5, #ICC_SRE_EL2_ENABLE
Kyle McMartin 0c652ad
+	msr	ICC_SRE_EL2, x5
Kyle McMartin 0c652ad
+	isb
Kyle McMartin 0c652ad
+	mov	x5, #1
Kyle McMartin 0c652ad
+	msr	ICC_SRE_EL1, x5
Kyle McMartin 0c652ad
+.endm
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * Restore the VGIC CPU state from memory
Kyle McMartin 0c652ad
+ * x0: Register pointing to VCPU struct
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+.macro	restore_vgic_v3_state
Kyle McMartin 0c652ad
+	// Disable SRE_EL1 access. Necessary, otherwise
Kyle McMartin 0c652ad
+	// ICH_VMCR_EL2.VFIQEn becomes one, and FIQ happens...
Kyle McMartin 0c652ad
+	msr	ICC_SRE_EL1, xzr
Kyle McMartin 0c652ad
+	isb
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	// Compute the address of struct vgic_cpu
Kyle McMartin 0c652ad
+	add	x3, x0, #VCPU_VGIC_CPU
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	// Restore all interesting registers
Kyle McMartin 0c652ad
+	ldr	w4, [x3, #VGIC_V3_CPU_HCR]
Kyle McMartin 0c652ad
+	ldr	w5, [x3, #VGIC_V3_CPU_VMCR]
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	msr	ICH_HCR_EL2, x4
Kyle McMartin 0c652ad
+	msr	ICH_VMCR_EL2, x5
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	mrs	x21, ICH_VTR_EL2
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	tbnz	w21, #29, 6f	// 6 bits
Kyle McMartin 0c652ad
+	tbz	w21, #30, 5f	// 5 bits
Kyle McMartin 0c652ad
+				// 7 bits
Kyle McMartin 0c652ad
+	ldr	w20, [x3, #(VGIC_V3_CPU_AP1R + 3*4)]
Kyle McMartin 0c652ad
+	msr	ICH_AP1R3_EL2, x20
Kyle McMartin 0c652ad
+	ldr	w19, [x3, #(VGIC_V3_CPU_AP1R + 2*4)]
Kyle McMartin 0c652ad
+	msr	ICH_AP1R2_EL2, x19
Kyle McMartin 0c652ad
+6:	ldr	w18, [x3, #(VGIC_V3_CPU_AP1R + 1*4)]
Kyle McMartin 0c652ad
+	msr	ICH_AP1R1_EL2, x18
Kyle McMartin 0c652ad
+5:	ldr	w17, [x3, #VGIC_V3_CPU_AP1R]
Kyle McMartin 0c652ad
+	msr	ICH_AP1R0_EL2, x17
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	tbnz	w21, #29, 6f	// 6 bits
Kyle McMartin 0c652ad
+	tbz	w21, #30, 5f	// 5 bits
Kyle McMartin 0c652ad
+				// 7 bits
Kyle McMartin 0c652ad
+	ldr	w20, [x3, #(VGIC_V3_CPU_AP0R + 3*4)]
Kyle McMartin 0c652ad
+	msr	ICH_AP0R3_EL2, x20
Kyle McMartin 0c652ad
+	ldr	w19, [x3, #(VGIC_V3_CPU_AP0R + 2*4)]
Kyle McMartin 0c652ad
+	msr	ICH_AP0R2_EL2, x19
Kyle McMartin 0c652ad
+6:	ldr	w18, [x3, #(VGIC_V3_CPU_AP0R + 1*4)]
Kyle McMartin 0c652ad
+	msr	ICH_AP0R1_EL2, x18
Kyle McMartin 0c652ad
+5:	ldr	w17, [x3, #VGIC_V3_CPU_AP0R]
Kyle McMartin 0c652ad
+	msr	ICH_AP0R0_EL2, x17
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	and	w22, w21, #0xf
Kyle McMartin 0c652ad
+	mvn	w22, w21
Kyle McMartin 0c652ad
+	ubfiz	w23, w22, 2, 4	// w23 = (15 - ListRegs) * 4
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	adr	x24, 1f
Kyle McMartin 0c652ad
+	add	x24, x24, x23
Kyle McMartin 0c652ad
+	br	x24
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+1:
Kyle McMartin 0c652ad
+	ldr	x20, [x3, #LR_OFFSET(15)]
Kyle McMartin 0c652ad
+	ldr	x19, [x3, #LR_OFFSET(14)]
Kyle McMartin 0c652ad
+	ldr	x18, [x3, #LR_OFFSET(13)]
Kyle McMartin 0c652ad
+	ldr	x17, [x3, #LR_OFFSET(12)]
Kyle McMartin 0c652ad
+	ldr	x16, [x3, #LR_OFFSET(11)]
Kyle McMartin 0c652ad
+	ldr	x15, [x3, #LR_OFFSET(10)]
Kyle McMartin 0c652ad
+	ldr	x14, [x3, #LR_OFFSET(9)]
Kyle McMartin 0c652ad
+	ldr	x13, [x3, #LR_OFFSET(8)]
Kyle McMartin 0c652ad
+	ldr	x12, [x3, #LR_OFFSET(7)]
Kyle McMartin 0c652ad
+	ldr	x11, [x3, #LR_OFFSET(6)]
Kyle McMartin 0c652ad
+	ldr	x10, [x3, #LR_OFFSET(5)]
Kyle McMartin 0c652ad
+	ldr	x9, [x3, #LR_OFFSET(4)]
Kyle McMartin 0c652ad
+	ldr	x8, [x3, #LR_OFFSET(3)]
Kyle McMartin 0c652ad
+	ldr	x7, [x3, #LR_OFFSET(2)]
Kyle McMartin 0c652ad
+	ldr	x6, [x3, #LR_OFFSET(1)]
Kyle McMartin 0c652ad
+	ldr	x5, [x3, #LR_OFFSET(0)]
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	adr	x24, 1f
Kyle McMartin 0c652ad
+	add	x24, x24, x23
Kyle McMartin 0c652ad
+	br	x24
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+1:
Kyle McMartin 0c652ad
+	msr	ICH_LR15_EL2, x20
Kyle McMartin 0c652ad
+	msr	ICH_LR14_EL2, x19
Kyle McMartin 0c652ad
+	msr	ICH_LR13_EL2, x18
Kyle McMartin 0c652ad
+	msr	ICH_LR12_EL2, x17
Kyle McMartin 0c652ad
+	msr	ICH_LR11_EL2, x16
Kyle McMartin 0c652ad
+	msr	ICH_LR10_EL2, x15
Kyle McMartin 0c652ad
+	msr	ICH_LR9_EL2,  x14
Kyle McMartin 0c652ad
+	msr	ICH_LR8_EL2,  x13
Kyle McMartin 0c652ad
+	msr	ICH_LR7_EL2,  x12
Kyle McMartin 0c652ad
+	msr	ICH_LR6_EL2,  x11
Kyle McMartin 0c652ad
+	msr	ICH_LR5_EL2,  x10
Kyle McMartin 0c652ad
+	msr	ICH_LR4_EL2,   x9
Kyle McMartin 0c652ad
+	msr	ICH_LR3_EL2,   x8
Kyle McMartin 0c652ad
+	msr	ICH_LR2_EL2,   x7
Kyle McMartin 0c652ad
+	msr	ICH_LR1_EL2,   x6
Kyle McMartin 0c652ad
+	msr	ICH_LR0_EL2,   x5
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	// Ensure that the above will be visible via the memory-mapped
Kyle McMartin 0c652ad
+	// view of the CPU interface (GICV).
Kyle McMartin 0c652ad
+	isb
Kyle McMartin 0c652ad
+	dsb	sy
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	// Prevent the guest from touching the GIC system registers
Kyle McMartin 0c652ad
+	mrs	x5, ICC_SRE_EL2
Kyle McMartin 0c652ad
+	and	x5, x5, #~ICC_SRE_EL2_ENABLE
Kyle McMartin 0c652ad
+	msr	ICC_SRE_EL2, x5
Kyle McMartin 0c652ad
+.endm
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+ENTRY(__save_vgic_v3_state)
Kyle McMartin 0c652ad
+	save_vgic_v3_state
Kyle McMartin 0c652ad
+	ret
Kyle McMartin 0c652ad
+ENDPROC(__save_vgic_v3_state)
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+ENTRY(__restore_vgic_v3_state)
Kyle McMartin 0c652ad
+	restore_vgic_v3_state
Kyle McMartin 0c652ad
+	ret
Kyle McMartin 0c652ad
+ENDPROC(__restore_vgic_v3_state)
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+ENTRY(__vgic_v3_get_ich_vtr_el2)
Kyle McMartin 0c652ad
+	mrs	x0, ICH_VTR_EL2
Kyle McMartin 0c652ad
+	ret
Kyle McMartin 0c652ad
+ENDPROC(__vgic_v3_get_ich_vtr_el2)
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	.popsection
Kyle McMartin 0c652ad
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
Kyle McMartin 0c652ad
index f43db8a..05d6079 100644
Kyle McMartin 0c652ad
--- a/arch/arm64/mm/init.c
Kyle McMartin 0c652ad
+++ b/arch/arm64/mm/init.c
Kyle McMartin 0c652ad
@@ -145,8 +145,17 @@ void __init arm64_memblock_init(void)
Kyle McMartin 0c652ad
 	early_init_fdt_scan_reserved_mem();
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 	/* 4GB maximum for 32-bit only capable devices */
Kyle McMartin 0c652ad
-	if (IS_ENABLED(CONFIG_ZONE_DMA))
Kyle McMartin 0c652ad
+	if (IS_ENABLED(CONFIG_ZONE_DMA)) {
Kyle McMartin 0c652ad
 		dma_phys_limit = dma_to_phys(NULL, DMA_BIT_MASK(32)) + 1;
Kyle McMartin 0c652ad
+		/*
Kyle McMartin 0c652ad
+		 * If platform doesn't have DRAM within the dma_phys_limit,
Kyle McMartin 0c652ad
+		 * remove the limit altogether. This allows one kernel (with
Kyle McMartin 0c652ad
+		 * CONFIG_ZONE_DMA defined) to support platforms with 32-bit
Kyle McMartin 0c652ad
+		 * only devices and platforms with no 32-bit DRAM.
Kyle McMartin 0c652ad
+		 */
Kyle McMartin 0c652ad
+		if (dma_phys_limit <= memblock_start_of_DRAM())
Kyle McMartin 0c652ad
+			dma_phys_limit = 0;
Kyle McMartin 0c652ad
+	}
Kyle McMartin 0c652ad
 	dma_contiguous_reserve(dma_phys_limit);
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 	memblock_allow_resize();
Kyle McMartin 0c652ad
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
Kyle McMartin 0c652ad
index 55d4ba4..deed6fa 100644
Kyle McMartin 0c652ad
--- a/arch/ia64/kernel/process.c
Kyle McMartin 0c652ad
+++ b/arch/ia64/kernel/process.c
Kyle McMartin 0c652ad
@@ -662,7 +662,7 @@ void
Kyle McMartin 0c652ad
 machine_restart (char *restart_cmd)
Kyle McMartin 0c652ad
 {
Kyle McMartin 0c652ad
 	(void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0);
Kyle McMartin 0c652ad
-	(*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL);
Kyle McMartin 0c652ad
+	efi_reboot(REBOOT_WARM, NULL);
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 void
Kyle McMartin 0c652ad
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
Kyle McMartin 0c652ad
index 71c52bc..a149c67 100644
Kyle McMartin 0c652ad
--- a/arch/ia64/kernel/time.c
Kyle McMartin 0c652ad
+++ b/arch/ia64/kernel/time.c
Kyle McMartin 0c652ad
@@ -384,21 +384,6 @@ static struct irqaction timer_irqaction = {
Kyle McMartin 0c652ad
 	.name =		"timer"
Kyle McMartin 0c652ad
 };
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
-static struct platform_device rtc_efi_dev = {
Kyle McMartin 0c652ad
-	.name = "rtc-efi",
Kyle McMartin 0c652ad
-	.id = -1,
Kyle McMartin 0c652ad
-};
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
-static int __init rtc_init(void)
Kyle McMartin 0c652ad
-{
Kyle McMartin 0c652ad
-	if (platform_device_register(&rtc_efi_dev) < 0)
Kyle McMartin 0c652ad
-		printk(KERN_ERR "unable to register rtc device...\n");
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
-	/* not necessarily an error */
Kyle McMartin 0c652ad
-	return 0;
Kyle McMartin 0c652ad
-}
Kyle McMartin 0c652ad
-module_init(rtc_init);
Kyle McMartin 0c652ad
-
Kyle McMartin 0c652ad
 void read_persistent_clock(struct timespec *ts)
Kyle McMartin 0c652ad
 {
Kyle McMartin 0c652ad
 	efi_gettimeofday(ts);
Kyle McMartin 0c652ad
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
Kyle McMartin 0c652ad
index 1eb5f64..da50c586a 100644
Kyle McMartin 0c652ad
--- a/arch/x86/include/asm/efi.h
Kyle McMartin 0c652ad
+++ b/arch/x86/include/asm/efi.h
Kyle McMartin 0c652ad
@@ -156,6 +156,8 @@ static inline efi_status_t efi_thunk_set_virtual_address_map(
Kyle McMartin 0c652ad
 	return EFI_SUCCESS;
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 #endif /* CONFIG_EFI_MIXED */
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+extern bool efi_reboot_required(void);
Kyle McMartin 0c652ad
 #else
Kyle McMartin 0c652ad
 /*
Kyle McMartin 0c652ad
  * IF EFI is not configured, have the EFI calls return -ENOSYS.
Kyle McMartin 0c652ad
@@ -168,6 +170,10 @@ static inline efi_status_t efi_thunk_set_virtual_address_map(
Kyle McMartin 0c652ad
 #define efi_call5(_f, _a1, _a2, _a3, _a4, _a5)		(-ENOSYS)
Kyle McMartin 0c652ad
 #define efi_call6(_f, _a1, _a2, _a3, _a4, _a5, _a6)	(-ENOSYS)
Kyle McMartin 0c652ad
 static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {}
Kyle McMartin 0c652ad
+static inline bool efi_reboot_required(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	return false;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
 #endif /* CONFIG_EFI */
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 #endif /* _ASM_X86_EFI_H */
Kyle McMartin 0c652ad
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
Kyle McMartin 0c652ad
index 52b1157..17962e6 100644
Kyle McMartin 0c652ad
--- a/arch/x86/kernel/reboot.c
Kyle McMartin 0c652ad
+++ b/arch/x86/kernel/reboot.c
Kyle McMartin 0c652ad
@@ -28,6 +28,7 @@
Kyle McMartin 0c652ad
 #include <linux/mc146818rtc.h>
Kyle McMartin 0c652ad
 #include <asm/realmode.h>
Kyle McMartin 0c652ad
 #include <asm/x86_init.h>
Kyle McMartin 0c652ad
+#include <asm/efi.h>
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 /*
Kyle McMartin 0c652ad
  * Power off function, if any
Kyle McMartin 0c652ad
@@ -401,12 +402,25 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 static int __init reboot_init(void)
Kyle McMartin 0c652ad
 {
Kyle McMartin 0c652ad
+	int rv;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 	/*
Kyle McMartin 0c652ad
 	 * Only do the DMI check if reboot_type hasn't been overridden
Kyle McMartin 0c652ad
 	 * on the command line
Kyle McMartin 0c652ad
 	 */
Kyle McMartin 0c652ad
-	if (reboot_default)
Kyle McMartin 0c652ad
-		dmi_check_system(reboot_dmi_table);
Kyle McMartin 0c652ad
+	if (!reboot_default)
Kyle McMartin 0c652ad
+		return 0;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * The DMI quirks table takes precedence. If no quirks entry
Kyle McMartin 0c652ad
+	 * matches and the ACPI Hardware Reduced bit is set, force EFI
Kyle McMartin 0c652ad
+	 * reboot.
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	rv = dmi_check_system(reboot_dmi_table);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (!rv && efi_reboot_required())
Kyle McMartin 0c652ad
+		reboot_type = BOOT_EFI;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 	return 0;
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 core_initcall(reboot_init);
Kyle McMartin 0c652ad
@@ -528,11 +542,7 @@ static void native_machine_emergency_restart(void)
Kyle McMartin 0c652ad
 			break;
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 		case BOOT_EFI:
Kyle McMartin 0c652ad
-			if (efi_enabled(EFI_RUNTIME_SERVICES))
Kyle McMartin 0c652ad
-				efi.reset_system(reboot_mode == REBOOT_WARM ?
Kyle McMartin 0c652ad
-						 EFI_RESET_WARM :
Kyle McMartin 0c652ad
-						 EFI_RESET_COLD,
Kyle McMartin 0c652ad
-						 EFI_SUCCESS, 0, NULL);
Kyle McMartin 0c652ad
+			efi_reboot(reboot_mode, NULL);
Kyle McMartin 0c652ad
 			reboot_type = BOOT_BIOS;
Kyle McMartin 0c652ad
 			break;
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
Kyle McMartin 0c652ad
index 05882e4..1db67a7 100644
Kyle McMartin 0c652ad
--- a/drivers/ata/ahci.h
Kyle McMartin 0c652ad
+++ b/drivers/ata/ahci.h
Kyle McMartin 0c652ad
@@ -373,6 +373,8 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 int ahci_stop_engine(struct ata_port *ap);
Kyle McMartin 0c652ad
 void ahci_start_engine(struct ata_port *ap);
Kyle McMartin 0c652ad
+int ahci_restart_engine(struct ata_port *ap);
Kyle McMartin 0c652ad
+void ahci_sw_activity(struct ata_link *link);
Kyle McMartin 0c652ad
 int ahci_check_ready(struct ata_link *link);
Kyle McMartin 0c652ad
 int ahci_kick_engine(struct ata_port *ap);
Kyle McMartin 0c652ad
 int ahci_port_resume(struct ata_port *ap);
Kyle McMartin 0c652ad
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
Kyle McMartin 0c652ad
index 042a9bb..81fbdc9 100644
Kyle McMartin 0c652ad
--- a/drivers/ata/ahci_xgene.c
Kyle McMartin 0c652ad
+++ b/drivers/ata/ahci_xgene.c
Kyle McMartin 0c652ad
@@ -78,6 +78,7 @@
Kyle McMartin 0c652ad
 struct xgene_ahci_context {
Kyle McMartin 0c652ad
 	struct ahci_host_priv *hpriv;
Kyle McMartin 0c652ad
 	struct device *dev;
Kyle McMartin 0c652ad
+	u8 last_cmd[MAX_AHCI_CHN_PERCTR]; /* tracking the last command */
Kyle McMartin 0c652ad
 	void __iomem *csr_core;		/* Core CSR address of IP */
Kyle McMartin 0c652ad
 	void __iomem *csr_diag;		/* Diag CSR address of IP */
Kyle McMartin 0c652ad
 	void __iomem *csr_axi;		/* AXI CSR address of IP */
Kyle McMartin 0c652ad
@@ -98,20 +99,72 @@ static int xgene_ahci_init_memram(struct xgene_ahci_context *ctx)
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 /**
Kyle McMartin 0c652ad
+ * xgene_ahci_qc_issue - Issue commands to the device
Kyle McMartin 0c652ad
+ * @qc: Command to issue
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * Due to H/W errata, for the IENTIFY DEVICE command
Kyle McMartin 0c652ad
+ * controller is unable to clear the BSY bit after
Kyle McMartin 0c652ad
+ * receiving the PIO setup FIS and results the dma
Kyle McMartin 0c652ad
+ * state machine to go into the CMFatalErrorUpdate
Kyle McMartin 0c652ad
+ * state resulting in the dma state machine lockup.
Kyle McMartin 0c652ad
+ * By restarting the dma engine to move it removes
Kyle McMartin 0c652ad
+ * the controller out of lock up state.
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	struct ata_port *ap = qc->ap;
Kyle McMartin 0c652ad
+	void __iomem *port_mmio = ahci_port_base(ap);
Kyle McMartin 0c652ad
+	struct ahci_port_priv *pp = ap->private_data;
Kyle McMartin 0c652ad
+	struct ahci_host_priv *hpriv = ap->host->private_data;
Kyle McMartin 0c652ad
+	struct xgene_ahci_context *ctx = hpriv->plat_data;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Keep track of the currently active link.  It will be used
Kyle McMartin 0c652ad
+	 * in completion path to determine whether NCQ phase is in
Kyle McMartin 0c652ad
+	 * progress.
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	pp->active_link = qc->dev->link;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * Restart the dma engine if the last cmd issued
Kyle McMartin 0c652ad
+	 * is IDENTIFY DEVICE command
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA))
Kyle McMartin 0c652ad
+		ahci_restart_engine(ap);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (qc->tf.protocol == ATA_PROT_NCQ)
Kyle McMartin 0c652ad
+		writel(1 << qc->tag, port_mmio + PORT_SCR_ACT);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (pp->fbs_enabled && pp->fbs_last_dev != qc->dev->link->pmp) {
Kyle McMartin 0c652ad
+		u32 fbs = readl(port_mmio + PORT_FBS);
Kyle McMartin 0c652ad
+		fbs &= ~(PORT_FBS_DEV_MASK | PORT_FBS_DEC);
Kyle McMartin 0c652ad
+		fbs |= qc->dev->link->pmp << PORT_FBS_DEV_OFFSET;
Kyle McMartin 0c652ad
+		writel(fbs, port_mmio + PORT_FBS);
Kyle McMartin 0c652ad
+		pp->fbs_last_dev = qc->dev->link->pmp;
Kyle McMartin 0c652ad
+	}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Save the last command issued */
Kyle McMartin 0c652ad
+	ctx->last_cmd[ap->port_no] = qc->tf.command;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	ahci_sw_activity(qc->dev->link);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	return 0;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+/**
Kyle McMartin 0c652ad
  * xgene_ahci_read_id - Read ID data from the specified device
Kyle McMartin 0c652ad
  * @dev: device
Kyle McMartin 0c652ad
  * @tf: proposed taskfile
Kyle McMartin 0c652ad
  * @id: data buffer
Kyle McMartin 0c652ad
  *
Kyle McMartin 0c652ad
  * This custom read ID function is required due to the fact that the HW
Kyle McMartin 0c652ad
- * does not support DEVSLP and the controller state machine may get stuck
Kyle McMartin 0c652ad
- * after processing the ID query command.
Kyle McMartin 0c652ad
+ * does not support DEVSLP.
Kyle McMartin 0c652ad
  */
Kyle McMartin 0c652ad
 static unsigned int xgene_ahci_read_id(struct ata_device *dev,
Kyle McMartin 0c652ad
 				       struct ata_taskfile *tf, u16 *id)
Kyle McMartin 0c652ad
 {
Kyle McMartin 0c652ad
 	u32 err_mask;
Kyle McMartin 0c652ad
-	void __iomem *port_mmio = ahci_port_base(dev->link->ap);
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 	err_mask = ata_do_dev_read_id(dev, tf, id);
Kyle McMartin 0c652ad
 	if (err_mask)
Kyle McMartin 0c652ad
@@ -133,16 +186,6 @@ static unsigned int xgene_ahci_read_id(struct ata_device *dev,
Kyle McMartin 0c652ad
 	 */
Kyle McMartin 0c652ad
 	id[ATA_ID_FEATURE_SUPP] &= ~(1 << 8);
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
-	/*
Kyle McMartin 0c652ad
-	 * Due to HW errata, restart the port if no other command active.
Kyle McMartin 0c652ad
-	 * Otherwise the controller may get stuck.
Kyle McMartin 0c652ad
-	 */
Kyle McMartin 0c652ad
-	if (!readl(port_mmio + PORT_CMD_ISSUE)) {
Kyle McMartin 0c652ad
-		writel(PORT_CMD_FIS_RX, port_mmio + PORT_CMD);
Kyle McMartin 0c652ad
-		readl(port_mmio + PORT_CMD);	/* Force a barrier */
Kyle McMartin 0c652ad
-		writel(PORT_CMD_FIS_RX | PORT_CMD_START, port_mmio + PORT_CMD);
Kyle McMartin 0c652ad
-		readl(port_mmio + PORT_CMD);	/* Force a barrier */
Kyle McMartin 0c652ad
-	}
Kyle McMartin 0c652ad
 	return 0;
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
@@ -300,6 +343,7 @@ static struct ata_port_operations xgene_ahci_ops = {
Kyle McMartin 0c652ad
 	.host_stop = xgene_ahci_host_stop,
Kyle McMartin 0c652ad
 	.hardreset = xgene_ahci_hardreset,
Kyle McMartin 0c652ad
 	.read_id = xgene_ahci_read_id,
Kyle McMartin 0c652ad
+	.qc_issue = xgene_ahci_qc_issue,
Kyle McMartin 0c652ad
 };
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 static const struct ata_port_info xgene_ahci_port_info = {
Kyle McMartin 0c652ad
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
Kyle McMartin 0c652ad
index 40ea583..3ec5dc7 100644
Kyle McMartin 0c652ad
--- a/drivers/ata/libahci.c
Kyle McMartin 0c652ad
+++ b/drivers/ata/libahci.c
Kyle McMartin 0c652ad
@@ -747,6 +747,18 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
Kyle McMartin 0c652ad
 	return 0;
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
+int ahci_restart_engine(struct ata_port *ap)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	struct ahci_host_priv *hpriv = ap->host->private_data;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	ahci_stop_engine(ap);
Kyle McMartin 0c652ad
+	ahci_start_fis_rx(ap);
Kyle McMartin 0c652ad
+	hpriv->start_engine(ap);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	return 0;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+EXPORT_SYMBOL_GPL(ahci_restart_engine);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 #ifdef CONFIG_PM
Kyle McMartin 0c652ad
 static void ahci_power_down(struct ata_port *ap)
Kyle McMartin 0c652ad
 {
Kyle McMartin 0c652ad
@@ -886,7 +898,7 @@ int ahci_reset_controller(struct ata_host *host)
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
 EXPORT_SYMBOL_GPL(ahci_reset_controller);
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
-static void ahci_sw_activity(struct ata_link *link)
Kyle McMartin 0c652ad
+void ahci_sw_activity(struct ata_link *link)
Kyle McMartin 0c652ad
 {
Kyle McMartin 0c652ad
 	struct ata_port *ap = link->ap;
Kyle McMartin 0c652ad
 	struct ahci_port_priv *pp = ap->private_data;
Kyle McMartin 0c652ad
@@ -899,6 +911,7 @@ static void ahci_sw_activity(struct ata_link *link)
Kyle McMartin 0c652ad
 	if (!timer_pending(&emp->timer))
Kyle McMartin 0c652ad
 		mod_timer(&emp->timer, jiffies + msecs_to_jiffies(10));
Kyle McMartin 0c652ad
 }
Kyle McMartin 0c652ad
+EXPORT_SYMBOL_GPL(ahci_sw_activity);
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
 static void ahci_sw_activity_blink(unsigned long arg)
Kyle McMartin 0c652ad
 {
Kyle McMartin 0c652ad
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
Kyle McMartin 0c652ad
index 9553496..c135154 100644
Kyle McMartin 0c652ad
--- a/drivers/firmware/efi/Makefile
Kyle McMartin 0c652ad
+++ b/drivers/firmware/efi/Makefile
Kyle McMartin 0c652ad
@@ -1,7 +1,7 @@
Kyle McMartin 0c652ad
 #
Kyle McMartin 0c652ad
 # Makefile for linux kernel
Kyle McMartin 0c652ad
 #
Kyle McMartin 0c652ad
-obj-$(CONFIG_EFI)			+= efi.o vars.o
Kyle McMartin 0c652ad
+obj-$(CONFIG_EFI)			+= efi.o vars.o reboot.o
Kyle McMartin 0c652ad
 obj-$(CONFIG_EFI_VARS)			+= efivars.o
Kyle McMartin 0c652ad
 obj-$(CONFIG_EFI_VARS_PSTORE)		+= efi-pstore.o
Kyle McMartin 0c652ad
 obj-$(CONFIG_UEFI_CPER)			+= cper.o
Kyle McMartin 0c652ad
diff --git a/drivers/firmware/efi/reboot.c b/drivers/firmware/efi/reboot.c
Kyle McMartin 0c652ad
new file mode 100644
Kyle McMartin 0c652ad
index 0000000..f94fb95
Kyle McMartin 0c652ad
--- /dev/null
Kyle McMartin 0c652ad
+++ b/drivers/firmware/efi/reboot.c
Kyle McMartin 0c652ad
@@ -0,0 +1,55 @@
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * Copyright (C) 2014 Intel Corporation; author Matt Fleming
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+#include <linux/efi.h>
Kyle McMartin 0c652ad
+#include <linux/reboot.h>
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+int efi_reboot_quirk_mode = -1;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+void efi_reboot(enum reboot_mode reboot_mode, const char *__unused)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	int efi_mode;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (!efi_enabled(EFI_RUNTIME_SERVICES))
Kyle McMartin 0c652ad
+		return;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	switch (reboot_mode) {
Kyle McMartin 0c652ad
+	case REBOOT_WARM:
Kyle McMartin 0c652ad
+	case REBOOT_SOFT:
Kyle McMartin 0c652ad
+		efi_mode = EFI_RESET_WARM;
Kyle McMartin 0c652ad
+		break;
Kyle McMartin 0c652ad
+	default:
Kyle McMartin 0c652ad
+		efi_mode = EFI_RESET_COLD;
Kyle McMartin 0c652ad
+		break;
Kyle McMartin 0c652ad
+	}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * If a quirk forced an EFI reset mode, always use that.
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	if (efi_reboot_quirk_mode != -1)
Kyle McMartin 0c652ad
+		efi_mode = efi_reboot_quirk_mode;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	efi.reset_system(efi_mode, EFI_SUCCESS, 0, NULL);
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+bool __weak efi_poweroff_required(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	return false;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void efi_power_off(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static int __init efi_shutdown_init(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	if (!efi_enabled(EFI_RUNTIME_SERVICES))
Kyle McMartin 0c652ad
+		return -ENODEV;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (efi_poweroff_required())
Kyle McMartin 0c652ad
+		pm_power_off = efi_power_off;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	return 0;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+late_initcall(efi_shutdown_init);
Kyle McMartin 0c652ad
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
Kyle McMartin 0c652ad
index bbb746e..7f0c2a3 100644
Kyle McMartin 0c652ad
--- a/drivers/irqchip/Kconfig
Kyle McMartin 0c652ad
+++ b/drivers/irqchip/Kconfig
Kyle McMartin 0c652ad
@@ -10,6 +10,11 @@ config ARM_GIC
Kyle McMartin 0c652ad
 config GIC_NON_BANKED
Kyle McMartin 0c652ad
 	bool
Kyle McMartin 0c652ad
 
Kyle McMartin 0c652ad
+config ARM_GIC_V3
Kyle McMartin 0c652ad
+	bool
Kyle McMartin 0c652ad
+	select IRQ_DOMAIN
Kyle McMartin 0c652ad
+	select MULTI_IRQ_HANDLER
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
 config ARM_NVIC
Kyle McMartin 0c652ad
 	bool
Kyle McMartin 0c652ad
 	select IRQ_DOMAIN
Kyle McMartin 0c652ad
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
Kyle McMartin 0c652ad
index 62a13e5..c57e642 100644
Kyle McMartin 0c652ad
--- a/drivers/irqchip/Makefile
Kyle McMartin 0c652ad
+++ b/drivers/irqchip/Makefile
Kyle McMartin 0c652ad
@@ -15,7 +15,8 @@ obj-$(CONFIG_ORION_IRQCHIP)		+= irq-orion.o
Kyle McMartin 0c652ad
 obj-$(CONFIG_ARCH_SUNXI)		+= irq-sun4i.o
Kyle McMartin 0c652ad
 obj-$(CONFIG_ARCH_SUNXI)		+= irq-sunxi-nmi.o
Kyle McMartin 0c652ad
 obj-$(CONFIG_ARCH_SPEAR3XX)		+= spear-shirq.o
Kyle McMartin 0c652ad
-obj-$(CONFIG_ARM_GIC)			+= irq-gic.o
Kyle McMartin 0c652ad
+obj-$(CONFIG_ARM_GIC)			+= irq-gic.o irq-gic-common.o
Kyle McMartin 0c652ad
+obj-$(CONFIG_ARM_GIC_V3)		+= irq-gic-v3.o irq-gic-common.o
Kyle McMartin 0c652ad
 obj-$(CONFIG_ARM_NVIC)			+= irq-nvic.o
Kyle McMartin 0c652ad
 obj-$(CONFIG_ARM_VIC)			+= irq-vic.o
Kyle McMartin 0c652ad
 obj-$(CONFIG_IMGPDC_IRQ)		+= irq-imgpdc.o
Kyle McMartin 0c652ad
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
Kyle McMartin 0c652ad
new file mode 100644
Kyle McMartin 0c652ad
index 0000000..60ac704
Kyle McMartin 0c652ad
--- /dev/null
Kyle McMartin 0c652ad
+++ b/drivers/irqchip/irq-gic-common.c
Kyle McMartin 0c652ad
@@ -0,0 +1,115 @@
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * Copyright (C) 2002 ARM Limited, All Rights Reserved.
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * This program is free software; you can redistribute it and/or modify
Kyle McMartin 0c652ad
+ * it under the terms of the GNU General Public License version 2 as
Kyle McMartin 0c652ad
+ * published by the Free Software Foundation.
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * This program is distributed in the hope that it will be useful,
Kyle McMartin 0c652ad
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
Kyle McMartin 0c652ad
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Kyle McMartin 0c652ad
+ * GNU General Public License for more details.
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * You should have received a copy of the GNU General Public License
Kyle McMartin 0c652ad
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#include <linux/interrupt.h>
Kyle McMartin 0c652ad
+#include <linux/io.h>
Kyle McMartin 0c652ad
+#include <linux/irq.h>
Kyle McMartin 0c652ad
+#include <linux/irqchip/arm-gic.h>
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#include "irq-gic-common.h"
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+void gic_configure_irq(unsigned int irq, unsigned int type,
Kyle McMartin 0c652ad
+		       void __iomem *base, void (*sync_access)(void))
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	u32 enablemask = 1 << (irq % 32);
Kyle McMartin 0c652ad
+	u32 enableoff = (irq / 32) * 4;
Kyle McMartin 0c652ad
+	u32 confmask = 0x2 << ((irq % 16) * 2);
Kyle McMartin 0c652ad
+	u32 confoff = (irq / 16) * 4;
Kyle McMartin 0c652ad
+	bool enabled = false;
Kyle McMartin 0c652ad
+	u32 val;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * Read current configuration register, and insert the config
Kyle McMartin 0c652ad
+	 * for "irq", depending on "type".
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	val = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
Kyle McMartin 0c652ad
+	if (type == IRQ_TYPE_LEVEL_HIGH)
Kyle McMartin 0c652ad
+		val &= ~confmask;
Kyle McMartin 0c652ad
+	else if (type == IRQ_TYPE_EDGE_RISING)
Kyle McMartin 0c652ad
+		val |= confmask;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * As recommended by the spec, disable the interrupt before changing
Kyle McMartin 0c652ad
+	 * the configuration
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
Kyle McMartin 0c652ad
+		writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
Kyle McMartin 0c652ad
+		if (sync_access)
Kyle McMartin 0c652ad
+			sync_access();
Kyle McMartin 0c652ad
+		enabled = true;
Kyle McMartin 0c652ad
+	}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * Write back the new configuration, and possibly re-enable
Kyle McMartin 0c652ad
+	 * the interrupt.
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (enabled)
Kyle McMartin 0c652ad
+		writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (sync_access)
Kyle McMartin 0c652ad
+		sync_access();
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+void __init gic_dist_config(void __iomem *base, int gic_irqs,
Kyle McMartin 0c652ad
+			    void (*sync_access)(void))
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	unsigned int i;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * Set all global interrupts to be level triggered, active low.
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	for (i = 32; i < gic_irqs; i += 16)
Kyle McMartin 0c652ad
+		writel_relaxed(0, base + GIC_DIST_CONFIG + i / 4);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * Set priority on all global interrupts.
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	for (i = 32; i < gic_irqs; i += 4)
Kyle McMartin 0c652ad
+		writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * Disable all interrupts.  Leave the PPI and SGIs alone
Kyle McMartin 0c652ad
+	 * as they are enabled by redistributor registers.
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	for (i = 32; i < gic_irqs; i += 32)
Kyle McMartin 0c652ad
+		writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i / 8);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (sync_access)
Kyle McMartin 0c652ad
+		sync_access();
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+void gic_cpu_config(void __iomem *base, void (*sync_access)(void))
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	int i;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * Deal with the banked PPI and SGI interrupts - disable all
Kyle McMartin 0c652ad
+	 * PPI interrupts, ensure all SGI interrupts are enabled.
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	writel_relaxed(0xffff0000, base + GIC_DIST_ENABLE_CLEAR);
Kyle McMartin 0c652ad
+	writel_relaxed(0x0000ffff, base + GIC_DIST_ENABLE_SET);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * Set priority on PPI and SGI interrupts
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	for (i = 0; i < 32; i += 4)
Kyle McMartin 0c652ad
+		writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (sync_access)
Kyle McMartin 0c652ad
+		sync_access();
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h
Kyle McMartin 0c652ad
new file mode 100644
Kyle McMartin 0c652ad
index 0000000..b41f024
Kyle McMartin 0c652ad
--- /dev/null
Kyle McMartin 0c652ad
+++ b/drivers/irqchip/irq-gic-common.h
Kyle McMartin 0c652ad
@@ -0,0 +1,29 @@
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * Copyright (C) 2002 ARM Limited, All Rights Reserved.
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * This program is free software; you can redistribute it and/or modify
Kyle McMartin 0c652ad
+ * it under the terms of the GNU General Public License version 2 as
Kyle McMartin 0c652ad
+ * published by the Free Software Foundation.
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * This program is distributed in the hope that it will be useful,
Kyle McMartin 0c652ad
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
Kyle McMartin 0c652ad
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Kyle McMartin 0c652ad
+ * GNU General Public License for more details.
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * You should have received a copy of the GNU General Public License
Kyle McMartin 0c652ad
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#ifndef _IRQ_GIC_COMMON_H
Kyle McMartin 0c652ad
+#define _IRQ_GIC_COMMON_H
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#include <linux/of.h>
Kyle McMartin 0c652ad
+#include <linux/irqdomain.h>
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+void gic_configure_irq(unsigned int irq, unsigned int type,
Kyle McMartin 0c652ad
+                       void __iomem *base, void (*sync_access)(void));
Kyle McMartin 0c652ad
+void gic_dist_config(void __iomem *base, int gic_irqs,
Kyle McMartin 0c652ad
+		     void (*sync_access)(void));
Kyle McMartin 0c652ad
+void gic_cpu_config(void __iomem *base, void (*sync_access)(void));
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#endif /* _IRQ_GIC_COMMON_H */
Kyle McMartin 0c652ad
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
Kyle McMartin 0c652ad
new file mode 100644
Kyle McMartin 0c652ad
index 0000000..c3dd8ad
Kyle McMartin 0c652ad
--- /dev/null
Kyle McMartin 0c652ad
+++ b/drivers/irqchip/irq-gic-v3.c
Kyle McMartin 0c652ad
@@ -0,0 +1,690 @@
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * Copyright (C) 2013, 2014 ARM Limited, All Rights Reserved.
Kyle McMartin 0c652ad
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * This program is free software; you can redistribute it and/or modify
Kyle McMartin 0c652ad
+ * it under the terms of the GNU General Public License version 2 as
Kyle McMartin 0c652ad
+ * published by the Free Software Foundation.
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * This program is distributed in the hope that it will be useful,
Kyle McMartin 0c652ad
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
Kyle McMartin 0c652ad
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Kyle McMartin 0c652ad
+ * GNU General Public License for more details.
Kyle McMartin 0c652ad
+ *
Kyle McMartin 0c652ad
+ * You should have received a copy of the GNU General Public License
Kyle McMartin 0c652ad
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#include <linux/cpu.h>
Kyle McMartin 0c652ad
+#include <linux/delay.h>
Kyle McMartin 0c652ad
+#include <linux/interrupt.h>
Kyle McMartin 0c652ad
+#include <linux/of.h>
Kyle McMartin 0c652ad
+#include <linux/of_address.h>
Kyle McMartin 0c652ad
+#include <linux/of_irq.h>
Kyle McMartin 0c652ad
+#include <linux/percpu.h>
Kyle McMartin 0c652ad
+#include <linux/slab.h>
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#include <linux/irqchip/arm-gic-v3.h>
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#include <asm/cputype.h>
Kyle McMartin 0c652ad
+#include <asm/exception.h>
Kyle McMartin 0c652ad
+#include <asm/smp_plat.h>
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#include "irq-gic-common.h"
Kyle McMartin 0c652ad
+#include "irqchip.h"
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+struct gic_chip_data {
Kyle McMartin 0c652ad
+	void __iomem		*dist_base;
Kyle McMartin 0c652ad
+	void __iomem		**redist_base;
Kyle McMartin 0c652ad
+	void __percpu __iomem	**rdist;
Kyle McMartin 0c652ad
+	struct irq_domain	*domain;
Kyle McMartin 0c652ad
+	u64			redist_stride;
Kyle McMartin 0c652ad
+	u32			redist_regions;
Kyle McMartin 0c652ad
+	unsigned int		irq_nr;
Kyle McMartin 0c652ad
+};
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static struct gic_chip_data gic_data __read_mostly;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#define gic_data_rdist()		(this_cpu_ptr(gic_data.rdist))
Kyle McMartin 0c652ad
+#define gic_data_rdist_rd_base()	(*gic_data_rdist())
Kyle McMartin 0c652ad
+#define gic_data_rdist_sgi_base()	(gic_data_rdist_rd_base() + SZ_64K)
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#define DEFAULT_PMR_VALUE	0xf0
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static inline unsigned int gic_irq(struct irq_data *d)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	return d->hwirq;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static inline int gic_irq_in_rdist(struct irq_data *d)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	return gic_irq(d) < 32;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static inline void __iomem *gic_dist_base(struct irq_data *d)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	if (gic_irq_in_rdist(d))	/* SGI+PPI -> SGI_base for this CPU */
Kyle McMartin 0c652ad
+		return gic_data_rdist_sgi_base();
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (d->hwirq <= 1023)		/* SPI -> dist_base */
Kyle McMartin 0c652ad
+		return gic_data.dist_base;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (d->hwirq >= 8192)
Kyle McMartin 0c652ad
+		BUG();		/* LPI Detected!!! */
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	return NULL;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_do_wait_for_rwp(void __iomem *base)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	u32 count = 1000000;	/* 1s! */
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	while (readl_relaxed(base + GICD_CTLR) & GICD_CTLR_RWP) {
Kyle McMartin 0c652ad
+		count--;
Kyle McMartin 0c652ad
+		if (!count) {
Kyle McMartin 0c652ad
+			pr_err_ratelimited("RWP timeout, gone fishing\n");
Kyle McMartin 0c652ad
+			return;
Kyle McMartin 0c652ad
+		}
Kyle McMartin 0c652ad
+		cpu_relax();
Kyle McMartin 0c652ad
+		udelay(1);
Kyle McMartin 0c652ad
+	};
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+/* Wait for completion of a distributor change */
Kyle McMartin 0c652ad
+static void gic_dist_wait_for_rwp(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	gic_do_wait_for_rwp(gic_data.dist_base);
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+/* Wait for completion of a redistributor change */
Kyle McMartin 0c652ad
+static void gic_redist_wait_for_rwp(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	gic_do_wait_for_rwp(gic_data_rdist_rd_base());
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+/* Low level accessors */
Kyle McMartin 0c652ad
+static u64 gic_read_iar(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	u64 irqstat;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	asm volatile("mrs %0, " __stringify(ICC_IAR1_EL1) : "=r" (irqstat));
Kyle McMartin 0c652ad
+	return irqstat;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_write_pmr(u64 val)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	asm volatile("msr " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val));
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_write_ctlr(u64 val)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	asm volatile("msr " __stringify(ICC_CTLR_EL1) ", %0" : : "r" (val));
Kyle McMartin 0c652ad
+	isb();
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_write_grpen1(u64 val)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	asm volatile("msr " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" (val));
Kyle McMartin 0c652ad
+	isb();
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_write_sgi1r(u64 val)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	asm volatile("msr " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val));
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_enable_sre(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	u64 val;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	asm volatile("mrs %0, " __stringify(ICC_SRE_EL1) : "=r" (val));
Kyle McMartin 0c652ad
+	val |= ICC_SRE_EL1_SRE;
Kyle McMartin 0c652ad
+	asm volatile("msr " __stringify(ICC_SRE_EL1) ", %0" : : "r" (val));
Kyle McMartin 0c652ad
+	isb();
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * Need to check that the SRE bit has actually been set. If
Kyle McMartin 0c652ad
+	 * not, it means that SRE is disabled at EL2. We're going to
Kyle McMartin 0c652ad
+	 * die painfully, and there is nothing we can do about it.
Kyle McMartin 0c652ad
+	 *
Kyle McMartin 0c652ad
+	 * Kindly inform the luser.
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	asm volatile("mrs %0, " __stringify(ICC_SRE_EL1) : "=r" (val));
Kyle McMartin 0c652ad
+	if (!(val & ICC_SRE_EL1_SRE))
Kyle McMartin 0c652ad
+		pr_err("GIC: unable to set SRE (disabled at EL2), panic ahead\n");
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_enable_redist(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	void __iomem *rbase;
Kyle McMartin 0c652ad
+	u32 count = 1000000;	/* 1s! */
Kyle McMartin 0c652ad
+	u32 val;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	rbase = gic_data_rdist_rd_base();
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Wake up this CPU redistributor */
Kyle McMartin 0c652ad
+	val = readl_relaxed(rbase + GICR_WAKER);
Kyle McMartin 0c652ad
+	val &= ~GICR_WAKER_ProcessorSleep;
Kyle McMartin 0c652ad
+	writel_relaxed(val, rbase + GICR_WAKER);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	while (readl_relaxed(rbase + GICR_WAKER) & GICR_WAKER_ChildrenAsleep) {
Kyle McMartin 0c652ad
+		count--;
Kyle McMartin 0c652ad
+		if (!count) {
Kyle McMartin 0c652ad
+			pr_err_ratelimited("redist didn't wake up...\n");
Kyle McMartin 0c652ad
+			return;
Kyle McMartin 0c652ad
+		}
Kyle McMartin 0c652ad
+		cpu_relax();
Kyle McMartin 0c652ad
+		udelay(1);
Kyle McMartin 0c652ad
+	};
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * Routines to acknowledge, disable and enable interrupts
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+static void gic_poke_irq(struct irq_data *d, u32 offset)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	u32 mask = 1 << (gic_irq(d) % 32);
Kyle McMartin 0c652ad
+	void (*rwp_wait)(void);
Kyle McMartin 0c652ad
+	void __iomem *base;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (gic_irq_in_rdist(d)) {
Kyle McMartin 0c652ad
+		base = gic_data_rdist_sgi_base();
Kyle McMartin 0c652ad
+		rwp_wait = gic_redist_wait_for_rwp;
Kyle McMartin 0c652ad
+	} else {
Kyle McMartin 0c652ad
+		base = gic_data.dist_base;
Kyle McMartin 0c652ad
+		rwp_wait = gic_dist_wait_for_rwp;
Kyle McMartin 0c652ad
+	}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	writel_relaxed(mask, base + offset + (gic_irq(d) / 32) * 4);
Kyle McMartin 0c652ad
+	rwp_wait();
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static int gic_peek_irq(struct irq_data *d, u32 offset)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	u32 mask = 1 << (gic_irq(d) % 32);
Kyle McMartin 0c652ad
+	void __iomem *base;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (gic_irq_in_rdist(d))
Kyle McMartin 0c652ad
+		base = gic_data_rdist_sgi_base();
Kyle McMartin 0c652ad
+	else
Kyle McMartin 0c652ad
+		base = gic_data.dist_base;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	return !!(readl_relaxed(base + offset + (gic_irq(d) / 32) * 4) & mask);
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_mask_irq(struct irq_data *d)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	gic_poke_irq(d, GICD_ICENABLER);
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_unmask_irq(struct irq_data *d)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	gic_poke_irq(d, GICD_ISENABLER);
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_eoi_irq(struct irq_data *d)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	gic_write_eoir(gic_irq(d));
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static int gic_set_type(struct irq_data *d, unsigned int type)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	unsigned int irq = gic_irq(d);
Kyle McMartin 0c652ad
+	void (*rwp_wait)(void);
Kyle McMartin 0c652ad
+	void __iomem *base;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Interrupt configuration for SGIs can't be changed */
Kyle McMartin 0c652ad
+	if (irq < 16)
Kyle McMartin 0c652ad
+		return -EINVAL;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
Kyle McMartin 0c652ad
+		return -EINVAL;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (gic_irq_in_rdist(d)) {
Kyle McMartin 0c652ad
+		base = gic_data_rdist_sgi_base();
Kyle McMartin 0c652ad
+		rwp_wait = gic_redist_wait_for_rwp;
Kyle McMartin 0c652ad
+	} else {
Kyle McMartin 0c652ad
+		base = gic_data.dist_base;
Kyle McMartin 0c652ad
+		rwp_wait = gic_dist_wait_for_rwp;
Kyle McMartin 0c652ad
+	}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	gic_configure_irq(irq, type, base, rwp_wait);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	return 0;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static u64 gic_mpidr_to_affinity(u64 mpidr)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	u64 aff;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 32 |
Kyle McMartin 0c652ad
+	       MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
Kyle McMartin 0c652ad
+	       MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8  |
Kyle McMartin 0c652ad
+	       MPIDR_AFFINITY_LEVEL(mpidr, 0)) & ~GICD_IROUTER_SPI_MODE_ANY;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	return aff;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	u64 irqnr;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	do {
Kyle McMartin 0c652ad
+		irqnr = gic_read_iar();
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+		if (likely(irqnr > 15 && irqnr < 1020)) {
Kyle McMartin 0c652ad
+			u64 irq = irq_find_mapping(gic_data.domain, irqnr);
Kyle McMartin 0c652ad
+			if (likely(irq)) {
Kyle McMartin 0c652ad
+				handle_IRQ(irq, regs);
Kyle McMartin 0c652ad
+				continue;
Kyle McMartin 0c652ad
+			}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+			WARN_ONCE(true, "Unexpected SPI received!\n");
Kyle McMartin 0c652ad
+			gic_write_eoir(irqnr);
Kyle McMartin 0c652ad
+		}
Kyle McMartin 0c652ad
+		if (irqnr < 16) {
Kyle McMartin 0c652ad
+			gic_write_eoir(irqnr);
Kyle McMartin 0c652ad
+#ifdef CONFIG_SMP
Kyle McMartin 0c652ad
+			handle_IPI(irqnr, regs);
Kyle McMartin 0c652ad
+#else
Kyle McMartin 0c652ad
+			WARN_ONCE(true, "Unexpected SGI received!\n");
Kyle McMartin 0c652ad
+#endif
Kyle McMartin 0c652ad
+			continue;
Kyle McMartin 0c652ad
+		}
Kyle McMartin 0c652ad
+	} while (irqnr != 0x3ff);
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void __init gic_dist_init(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	unsigned int i;
Kyle McMartin 0c652ad
+	u64 affinity;
Kyle McMartin 0c652ad
+	void __iomem *base = gic_data.dist_base;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Disable the distributor */
Kyle McMartin 0c652ad
+	writel_relaxed(0, base + GICD_CTLR);
Kyle McMartin 0c652ad
+	gic_dist_wait_for_rwp();
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Enable distributor with ARE, Group1 */
Kyle McMartin 0c652ad
+	writel_relaxed(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1,
Kyle McMartin 0c652ad
+		       base + GICD_CTLR);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * Set all global interrupts to the boot CPU only. ARE must be
Kyle McMartin 0c652ad
+	 * enabled.
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	affinity = gic_mpidr_to_affinity(cpu_logical_map(smp_processor_id()));
Kyle McMartin 0c652ad
+	for (i = 32; i < gic_data.irq_nr; i++)
Kyle McMartin 0c652ad
+		writeq_relaxed(affinity, base + GICD_IROUTER + i * 8);
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static int gic_populate_rdist(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	u64 mpidr = cpu_logical_map(smp_processor_id());
Kyle McMartin 0c652ad
+	u64 typer;
Kyle McMartin 0c652ad
+	u32 aff;
Kyle McMartin 0c652ad
+	int i;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * Convert affinity to a 32bit value that can be matched to
Kyle McMartin 0c652ad
+	 * GICR_TYPER bits [63:32].
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 |
Kyle McMartin 0c652ad
+	       MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
Kyle McMartin 0c652ad
+	       MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
Kyle McMartin 0c652ad
+	       MPIDR_AFFINITY_LEVEL(mpidr, 0));
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	for (i = 0; i < gic_data.redist_regions; i++) {
Kyle McMartin 0c652ad
+		void __iomem *ptr = gic_data.redist_base[i];
Kyle McMartin 0c652ad
+		u32 reg;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+		reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK;
Kyle McMartin 0c652ad
+		if (reg != 0x30 && reg != 0x40) { /* We're in trouble... */
Kyle McMartin 0c652ad
+			pr_warn("No redistributor present @%p\n", ptr);
Kyle McMartin 0c652ad
+			break;
Kyle McMartin 0c652ad
+		}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+		do {
Kyle McMartin 0c652ad
+			typer = readq_relaxed(ptr + GICR_TYPER);
Kyle McMartin 0c652ad
+			if ((typer >> 32) == aff) {
Kyle McMartin 0c652ad
+				gic_data_rdist_rd_base() = ptr;
Kyle McMartin 0c652ad
+				pr_info("CPU%d: found redistributor %llx @%p\n",
Kyle McMartin 0c652ad
+					smp_processor_id(),
Kyle McMartin 0c652ad
+					(unsigned long long)mpidr, ptr);
Kyle McMartin 0c652ad
+				return 0;
Kyle McMartin 0c652ad
+			}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+			if (gic_data.redist_stride) {
Kyle McMartin 0c652ad
+				ptr += gic_data.redist_stride;
Kyle McMartin 0c652ad
+			} else {
Kyle McMartin 0c652ad
+				ptr += SZ_64K * 2; /* Skip RD_base + SGI_base */
Kyle McMartin 0c652ad
+				if (typer & GICR_TYPER_VLPIS)
Kyle McMartin 0c652ad
+					ptr += SZ_64K * 2; /* Skip VLPI_base + reserved page */
Kyle McMartin 0c652ad
+			}
Kyle McMartin 0c652ad
+		} while (!(typer & GICR_TYPER_LAST));
Kyle McMartin 0c652ad
+	}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* We couldn't even deal with ourselves... */
Kyle McMartin 0c652ad
+	WARN(true, "CPU%d: mpidr %llx has no re-distributor!\n",
Kyle McMartin 0c652ad
+	     smp_processor_id(), (unsigned long long)mpidr);
Kyle McMartin 0c652ad
+	return -ENODEV;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_cpu_init(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	void __iomem *rbase;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Register ourselves with the rest of the world */
Kyle McMartin 0c652ad
+	if (gic_populate_rdist())
Kyle McMartin 0c652ad
+		return;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	gic_enable_redist();
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	rbase = gic_data_rdist_sgi_base();
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	gic_cpu_config(rbase, gic_redist_wait_for_rwp);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Enable system registers */
Kyle McMartin 0c652ad
+	gic_enable_sre();
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Set priority mask register */
Kyle McMartin 0c652ad
+	gic_write_pmr(DEFAULT_PMR_VALUE);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* EOI deactivates interrupt too (mode 0) */
Kyle McMartin 0c652ad
+	gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* ... and let's hit the road... */
Kyle McMartin 0c652ad
+	gic_write_grpen1(1);
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+#ifdef CONFIG_SMP
Kyle McMartin 0c652ad
+static int gic_secondary_init(struct notifier_block *nfb,
Kyle McMartin 0c652ad
+			      unsigned long action, void *hcpu)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
Kyle McMartin 0c652ad
+		gic_cpu_init();
Kyle McMartin 0c652ad
+	return NOTIFY_OK;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+/*
Kyle McMartin 0c652ad
+ * Notifier for enabling the GIC CPU interface. Set an arbitrarily high
Kyle McMartin 0c652ad
+ * priority because the GIC needs to be up before the ARM generic timers.
Kyle McMartin 0c652ad
+ */
Kyle McMartin 0c652ad
+static struct notifier_block gic_cpu_notifier = {
Kyle McMartin 0c652ad
+	.notifier_call = gic_secondary_init,
Kyle McMartin 0c652ad
+	.priority = 100,
Kyle McMartin 0c652ad
+};
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask,
Kyle McMartin 0c652ad
+				   u64 cluster_id)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	int cpu = *base_cpu;
Kyle McMartin 0c652ad
+	u64 mpidr = cpu_logical_map(cpu);
Kyle McMartin 0c652ad
+	u16 tlist = 0;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	while (cpu < nr_cpu_ids) {
Kyle McMartin 0c652ad
+		/*
Kyle McMartin 0c652ad
+		 * If we ever get a cluster of more than 16 CPUs, just
Kyle McMartin 0c652ad
+		 * scream and skip that CPU.
Kyle McMartin 0c652ad
+		 */
Kyle McMartin 0c652ad
+		if (WARN_ON((mpidr & 0xff) >= 16))
Kyle McMartin 0c652ad
+			goto out;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+		tlist |= 1 << (mpidr & 0xf);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+		cpu = cpumask_next(cpu, mask);
Kyle McMartin 0c652ad
+		if (cpu == nr_cpu_ids)
Kyle McMartin 0c652ad
+			goto out;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+		mpidr = cpu_logical_map(cpu);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+		if (cluster_id != (mpidr & ~0xffUL)) {
Kyle McMartin 0c652ad
+			cpu--;
Kyle McMartin 0c652ad
+			goto out;
Kyle McMartin 0c652ad
+		}
Kyle McMartin 0c652ad
+	}
Kyle McMartin 0c652ad
+out:
Kyle McMartin 0c652ad
+	*base_cpu = cpu;
Kyle McMartin 0c652ad
+	return tlist;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_send_sgi(u64 cluster_id, u16 tlist, unsigned int irq)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	u64 val;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	val = (MPIDR_AFFINITY_LEVEL(cluster_id, 3) << 48	|
Kyle McMartin 0c652ad
+	       MPIDR_AFFINITY_LEVEL(cluster_id, 2) << 32	|
Kyle McMartin 0c652ad
+	       irq << 24			    		|
Kyle McMartin 0c652ad
+	       MPIDR_AFFINITY_LEVEL(cluster_id, 1) << 16	|
Kyle McMartin 0c652ad
+	       tlist);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	pr_debug("CPU%d: ICC_SGI1R_EL1 %llx\n", smp_processor_id(), val);
Kyle McMartin 0c652ad
+	gic_write_sgi1r(val);
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	int cpu;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (WARN_ON(irq >= 16))
Kyle McMartin 0c652ad
+		return;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * Ensure that stores to Normal memory are visible to the
Kyle McMartin 0c652ad
+	 * other CPUs before issuing the IPI.
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	smp_wmb();
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	for_each_cpu_mask(cpu, *mask) {
Kyle McMartin 0c652ad
+		u64 cluster_id = cpu_logical_map(cpu) & ~0xffUL;
Kyle McMartin 0c652ad
+		u16 tlist;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+		tlist = gic_compute_target_list(&cpu, mask, cluster_id);
Kyle McMartin 0c652ad
+		gic_send_sgi(cluster_id, tlist, irq);
Kyle McMartin 0c652ad
+	}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* Force the above writes to ICC_SGI1R_EL1 to be executed */
Kyle McMartin 0c652ad
+	isb();
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static void gic_smp_init(void)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	set_smp_cross_call(gic_raise_softirq);
Kyle McMartin 0c652ad
+	register_cpu_notifier(&gic_cpu_notifier);
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
Kyle McMartin 0c652ad
+			    bool force)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
Kyle McMartin 0c652ad
+	void __iomem *reg;
Kyle McMartin 0c652ad
+	int enabled;
Kyle McMartin 0c652ad
+	u64 val;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	if (gic_irq_in_rdist(d))
Kyle McMartin 0c652ad
+		return -EINVAL;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/* If interrupt was enabled, disable it first */
Kyle McMartin 0c652ad
+	enabled = gic_peek_irq(d, GICD_ISENABLER);
Kyle McMartin 0c652ad
+	if (enabled)
Kyle McMartin 0c652ad
+		gic_mask_irq(d);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	reg = gic_dist_base(d) + GICD_IROUTER + (gic_irq(d) * 8);
Kyle McMartin 0c652ad
+	val = gic_mpidr_to_affinity(cpu_logical_map(cpu));
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	writeq_relaxed(val, reg);
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	/*
Kyle McMartin 0c652ad
+	 * If the interrupt was enabled, enabled it again. Otherwise,
Kyle McMartin 0c652ad
+	 * just wait for the distributor to have digested our changes.
Kyle McMartin 0c652ad
+	 */
Kyle McMartin 0c652ad
+	if (enabled)
Kyle McMartin 0c652ad
+		gic_unmask_irq(d);
Kyle McMartin 0c652ad
+	else
Kyle McMartin 0c652ad
+		gic_dist_wait_for_rwp();
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	return IRQ_SET_MASK_OK;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+#else
Kyle McMartin 0c652ad
+#define gic_set_affinity	NULL
Kyle McMartin 0c652ad
+#define gic_smp_init()		do { } while(0)
Kyle McMartin 0c652ad
+#endif
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static struct irq_chip gic_chip = {
Kyle McMartin 0c652ad
+	.name			= "GICv3",
Kyle McMartin 0c652ad
+	.irq_mask		= gic_mask_irq,
Kyle McMartin 0c652ad
+	.irq_unmask		= gic_unmask_irq,
Kyle McMartin 0c652ad
+	.irq_eoi		= gic_eoi_irq,
Kyle McMartin 0c652ad
+	.irq_set_type		= gic_set_type,
Kyle McMartin 0c652ad
+	.irq_set_affinity	= gic_set_affinity,
Kyle McMartin 0c652ad
+};
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
Kyle McMartin 0c652ad
+			      irq_hw_number_t hw)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	/* SGIs are private to the core kernel */
Kyle McMartin 0c652ad
+	if (hw < 16)
Kyle McMartin 0c652ad
+		return -EPERM;
Kyle McMartin 0c652ad
+	/* PPIs */
Kyle McMartin 0c652ad
+	if (hw < 32) {
Kyle McMartin 0c652ad
+		irq_set_percpu_devid(irq);
Kyle McMartin 0c652ad
+		irq_set_chip_and_handler(irq, &gic_chip,
Kyle McMartin 0c652ad
+					 handle_percpu_devid_irq);
Kyle McMartin 0c652ad
+		set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
Kyle McMartin 0c652ad
+	}
Kyle McMartin 0c652ad
+	/* SPIs */
Kyle McMartin 0c652ad
+	if (hw >= 32 && hw < gic_data.irq_nr) {
Kyle McMartin 0c652ad
+		irq_set_chip_and_handler(irq, &gic_chip,
Kyle McMartin 0c652ad
+					 handle_fasteoi_irq);
Kyle McMartin 0c652ad
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
Kyle McMartin 0c652ad
+	}
Kyle McMartin 0c652ad
+	irq_set_chip_data(irq, d->host_data);
Kyle McMartin 0c652ad
+	return 0;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static int gic_irq_domain_xlate(struct irq_domain *d,
Kyle McMartin 0c652ad
+				struct device_node *controller,
Kyle McMartin 0c652ad
+				const u32 *intspec, unsigned int intsize,
Kyle McMartin 0c652ad
+				unsigned long *out_hwirq, unsigned int *out_type)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	if (d->of_node != controller)
Kyle McMartin 0c652ad
+		return -EINVAL;
Kyle McMartin 0c652ad
+	if (intsize < 3)
Kyle McMartin 0c652ad
+		return -EINVAL;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	switch(intspec[0]) {
Kyle McMartin 0c652ad
+	case 0:			/* SPI */
Kyle McMartin 0c652ad
+		*out_hwirq = intspec[1] + 32;
Kyle McMartin 0c652ad
+		break;
Kyle McMartin 0c652ad
+	case 1:			/* PPI */
Kyle McMartin 0c652ad
+		*out_hwirq = intspec[1] + 16;
Kyle McMartin 0c652ad
+		break;
Kyle McMartin 0c652ad
+	default:
Kyle McMartin 0c652ad
+		return -EINVAL;
Kyle McMartin 0c652ad
+	}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	*out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
Kyle McMartin 0c652ad
+	return 0;
Kyle McMartin 0c652ad
+}
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static const struct irq_domain_ops gic_irq_domain_ops = {
Kyle McMartin 0c652ad
+	.map = gic_irq_domain_map,
Kyle McMartin 0c652ad
+	.xlate = gic_irq_domain_xlate,
Kyle McMartin 0c652ad
+};
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+static int __init gic_of_init(struct device_node *node, struct device_node *parent)
Kyle McMartin 0c652ad
+{
Kyle McMartin 0c652ad
+	void __iomem *dist_base;
Kyle McMartin 0c652ad
+	void __iomem **redist_base;
Kyle McMartin 0c652ad
+	u64 redist_stride;
Kyle McMartin 0c652ad
+	u32 redist_regions;
Kyle McMartin 0c652ad
+	u32 reg;
Kyle McMartin 0c652ad
+	int gic_irqs;
Kyle McMartin 0c652ad
+	int err;
Kyle McMartin 0c652ad
+	int i;
Kyle McMartin 0c652ad
+
Kyle McMartin 0c652ad
+	dist_base = of_iomap(node, 0);