[kernel] Re-enable kernel-arm64.patch after updating.

Kyle McMartin kyle at fedoraproject.org
Tue Oct 21 18:13:58 UTC 2014


commit 88b2d0957639b3cb07acd1744ad515af61d2176d
Author: Kyle McMartin <kmcmarti at redhat.com>
Date:   Tue Oct 21 13:05:11 2014 -0400

    Re-enable kernel-arm64.patch after updating.
    
    - CONFIG_SERIAL_8250_FINTEK moved to generic since it appears on x86-generic
      and arm64 now.
    - CONFIG_IMX_THERMAL=n added to config-arm64.

 config-arm64       |    5 +
 config-generic     |    2 +
 config-x86-generic |    2 -
 kernel-arm64.patch |11287 +++++++++++++++++++++++++++++++---------------------
 kernel.spec        |   11 +-
 5 files changed, 6755 insertions(+), 4552 deletions(-)
---
diff --git a/config-arm64 b/config-arm64
index eac2b9a..47174cd 100644
--- a/config-arm64
+++ b/config-arm64
@@ -137,3 +137,8 @@ CONFIG_ACPI_CUSTOM_METHOD=m
 CONFIG_AMD_XGBE=m
 CONFIG_AMD_XGBE_PHY=m
 # CONFIG_AMD_XGBE_DCB is not set
+
+# CONFIG_IMX_THERMAL is not set
+
+# temporary 2014-10-21
+# CONFIG_BPF_JIT is not set
diff --git a/config-generic b/config-generic
index a0b1820..4f7848c 100644
--- a/config-generic
+++ b/config-generic
@@ -5273,3 +5273,5 @@ CONFIG_FMC_CHARDEV=m
 # CONFIG_GLOB_SELFTEST is not set
 
 # CONFIG_SBSAUART_TTY is not set
+
+# CONFIG_SERIAL_8250_FINTEK is not set
diff --git a/config-x86-generic b/config-x86-generic
index 719f3e4..44f2016 100644
--- a/config-x86-generic
+++ b/config-x86-generic
@@ -408,8 +408,6 @@ CONFIG_GPIO_ICH=m
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_TWL6040_CORE is not set
 
-# CONFIG_SERIAL_8250_FINTEK is not set
-
 CONFIG_PCI_CNB20LE_QUIRK=y
 
 CONFIG_ACPI_EC_DEBUGFS=m
diff --git a/kernel-arm64.patch b/kernel-arm64.patch
index a05aa33..0a0941d 100644
--- a/kernel-arm64.patch
+++ b/kernel-arm64.patch
@@ -1,135 +1,62 @@
-commit 87257d3e584fad0b47e6304da54a1932f42b11bb
+commit fb3aa1c1644a73bc36a47a6844c3ee6414787e9e
 Author: Mark Salter <msalter at redhat.com>
-Date:   Tue Sep 30 17:19:24 2014 -0400
-
-    arm64: avoid need for console= to enable serial console
-    
-    Tell kernel to prefer one of the serial ports on platforms
-    pl011, 8250, or sbsa uarts. console= on command line will
-    override these assumed preferences.
-    
-    Signed-off-by: Mark Salter <msalter at redhat.com>
-
-commit 56db24589d311ea3590527030ede007ec339e2d7
-Author: Tom Lendacky <thomas.lendacky at amd.com>
-Date:   Tue Sep 9 23:33:17 2014 -0400
+Date:   Sun Oct 19 11:11:08 2014 -0400
 
-    drivers: net: AMD Seattle XGBE PHY support for A0 silicon
+    clocksource: arm_arch_timer: fix system hang
     
-    This patch modifies the upstream AMD XGBE PHY driver to support
-    A0 Seattle silicon in currently shipping systems. The upstream
-    Linux driver is targetted for Seattle B0 silicon.
+    Arm allows for two possible architectural clock sources. One memory mapped
+    and the other coprocessor based. If both timers exist, then the driver waits
+    for both to be probed before registering a clocksource.
     
-    Signed-off-by: Mark Salter <msalter at redhat.com>
-
-commit 75554bb2e3c433a47e172d81a0b59df58810dc01
-Author: Tom Lendacky <thomas.lendacky at amd.com>
-Date:   Tue Sep 9 23:34:07 2014 -0400
-
-    drivers: net: AMD Seattle XGBE 10GbE support for A0 silicon
+    Commit c387f07e6205 ("clocksource: arm_arch_timer: Discard unavailable timers
+    correctly") attempted to fix a hang occurring when one of the two possible
+    timers had a device node, but was disabled. In that case, the second probe
+    would never occur and the system would hang without a clocksource being
+    registered.
     
-    This patch modifies the upstream AMD 10GbE XGBE Ethernet driver to
-    support A0 Seattle silicon in currently shipping systems. The
-    upstream Linux driver is targetted for Seattle B0 silicon.
+    Unfortunately, incorrect logic in that commit made things worse such that
+    a hang would occur unless both timers had a device node and were enabled.
+    This patch fixes the logic so that we don't wait to probe a second timer
+    unless it exists and is enabled.
     
     Signed-off-by: Mark Salter <msalter at redhat.com>
 
-commit 41cb1b3c9e62256b8a4e92c50cd51b2a68d0c9c6
-Author: Graeme Gregory <graeme.gregory at linaro.org>
-Date:   Fri Jul 26 17:55:02 2013 +0100
-
-    virtio-mmio: add ACPI probing
-    
-    Added the match table and pointers for ACPI probing to the driver.
-    
-    Signed-off-by: Graeme Gregory <graeme.gregory at linaro.org>
-
-commit c06502fb4f00c6996c1f55cd342288508808c678
-Author: Graeme Gregory <graeme.gregory at linaro.org>
-Date:   Wed Jul 24 11:29:48 2013 +0100
+commit 798bcf9c5057f0acd54154d09abf6fc4fc044e41
+Author: Mark Salter <msalter at redhat.com>
+Date:   Tue Oct 14 13:51:54 2014 -0400
 
-    net: smc91x: add ACPI probing support.
+    arm64: [NOT FOR UPSTREAM] fix dma_ops for ACPI and PCI devices
     
-    Add device ID LINA0003 for this device and add the match table.
+    Commit 2189064795dc3fb4101e5:
     
-    As its a platform device it needs no other code and will be probed in by
-    acpi_platform once device ID is added.
+      arm64: Implement set_arch_dma_coherent_ops() to replace bus notifiers
     
-    Signed-off-by: Graeme Gregory <graeme.gregory at linaro.org>
-
-commit aad559613ff05a13f940129675659297e7125979
-Author: Mark Salter <msalter at redhat.com>
-Date:   Tue Sep 23 12:48:48 2014 -0400
-
-    arm64/pci: add coherency inheritance for pci devices
+    removed the bus notifiers from dma-mapping.c. This patch
+    adds the notifier back for ACPI and PCI devices until a
+    better permanent solution is worked out.
     
     Signed-off-by: Mark Salter <msalter at redhat.com>
 
-commit 8d2a4226d96ccae17fbc0ef7d7d9c5a07ad8b31f
+commit 4b7a879d4fe95e935a06bd5209026a2278251ce6
 Author: Mark Salter <msalter at redhat.com>
-Date:   Tue Sep 23 12:35:17 2014 -0400
-
-    arm64/acpi: make acpi disabled by default
-    
-    Signed-off-by: Mark Salter <msalter at redhat.com>
-
-commit 0553f2b9fc94bfb0f9038003ad6f150cca196aad
-Author: Wei Huang <wei at redhat.com>
-Date:   Thu Sep 18 20:32:03 2014 -0400
+Date:   Thu Aug 14 12:32:13 2014 -0400
 
-    KVM: fix VTTBR_BADDR_MASK
-    
-    The following is patch from AMD to fix VTTBR_BADDR_MASK. According to
-    AMD, this patch is required to enable KVM on Seattle.
-    
-      The current VTTBR_BADDR_MASK only masks 39 bits, which is broken on current
-      systems.  Rather than just add a bit it seems like a good time to also set
-      things at run-time instead of compile time to accomodate more hardware.
-    
-      This patch sets TCR_EL2.PS, VTCR_EL2.T0SZ and vttbr_baddr_mask in runtime,
-      not compile time.
-    
-      In ARMv8, EL2 physical address size (TCR_EL2.PS) and stage2 input address
-      size (VTCR_EL2.T0SZE) cannot be determined in compile time since they
-      depend on hardware capability.
-    
-      According to Table D4-23 and Table D4-25 in ARM DDI 0487A.b document,
-      vttbr_x is calculated using different fixed values with consideration
-      of T0SZ, granule size and the level of translation tables. Therefore,
-      vttbr_baddr_mask should be determined dynamically.
-    
-      Changes since v5:
-      Fixed declaration of vttbr_baddr_mask to not create multiple instances
-      Refactored return codes based on feedback
-      For 32 bit included kvm_arm.h in kvm_mmu.h to explictly pick up
-      VTTBR_BADDR_MASK
-    
-      Changes since v4:
-      More minor cleanups from review
-      Moved some functions into headers
-      Added runtime check in kvm_alloc_stage2_pgd
-    
-      Changes since v3:
-      Another rebase
-      Addressed minor comments from v2
-    
-      Changes since v2:
-      Rebased on https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git next branch
+    acpi: add utility to test for device dma coherency
     
-      Changes since v1:
-      Rebased fix on Jungseok Lee's patch https://lkml.org/lkml/2014/5/12/189 to
-      provide better long term fix.  Updated that patch to log error instead of
-      silently fail on unaligned vttbr.
+    ACPI 5.1 adds a _CCA object to indicate memory coherency
+    of a bus master device. It is an integer with zero meaning
+    non-coherent and one meaning coherent. This attribute may
+    be inherited from a parent device. It may also be missing
+    entirely, in which case, an architecture-specific default
+    is assumed.
     
-      Cc: Marc Zyngier <marc.zyngier at arm.com>
-      Cc: Christoffer Dall <christoffer.dall at linaro.org>
-      Cc: Sungjinn Chung <sungjinn.chung at samsung.com>
-      Signed-off-by: Jungseok Lee <jays.lee at samsung.com>
-      Signed-off-by: Joel Schopp <joel.schopp at amd.com>
+    This patch adds a utility function to parse a device handle
+    (and its parents) for a _CCA object and return the coherency
+    attribute if found.
     
-    Signed-off-by: Wei Huang <wei at redhat.com>
+    Signed-off-by: Mark Salter <msalter at redhat.com>
 
-commit f53d1278fe445b7130f1ff76b2f453b453368284
+commit 0e83bbc67aa2ced7b0f62bc9cdbf8026f3a83ea7
 Author: Wei Huang <wei at redhat.com>
 Date:   Thu Sep 18 20:02:57 2014 -0400
 
@@ -146,7 +73,7 @@ Date:   Thu Sep 18 20:02:57 2014 -0400
     
     Signed-off-by: Wei Huang <wei at redhat.com>
 
-commit ba63e452ff5b09cc0314f94e163a51c3279b9ca7
+commit b01e346d3156935d05aada065b69dbd4e8e3c38e
 Author: Wei Huang <wei at redhat.com>
 Date:   Thu Sep 18 20:02:56 2014 -0400
 
@@ -159,7 +86,7 @@ Date:   Thu Sep 18 20:02:56 2014 -0400
     
     Signed-off-by: Wei Huang <wei at redhat.com>
 
-commit dd3f6094c2142786f40a3bc4d69c60b430ecc675
+commit 1f7fbdb23b3f616344bc6ab42d133528508b4183
 Author: Wei Huang <wei at redhat.com>
 Date:   Thu Sep 18 20:02:55 2014 -0400
 
@@ -176,143 +103,472 @@ Date:   Thu Sep 18 20:02:55 2014 -0400
     
     Signed-off-by: Wei Huang <wei at redhat.com>
 
-commit cdfc19f1fbe88c1610db790ad55318d55ab00ee9
-Author: Mark Salter <msalter at redhat.com>
-Date:   Thu Sep 18 21:13:05 2014 -0400
+commit f1e1479c450a58b7fc68fec33c39b050dcc4b13d
+Author: Al Stone <ahs3 at redhat.com>
+Date:   Thu Sep 18 15:46:38 2014 -0600
 
-    arm64/pci: fix dma coherency inheritance for PCI devices
+    DO NOT UPSTREAM -- patch to work around bad MAC of 0x0
     
-    The default dma_ops for devices on arm64 systems are noncoherent in
-    nature and rely upon special operations and bounce buffers to
-    perform a device DMA operation to/from memory. Some drivers rely
-    upon coherent operations involving suitably capable hardware. In
-    this case, a "dma-coherent" property will exist on the corresponding
-    Device Tree node for the bridge device, or one of its ancestors.
-    This patch adds support for applying a DMA coherent dma_ops for
-    PCI devices in the case of such a property.
+    Signed-off-by: Al Stone <ahs3 at redhat.com>
+
+commit b97981d8eaeef88d34b68d6bf6fae3088fce76f6
+Author: Tom Lendacky <thomas.lendacky at amd.com>
+Date:   Mon Sep 15 17:02:52 2014 -0600
+
+    amd-xgbe: AMD 10GbE driver APCI support for A0
     
-    Signed-off-by: Mark Salter <msalter at redhat.com>
+    This patch provides ACPI support for the AMD 10GbE device driver
+    and AMD 10GbE phy driver.
+    
+    Signed-off-by: Tom Lendacky <thomas.lendacky at amd.com>
 
-commit c8a62324eba5718fb43a94a168de7a81787aa94d
+commit dd2c9edb72ff2e36152bae3bdf4f849b155c6178
 Author: Mark Salter <msalter at redhat.com>
-Date:   Thu Sep 18 15:05:23 2014 -0400
+Date:   Tue Oct 7 12:54:08 2014 -0400
 
-    arm64: add sev to parking protocol
+    xgene acpi network - first cut
+
+commit 34f6f9c9a449fce5038a79ef74d85c0cd8aa983d
+Author: Mika Westerberg <mika.westerberg at linux.intel.com>
+Date:   Wed Oct 1 04:22:27 2014 +0200
+
+    misc: at25: Add ACPI probing support
     
-    Parking protocol wakes secondary cores with an interrupt.
-    This patch adds an additional sev() to send an event. This
-    is a temporary hack for APM Mustang board and not intended
-    for upstream.
+    Add support for matching using DT compatible string from ACPI _DSD.
     
-    Signed-off-by: Mark Salter <msalter at redhat.com>
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
 
-commit e5f4ba1223515c46f1875597e77d5c32a37829ee
-Author: Mark Salter <msalter at redhat.com>
-Date:   Sun Sep 14 09:44:44 2014 -0400
+commit a17b2b5016d76e752f706b5f6b04ffae8ec1728e
+Author: Mika Westerberg <mika.westerberg at linux.intel.com>
+Date:   Wed Oct 1 04:21:18 2014 +0200
 
-    Revert "ahci_xgene: Skip the PHY and clock initialization if already configured by the firmware."
+    misc: at25: Make use of device property API
     
-    This reverts commit 0bed13bebd6c99d097796d2ca6c4f10fb5b2eabc.
+    Make use of device property API in this driver so that both DT and ACPI
+    based systems can use this driver.
     
-    Temporarily revert for backwards compatibility with rh-0.12-1 firmware
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
 
-commit aeff595a5d57264e5f01add5c43f584d88be6a92
-Author: Mark Salter <msalter at redhat.com>
-Date:   Mon Aug 11 13:46:43 2014 -0400
+commit 66442ae93d72f35bf046a6001403fdb89fbcfbdf
+Author: Mika Westerberg <mika.westerberg at linux.intel.com>
+Date:   Wed Oct 1 04:20:43 2014 +0200
 
-    xgene: add support for ACPI-probed serial port
+    input: gpio_keys_polled - Add ACPI probing support
+    
+    Allow the driver to probe from ACPI namespace.
+    
+    Signed-off-by: Aaron Lu <aaron.lu at intel.com>
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+
+commit 7f06c354929e2325f200de26e47189a13100647e
+Author: Aaron Lu <aaron.lu at intel.com>
+Date:   Wed Oct 1 04:20:05 2014 +0200
+
+    input: gpio_keys_polled - Make use of device property API
+    
+    Make use of device property API in this driver so that both OF based
+    system and ACPI based system can use this driver.
+    
+    Signed-off-by: Aaron Lu <aaron.lu at intel.com>
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+
+commit 1fb6d8d9606826cf1dfdac8a75bc5e3f68e4d0de
+Author: Aaron Lu <aaron.lu at intel.com>
+Date:   Wed Oct 1 04:17:46 2014 +0200
+
+    input: gpio_keys_polled - Add support for GPIO descriptors
+    
+    GPIO descriptors are the preferred way over legacy GPIO numbers
+    nowadays. Convert the driver to use GPIO descriptors internally but
+    still allow passing legacy GPIO numbers from platform data to support
+    existing platforms.
+    
+    Signed-off-by: Aaron Lu <aaron.lu at intel.com>
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Acked-by: Alexandre Courbot <acourbot at nvidia.com>
+    Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+
+commit 8cd8efd79a3f822db3ffc2f30f7646584b69d99f
+Author: Max Eliaser <max at meliaserlow.dyndns.tv>
+Date:   Wed Oct 1 04:17:02 2014 +0200
+
+    leds: leds-gpio: Add ACPI probing support
+    
+    This allows the driver to probe from ACPI namespace.
+    
+    Signed-off-by: Max Eliaser <max.eliaser at intel.com>
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Acked-by: Bryan Wu <cooloney at gmail.com>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+
+commit 14144259abecb65edd35b9d5e717688800628e27
+Author: Max Eliaser <max at meliaserlow.dyndns.tv>
+Date:   Wed Oct 1 04:16:25 2014 +0200
+
+    leds: leds-gpio: Make use of device property API
+    
+    Make use of device property API in this driver so that both OF and ACPI
+    based system can use the same driver.
+    
+    Signed-off-by: Max Eliaser <max.eliaser at intel.com>
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+
+commit 998f66211496063e464918fcdb4e40e99fcf2501
+Author: Mika Westerberg <mika.westerberg at linux.intel.com>
+Date:   Wed Oct 1 04:15:41 2014 +0200
+
+    leds: leds-gpio: Add support for GPIO descriptors
+    
+    GPIO descriptors are the preferred way over legacy GPIO numbers
+    nowadays. Convert the driver to use GPIO descriptors internally but
+    still allow passing legacy GPIO numbers from platform data to support
+    existing platforms.
+    
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Acked-by: Alexandre Courbot <acourbot at nvidia.com>
+    Acked-by: Bryan Wu <cooloney at gmail.com>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+
+commit ecf8d19a6019f60c567615c46bec6f4501c03c99
+Author: Mika Westerberg <mika.westerberg at linux.intel.com>
+Date:   Wed Oct 1 04:15:01 2014 +0200
+
+    gpio: sch: Consolidate core and resume banks
+    
+    This is actually a single device with two sets of identical registers,
+    which just happen to start from a different offset. Instead of having
+    separate GPIO chips created we consolidate them to be single GPIO chip.
+    
+    In addition having a single GPIO chip allows us to handle ACPI GPIO
+    translation in the core in a more generic way, since the two GPIO chips
+    share the same parent ACPI device.
+    
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Acked-by: Linus Walleij <linus.walleij at linaro.org>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+
+commit f87218916f4a9bcd2acdf8db1a4dbf8db5592036
+Author: Mika Westerberg <mika.westerberg at linux.intel.com>
+Date:   Wed Oct 1 04:14:20 2014 +0200
+
+    gpio: Support for unified device properties interface
+    
+    Some drivers need to deal with only firmware representation of its
+    GPIOs. An example would be a GPIO button array driver where each button
+    is described as a separate firmware node in device tree. Typically these
+    child nodes do not have physical representation in the Linux device
+    model.
+    
+    In order to help device drivers to handle such firmware child nodes we
+    add dev[m]_get_named_gpiod_from_child() that takes a child firmware
+    node pointer as its second argument (the first one is the parent device
+    itself), finds the GPIO using whatever is the underlying firmware
+    method, and requests the GPIO properly.
+    
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+
+commit 2edae8da3e10c8b9d679637693e9d26a0cb9440f
+Author: Mika Westerberg <mika.westerberg at linux.intel.com>
+Date:   Wed Oct 1 04:12:41 2014 +0200
 
-commit 02429d239f5ae917d870a7611a9d838b7822df1a
+    gpio / ACPI: Add support for _DSD device properties
+    
+    With release of ACPI 5.1 and _DSD method we can finally name GPIOs (and
+    other things as well) returned by _CRS. Previously we were only able to
+    use integer index to find the corresponding GPIO, which is pretty error
+    prone if the order changes.
+    
+    With _DSD we can now query GPIOs using name instead of an integer index,
+    like the below example shows:
+    
+      // Bluetooth device with reset and shutdown GPIOs
+      Device (BTH)
+      {
+          Name (_HID, ...)
+    
+          Name (_CRS, ResourceTemplate ()
+          {
+              GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+                      "\\_SB.GPO0", 0, ResourceConsumer) {15}
+              GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
+                      "\\_SB.GPO0", 0, ResourceConsumer) {27, 31}
+          })
+    
+          Name (_DSD, Package ()
+          {
+              ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+              Package ()
+    	  {
+                  Package () {"reset-gpio", Package() {^BTH, 1, 1, 0 }},
+                  Package () {"shutdown-gpio", Package() {^BTH, 0, 0, 0 }},
+              }
+          })
+      }
+    
+    The format of the supported GPIO property is:
+    
+      Package () { "name", Package () { ref, index, pin, active_low }}
+    
+      ref - The device that has _CRS containing GpioIo()/GpioInt() resources,
+            typically this is the device itself (BTH in our case).
+      index - Index of the GpioIo()/GpioInt() resource in _CRS starting from zero.
+      pin - Pin in the GpioIo()/GpioInt() resource. Typically this is zero.
+      active_low - If 1 the GPIO is marked as active_low.
+    
+    Since ACPI GpioIo() resource does not have field saying whether it is
+    active low or high, the "active_low" argument can be used here. Setting
+    it to 1 marks the GPIO as active low.
+    
+    In our Bluetooth example the "reset-gpio" refers to the second GpioIo()
+    resource, second pin in that resource with the GPIO number of 31.
+    
+    This patch implements necessary support to gpiolib for extracting GPIOs
+    using _DSD device properties.
+    
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Acked-by: Linus Walleij <linus.walleij at linaro.org>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+
+commit 01164a93badc2df11a1f1bfdf7d46e3253a0a6ec
+Author: Mika Westerberg <mika.westerberg at linux.intel.com>
+Date:   Wed Oct 1 04:11:20 2014 +0200
+
+    ACPI: Document ACPI device specific properties
+    
+    This document describes the data format and interfaces of ACPI device
+    specific properties.
+    
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Signed-off-by: Darren Hart <dvhart at linux.intel.com>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+
+commit 1ea48df9784142befa0cdb6cb79f7fd405a7a103
+Author: Mika Westerberg <mika.westerberg at linux.intel.com>
+Date:   Wed Oct 1 04:10:40 2014 +0200
+
+    ACPI: Allow drivers to match using Device Tree compatible property
+    
+    We have lots of existing Device Tree enabled drivers and allocating
+    separate _HID for each is not feasible. Instead we allocate special _HID
+    "PRP0001" that means that the match should be done using Device Tree
+    compatible property using driver's .of_match_table instead.
+    
+    If there is a need to distinguish from where the device is enumerated
+    (DT/ACPI) driver can check dev->of_node or ACPI_COMPATION(dev).
+    
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+
+commit f15380516841e837f8e20ed18c0039e052bb6187
+Author: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+Date:   Wed Oct 1 04:10:03 2014 +0200
+
+    Driver core: Unified device properties interface for platform firmware
+    
+    Add a uniform interface by which device drivers can request device
+    properties from the platform firmware by providing a property name
+    and the corresponding data type.  The purpose of it is to help to
+    write portable code that won't depend on any particular platform
+    firmware interface.
+    
+    Three general helper functions, device_get_property(),
+    device_read_property() and device_read_property_array() are provided.
+    The first one allows the raw value of a given device property to be
+    accessed.  The remaining two allow the value of a numeric or string
+    property and multiple numeric or string values of one array
+    property to be acquired, respectively.  Static inline wrappers are also
+    provided for the various property data types that can be passed to
+    device_read_property() or device_read_property_array() for extra type
+    checking.
+    
+    In addition to that, new generic routines are provided for retrieving
+    properties from device description objects in the platform firmware
+    in case a device driver needs/wants to access properties of a child
+    object of a given device object.  There are cases in which there is
+    no struct device representation of such child objects and this
+    additional API is useful then.  Again, three functions are provided,
+    device_get_child_property(), device_read_child_property(),
+    device_read_child_property_array(), in analogy with device_get_property(),
+    device_read_property() and device_read_property_array() described above,
+    respectively, along with static inline wrappers for all of the propery
+    data types that can be used.  For all of them, the first argument is
+    a struct device pointer to the parent device object and the second
+    argument is a (void *) pointer to the child description provided by
+    the platform firmware (either ACPI or FDT).
+    
+    Finally, device_for_each_child_node() is added for iterating over
+    the children of the device description object associated with a
+    given device.
+    
+    The interface covers both ACPI and Device Trees.
+    
+    This change set includes material from Mika Westerberg and Aaron Lu.
+    
+    Signed-off-by: Aaron Lu <aaron.lu at intel.com>
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+
+commit 6b0beaa05b29a299e62293fa4ea4dad0053f31b1
+Author: Mika Westerberg <mika.westerberg at linux.intel.com>
+Date:   Wed Oct 1 04:08:56 2014 +0200
+
+    ACPI: Add support for device specific properties
+    
+    Device Tree is used in many embedded systems to describe the system
+    configuration to the OS. It supports attaching properties or name-value
+    pairs to the devices it describe. With these properties one can pass
+    additional information to the drivers that would not be available
+    otherwise.
+    
+    ACPI is another configuration mechanism (among other things) typically
+    seen, but not limited to, x86 machines. ACPI allows passing arbitrary
+    data from methods but there has not been mechanism equivalent to Device
+    Tree until the introduction of _DSD in the recent publication of the
+    ACPI 5.1 specification.
+    
+    In order to facilitate ACPI usage in systems where Device Tree is
+    typically used, it would be beneficial to standardize a way to retrieve
+    Device Tree style properties from ACPI devices, which is what we do in
+    this patch.
+    
+    If a given device described in ACPI namespace wants to export properties it
+    must implement _DSD method (Device Specific Data, introduced with ACPI 5.1)
+    that returns the properties in a package of packages. For example:
+    
+    	Name (_DSD, Package () {
+    		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    		Package () {
+    			Package () {"name1", <VALUE1>},
+    			Package () {"name2", <VALUE2>},
+    			...
+    		}
+    	})
+    
+    The UUID reserved for properties is daffd814-6eba-4d8c-8a91-bc9bbf4aa301
+    and is documented in the ACPI 5.1 companion document called "_DSD
+    Implementation Guide" [1], [2].
+    
+    We add several helper functions that can be used to extract these
+    properties and convert them to different Linux data types.
+    
+    The ultimate goal is that we only have one device property API that
+    retrieves the requested properties from Device Tree or from ACPI
+    transparent to the caller.
+    
+    [1] http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
+    [2] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
+    
+    Reviewed-by: Hanjun Guo <hanjun.guo at linaro.org>
+    Reviewed-by: Josh Triplett <josh at joshtriplett.org>
+    Signed-off-by: Darren Hart <dvhart at linux.intel.com>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+    Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
+    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+
+commit ca68950ecf22403e9d0cacdcd86fb4c245de6b9f
 Author: Mark Salter <msalter at redhat.com>
-Date:   Sat Aug 9 12:01:20 2014 -0400
+Date:   Tue Sep 30 17:19:24 2014 -0400
 
-    sata/xgene: support acpi probing
+    arm64: avoid need for console= to enable serial console
+    
+    Tell kernel to prefer one of the serial ports on platforms
+    pl011, 8250, or sbsa uarts. console= on command line will
+    override these assumed preferences.
     
     Signed-off-by: Mark Salter <msalter at redhat.com>
 
-commit 774385f250ebb7448ca3eeb344a064ac989c4988
-Author: Hanjun Guo <hanjun.guo at linaro.org>
-Date:   Thu Aug 28 14:26:16 2014 -0400
+commit 6194557254f1ed05638237a64f45f2ec08aa2523
+Author: Tom Lendacky <thomas.lendacky at amd.com>
+Date:   Tue Sep 9 23:33:17 2014 -0400
 
-    ARM64 / ACPI: Introduce some PCI functions when PCI is enabled
+    drivers: net: AMD Seattle XGBE PHY support for A0 silicon
     
-    Introduce some PCI functions to make ACPI can be compiled when
-    CONFIG_PCI is enabled, these functions should be revisited when
-    implemented on ARM64.
+    This patch modifies the upstream AMD XGBE PHY driver to support
+    A0 Seattle silicon in currently shipping systems. The upstream
+    Linux driver is targetted for Seattle B0 silicon.
     
-    Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
-    [fixed up for 3.17-rc]
     Signed-off-by: Mark Salter <msalter at redhat.com>
 
-commit 6f711c98b37f1b0a42c4a523d0380d47ed2f95b9
-Author: Al Stone <ahs3 at redhat.com>
-Date:   Thu Aug 28 13:14:16 2014 -0400
+commit 0c9b242dd24b3ddf2e87209cb07c4bc7f5da21c4
+Author: Tom Lendacky <thomas.lendacky at amd.com>
+Date:   Tue Sep 9 23:34:07 2014 -0400
 
-    Fix arm64 compilation error in PNP code
+    drivers: net: AMD Seattle XGBE 10GbE support for A0 silicon
+    
+    This patch modifies the upstream AMD 10GbE XGBE Ethernet driver to
+    support A0 Seattle silicon in currently shipping systems. The
+    upstream Linux driver is targetted for Seattle B0 silicon.
     
     Signed-off-by: Mark Salter <msalter at redhat.com>
 
-commit f874873b7cb10f827bb7f8e08fa282878f740e77
-Author: Bob Moore <robert.moore at intel.com>
-Date:   Tue Sep 2 08:27:40 2014 +0800
+commit 7697f77962035de040c847f4c331eb91dc1c7c91
+Author: Graeme Gregory <graeme.gregory at linaro.org>
+Date:   Fri Jul 26 17:55:02 2013 +0100
 
-    ACPICA: Update version to 20140828.
+    virtio-mmio: add ACPI probing
     
-    Version 20140828.
+    Added the match table and pointers for ACPI probing to the driver.
     
-    Signed-off-by: Bob Moore <robert.moore at intel.com>
-    Signed-off-by: Lv Zheng <lv.zheng at intel.com>
+    Signed-off-by: Graeme Gregory <graeme.gregory at linaro.org>
 
-commit 26f9b7b90576cf808a50edf1ec86ceece9349c9f
-Author: Bob Moore <robert.moore at intel.com>
-Date:   Tue Sep 2 08:27:27 2014 +0800
+commit 3025ec9f5711f2773be702464bf3150aa914bd66
+Author: Graeme Gregory <graeme.gregory at linaro.org>
+Date:   Wed Jul 24 11:29:48 2013 +0100
 
-    ACPICA: Disassembler: Fix for gpio_int interrupt polarity flags.
+    net: smc91x: add ACPI probing support.
+    
+    Add device ID LINA0003 for this device and add the match table.
     
-    The field is actually 2 bits, not 1.
+    As its a platform device it needs no other code and will be probed in by
+    acpi_platform once device ID is added.
     
-    Signed-off-by: Bob Moore <robert.moore at intel.com>
-    Signed-off-by: Lv Zheng <lv.zheng at intel.com>
+    Signed-off-by: Graeme Gregory <graeme.gregory at linaro.org>
 
-commit 6e1eddc48f6f9b948be4126dd38841f6f70da080
-Author: Hanjun Guo <hanjun.guo at linaro.org>
-Date:   Tue Sep 2 08:27:19 2014 +0800
+commit a41a9bd6569e079f0572d4b106ffa95d2c16ad06
+Author: Mark Salter <msalter at redhat.com>
+Date:   Thu Sep 18 15:05:23 2014 -0400
 
-    ACPICA: Headers: Add GTDT flag definitions for the timer subtable.
+    arm64: add sev to parking protocol
     
-    Mostly by Hanjun Guo <hanjun.guo at linaro.org>
+    Parking protocol wakes secondary cores with an interrupt.
+    This patch adds an additional sev() to send an event. This
+    is a temporary hack for APM Mustang board and not intended
+    for upstream.
     
-    Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
-    Signed-off-by: Bob Moore <robert.moore at intel.com>
-    Signed-off-by: Lv Zheng <lv.zheng at intel.com>
+    Signed-off-by: Mark Salter <msalter at redhat.com>
 
-commit 1091460efb5542ba87f40ef20daff44215587f26
-Author: Hanjun Guo <hanjun.guo at linaro.org>
-Date:   Tue Sep 2 08:27:12 2014 +0800
+commit 6e86c887dd05557830a38aa8fd93fab03a409b69
+Author: Mark Salter <msalter at redhat.com>
+Date:   Sun Sep 14 09:44:44 2014 -0400
 
-    ACPICA: ACPI 5.1/Disassembler: Add GICC affinity subtable to SRAT table.
-    
-    Update template for SRAT.
-    Add clock_domain to standard CPU affinity subtable.
+    Revert "ahci_xgene: Skip the PHY and clock initialization if already configured by the firmware."
     
-    Mostly by Hanjun Guo <hanjun.guo at linaro.org>
+    This reverts commit 0bed13bebd6c99d097796d2ca6c4f10fb5b2eabc.
     
-    Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
-    Signed-off-by: Bob Moore <robert.moore at intel.com>
-    Signed-off-by: Lv Zheng <lv.zheng at intel.com>
+    Temporarily revert for backwards compatibility with rh-0.12-1 firmware
 
-commit 02ba5e067dbb83b0f481db821d05851e9623c401
-Author: Bob Moore <robert.moore at intel.com>
-Date:   Tue Sep 2 08:27:05 2014 +0800
+commit 81bcad4ccaf54357a6e3d51a135e07a67ce122ee
+Author: Mark Salter <msalter at redhat.com>
+Date:   Mon Aug 11 13:46:43 2014 -0400
 
-    ACPICA: Add _PSx names to the METHOD_NAME list.
-    
-    Will be used by iASL.
+    xgene: add support for ACPI-probed serial port
+
+commit d99f65d46bcc6a28262ff18506b0f2abd10d789e
+Author: Mark Salter <msalter at redhat.com>
+Date:   Sat Aug 9 12:01:20 2014 -0400
+
+    sata/xgene: support acpi probing
     
-    Signed-off-by: Bob Moore <robert.moore at intel.com>
-    Signed-off-by: Lv Zheng <lv.zheng at intel.com>
+    Signed-off-by: Mark Salter <msalter at redhat.com>
 
-commit f2ecef6608a1f74b236df4f93da9b7b5aba4d3fd
+commit 977b4da81b8b80d02f54f2fc799fb292b22ade12
 Author: Mark Salter <msalter at redhat.com>
 Date:   Tue Sep 9 22:59:48 2014 -0400
 
@@ -328,7 +584,37 @@ Date:   Tue Sep 9 22:59:48 2014 -0400
     
     Signed-off-by: Mark Salter <msalter at redhat.com>
 
-commit 63e220c94f072f10bfae2e1ed375af9dbc017571
+commit b0be9a425fd397fbed0b720a310e82d5d422f0da
+Author: Mark Salter <msalter at redhat.com>
+Date:   Tue Sep 23 12:35:17 2014 -0400
+
+    arm64/acpi: make acpi disabled by default
+    
+    Signed-off-by: Mark Salter <msalter at redhat.com>
+
+commit 2dd589faf326c07b981093f73a9c7448ddf4afbf
+Author: Hanjun Guo <hanjun.guo at linaro.org>
+Date:   Thu Aug 28 14:26:16 2014 -0400
+
+    ARM64 / ACPI: Introduce some PCI functions when PCI is enabled
+    
+    Introduce some PCI functions to make ACPI can be compiled when
+    CONFIG_PCI is enabled, these functions should be revisited when
+    implemented on ARM64.
+    
+    Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
+    [fixed up for 3.17-rc]
+    Signed-off-by: Mark Salter <msalter at redhat.com>
+
+commit 1857c8d68b23fb57f6f6c64d09e3ce183244d399
+Author: Al Stone <ahs3 at redhat.com>
+Date:   Thu Aug 28 13:14:16 2014 -0400
+
+    Fix arm64 compilation error in PNP code
+    
+    Signed-off-by: Mark Salter <msalter at redhat.com>
+
+commit 4529b4dbbaa8732c742300f3abe8db83e08670e8
 Author: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
 Date:   Tue Sep 9 15:37:15 2014 -0500
 
@@ -354,7 +640,7 @@ Date:   Tue Sep 9 15:37:15 2014 -0500
     
     Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
 
-commit d9d7224bd65fb3c1490f06d635b7aceb035acb1e
+commit 2bf2a4a102bbe2abf7b2306e89d4d59fb7ade8d2
 Author: Graeme Gregory <graeme.gregory at linaro.org>
 Date:   Wed Aug 13 13:47:18 2014 +0100
 
@@ -369,41 +655,11 @@ Date:   Wed Aug 13 13:47:18 2014 +0100
     
     Signed-off-by: Graeme Gregory <graeme.gregory at linaro.org>
 
-commit 4c67296fce53fed671a78b698d4552636f499b7f
+commit 5c62121c6de8268b06d563596953ce71d292733a
 Author: Mark Salter <msalter at redhat.com>
-Date:   Thu Aug 14 13:17:37 2014 -0400
+Date:   Mon Sep 8 11:58:46 2014 -0400
 
-    arm64: set dma coherency ops for ACPI probed devices
-    
-    Search for a _CCA object and set the correct dma ops based
-    on device coherency attribute and architecture default.
-    
-    Signed-off-by: Mark Salter <msalter at redhat.com>
-
-commit 959c571815c440150b2f290bf3d13b2fbadbee70
-Author: Mark Salter <msalter at redhat.com>
-Date:   Thu Aug 14 12:32:13 2014 -0400
-
-    acpi: add utility to test for device dma coherency
-    
-    ACPI 5.1 adds a _CCA object to indicate memory coherency
-    of a bus master device. It is an integer with zero meaning
-    non-coherent and one meaning coherent. This attribute may
-    be inherited from a parent device. It may also be missing
-    entirely, in which case, an architecture-specific default
-    is assumed.
-    
-    This patch adds a utility function to parse a device handle
-    (and its parents) for a _CCA object and return the coherency
-    attribute if found.
-    
-    Signed-off-by: Mark Salter <msalter at redhat.com>
-
-commit 0dbac48379d3aace2fd7468d83044116f176b4c9
-Author: Mark Salter <msalter at redhat.com>
-Date:   Mon Sep 8 11:58:46 2014 -0400
-
-    acpi: fix acpi_os_ioremap for arm64
+    acpi: fix acpi_os_ioremap for arm64
     
     The acpi_os_ioremap() function may be used to map normal RAM or IO
     regions. The current implementation simply uses ioremap_cache(). This
@@ -413,7 +669,7 @@ Date:   Mon Sep 8 11:58:46 2014 -0400
     
     Signed-off-by: Mark Salter <msalter at redhat.com>
 
-commit c9eab819c2107e0c95cf57233de4de5404851ab6
+commit c4f70201c3e20f95c1a96929cf8e524a82dddf81
 Author: Graeme Gregory <graeme.gregory at linaro.org>
 Date:   Mon Sep 8 10:36:44 2014 -0400
 
@@ -425,7 +681,7 @@ Date:   Mon Sep 8 10:36:44 2014 -0400
     Signed-off-by: Al Stone <al.stone at linaro.org>
     Signed-off-by: Graeme Gregory <graeme.gregory at linaro.org>
 
-commit 7e772a485f980b826a58ecd9c39fbe82085c55fa
+commit e632bb50e732757dd8ac56f94785b86c300585ba
 Author: Mark Salter <msalter at redhat.com>
 Date:   Mon Sep 8 17:04:28 2014 -0400
 
@@ -437,7 +693,7 @@ Date:   Mon Sep 8 17:04:28 2014 -0400
     
     Signed-off-by: Mark Salter <msalter at redhat.com>
 
-commit b42e8f7901e58b86a1cb3ffdf14cb2455fd91ede
+commit 51ba60203fe3cb844f1b56389dc840ecf0264817
 Author: Graeme Gregory <graeme.gregory at linaro.org>
 Date:   Fri Sep 12 22:00:16 2014 +0800
 
@@ -449,7 +705,7 @@ Date:   Fri Sep 12 22:00:16 2014 +0800
     Signed-off-by: Graeme Gregory <graeme.gregory at linaro.org>
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit 57dc75b87d5663181e1c19802297e72e51a324ba
+commit 49c2936aebfdc0d6fb6f8a2ed85295e4370afac7
 Author: Graeme Gregory <graeme.gregory at linaro.org>
 Date:   Fri Sep 12 22:00:15 2014 +0800
 
@@ -465,7 +721,7 @@ Date:   Fri Sep 12 22:00:15 2014 +0800
     Signed-off-by: Al Stone <al.stone at linaro.org>
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit 106c5cb3caff13c91cb6056f88a1c0e710b8e0eb
+commit 4a1bcc17290231af1cfbef33aa6ec77aca609389
 Author: Al Stone <al.stone at linaro.org>
 Date:   Fri Sep 12 22:00:14 2014 +0800
 
@@ -479,7 +735,7 @@ Date:   Fri Sep 12 22:00:14 2014 +0800
     Signed-off-by: Al Stone <al.stone at linaro.org>
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit 73f4aca21985ace8989b6fc8af503940c469f1d7
+commit 2863c8dd559eaa85dbec982045ae8201bdd0216e
 Author: Hanjun Guo <hanjun.guo at linaro.org>
 Date:   Fri Sep 12 22:00:13 2014 +0800
 
@@ -491,7 +747,7 @@ Date:   Fri Sep 12 22:00:13 2014 +0800
     Originally-by: Amit Daniel Kachhap <amit.daniel at samsung.com>
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit 5efba15fb24c25139dd621a417f2b9cbe2e675f5
+commit 75398d7dfd0a9bb67c70568bbc49e79d43681516
 Author: Tomasz Nowicki <tomasz.nowicki at linaro.org>
 Date:   Fri Sep 12 22:00:12 2014 +0800
 
@@ -509,7 +765,7 @@ Date:   Fri Sep 12 22:00:12 2014 +0800
     Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit e060d9d74cecff59ea96d6124ffb1c9c044a4f9d
+commit 325e4412a370d58213bd1cd9de5a5f104dd2bab4
 Author: Hanjun Guo <hanjun.guo at linaro.org>
 Date:   Fri Sep 12 22:00:11 2014 +0800
 
@@ -525,7 +781,7 @@ Date:   Fri Sep 12 22:00:11 2014 +0800
     Originally-by: Amit Daniel Kachhap <amit.daniel at samsung.com>
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit c25e8f66c630713107967076933b5f349655ea6a
+commit 4537275d3b1611bb1102eadfce56af2d36d1c25b
 Author: Hanjun Guo <hanjun.guo at linaro.org>
 Date:   Fri Sep 12 22:00:10 2014 +0800
 
@@ -539,7 +795,7 @@ Date:   Fri Sep 12 22:00:10 2014 +0800
     
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit 5ce1c3ff91aa9d8012324518789363bb4ded33d4
+commit 5ae8a2bbb06f1833c6494fc7a5f30931cc4b5d9a
 Author: Hanjun Guo <hanjun.guo at linaro.org>
 Date:   Fri Sep 12 22:00:09 2014 +0800
 
@@ -558,7 +814,7 @@ Date:   Fri Sep 12 22:00:09 2014 +0800
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
     Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
 
-commit 8634cf0fcc8294c355d7cecb55da017ba9ff3ff7
+commit 4a3aed9caf1780e72030a7efc32d28a32d3ed603
 Author: Hanjun Guo <hanjun.guo at linaro.org>
 Date:   Fri Sep 12 22:00:08 2014 +0800
 
@@ -570,7 +826,7 @@ Date:   Fri Sep 12 22:00:08 2014 +0800
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
     Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
 
-commit 05facef9c824235c82d8d9c2ae03fe7a729ceef8
+commit d9f88c9f5385ac2ae7c87ca0ee63e8e77a37ca09
 Author: Hanjun Guo <hanjun.guo at linaro.org>
 Date:   Fri Sep 12 22:00:07 2014 +0800
 
@@ -599,7 +855,7 @@ Date:   Fri Sep 12 22:00:07 2014 +0800
     Signed-off-by: Graeme Gregory <graeme.gregory at linaro.org>
     Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
 
-commit a13a8c748b6170a8a3f4876163ff74e460bd889f
+commit f5b32d09a98c2d5353915d2bcc3d7fa3151b6890
 Author: Hanjun Guo <hanjun.guo at linaro.org>
 Date:   Fri Sep 12 22:00:06 2014 +0800
 
@@ -614,7 +870,7 @@ Date:   Fri Sep 12 22:00:06 2014 +0800
     
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit a6bf98355490142fc3f6e9c0839af128e326f16d
+commit 445abae9b9e86d9bd81b3cbffc5d20e8cb375ab0
 Author: Graeme Gregory <graeme.gregory at linaro.org>
 Date:   Fri Sep 12 22:00:05 2014 +0800
 
@@ -627,7 +883,7 @@ Date:   Fri Sep 12 22:00:05 2014 +0800
     Signed-off-by: Graeme Gregory <graeme.gregory at linaro.org>
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit e3b9886532d1e13ddb68e4955ad776a8623f9766
+commit fad554282770ff7d0a0b002bb2c3d289ad5cc187
 Author: Al Stone <al.stone at linaro.org>
 Date:   Fri Sep 12 22:00:04 2014 +0800
 
@@ -643,7 +899,7 @@ Date:   Fri Sep 12 22:00:04 2014 +0800
     Signed-off-by: Graeme Gregory <graeme.gregory at linaro.org>
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit cf1cbe39385d417286a98e3abd7ea3456be2e88c
+commit ed545c4a15e82373747e2ca4dd44c313a5cbfdbc
 Author: Graeme Gregory <graeme.gregory at linaro.org>
 Date:   Fri Sep 12 22:00:03 2014 +0800
 
@@ -658,7 +914,7 @@ Date:   Fri Sep 12 22:00:03 2014 +0800
     Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit 90e5cfbaf183d0eb92f1977c24da20c4e0a2f6be
+commit f6b5641dd6b5bf915ee9c18bb0f44f07b858bfc2
 Author: Al Stone <al.stone at linaro.org>
 Date:   Fri Sep 12 22:00:02 2014 +0800
 
@@ -690,7 +946,7 @@ Date:   Fri Sep 12 22:00:02 2014 +0800
     Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit 2fe5d24887dea3f1bffabf04e364fa9f355ed553
+commit 7a5a04722c2527962e4b1ebc979e185a64ed11b4
 Author: Tomasz Nowicki <tomasz.nowicki at linaro.org>
 Date:   Fri Sep 12 22:00:01 2014 +0800
 
@@ -708,7 +964,7 @@ Date:   Fri Sep 12 22:00:01 2014 +0800
     Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit 8c278c76231f0ba0110e755678eefdd6d077f5da
+commit 80eb7126770fd6b5c595e4733fb3194bda75f25b
 Author: Ashwin Chaugule <ashwin.chaugule at linaro.org>
 Date:   Fri Sep 12 22:00:00 2014 +0800
 
@@ -725,7 +981,7 @@ Date:   Fri Sep 12 22:00:00 2014 +0800
     Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit 651ab5ff6804fa0f516715b4d47399e587944de0
+commit 36633ceecab0b57354030ba4e796c3eccb0084a8
 Author: Hanjun Guo <hanjun.guo at linaro.org>
 Date:   Fri Sep 12 21:59:59 2014 +0800
 
@@ -737,312 +993,7 @@ Date:   Fri Sep 12 21:59:59 2014 +0800
     
     Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
 
-commit b91246f1a7120de6de8fe630ed01e9a0d0415e88
-Author: Tanmay Inamdar <tinamdar at apm.com>
-Date:   Fri Sep 26 14:08:27 2014 -0700
-
-    MAINTAINERS: entry for APM X-Gene PCIe host driver
-    
-    Add entry for AppliedMicro X-Gene PCIe host driver.
-    
-    Signed-off-by: Tanmay Inamdar <tinamdar at apm.com>
-
-commit d20b104083718058b599a5ca1a925d8c5243e2e1
-Author: Tanmay Inamdar <tinamdar at apm.com>
-Date:   Fri Sep 26 14:08:26 2014 -0700
-
-    dt-bindings: pci: xgene pcie device tree bindings
-    
-    This patch adds the bindings for X-Gene PCIe driver. The driver resides
-    under 'drivers/pci/host/pci-xgene.c' file.
-    
-    Signed-off-by: Tanmay Inamdar <tinamdar at apm.com>
-
-commit 9c429c919b77a3a63ac2843e9e0e2e50e59d28f3
-Author: Tanmay Inamdar <tinamdar at apm.com>
-Date:   Fri Sep 26 14:08:25 2014 -0700
-
-    arm64: dts: APM X-Gene PCIe device tree nodes
-    
-    This patch adds the device tree nodes for APM X-Gene PCIe host controller and
-    PCIe clock interface. Since X-Gene SOC supports maximum 5 ports, 5 dts
-    nodes are added.
-    
-    Signed-off-by: Tanmay Inamdar <tinamdar at apm.com>
-
-commit 3aa4f71932b67e648aff4ae0dc5ace7162d74c1c
-Author: Tanmay Inamdar <tinamdar at apm.com>
-Date:   Fri Sep 26 14:08:24 2014 -0700
-
-    pci:host: APM X-Gene PCIe host controller driver
-    
-    This patch adds the AppliedMicro X-Gene SOC PCIe host controller driver.
-    X-Gene PCIe controller supports maximum up to 8 lanes and GEN3 speed.
-    X-Gene SOC supports maximum 5 PCIe ports.
-    
-    Reviewed-by: Liviu Dudau <Liviu.Dudau at arm.com>
-    Tested-by: Ming Lei <ming.lei at canonical.com>
-    Tested-by: Dann Frazier <dann.frazier at canonical.com>
-    Signed-off-by: Tanmay Inamdar <tinamdar at apm.com>
-
-commit f3c00bd4ae49b19923049f0f4f9d6a95eaa61b1e
-Author: Liviu Dudau <Liviu.Dudau at arm.com>
-Date:   Tue Sep 23 20:01:14 2014 +0100
-
-    arm64: Add architectural support for PCI
-    
-    Use the generic PCI domain and OF functions to provide support for PCI
-    on arm64.
-    
-    [bhelgaas: Change comments to use generic PCI, not just PCIe.  Nothing at
-    this level is PCIe-specific.]
-    Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
-    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
-    Acked-by: Catalin Marinas <catalin.marinas at arm.com>
-
-commit 497220defa08534526ad7b20a9c7eb2d0d903ca4
-Author: Liviu Dudau <Liviu.Dudau at arm.com>
-Date:   Tue Sep 23 20:01:13 2014 +0100
-
-    PCI: Add pci_remap_iospace() to map bus I/O resources
-    
-    Add pci_remap_iospace() to map bus I/O resources into the CPU virtual
-    address space.  Architectures with special needs may provide their own
-    version, but most should be able to use this one.
-    
-    This function is useful for PCI host bridge drivers that need to map the
-    PCI I/O resources into virtual memory space.
-    
-    [bhelgaas: phys_addr description, drop temporary "err" variable]
-    Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
-    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
-    Reviewed-by: Rob Herring <robh at kernel.org>
-    Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
-    CC: Arnd Bergmann <arnd at arndb.de>
-
-commit 7a46ace11cf09b3713dcdc2ef4a17130a738f856
-Author: Liviu Dudau <Liviu.Dudau at arm.com>
-Date:   Tue Sep 23 20:01:12 2014 +0100
-
-    PCI: Assign unassigned bus resources in pci_scan_root_bus()
-    
-    If the firmware has not assigned all the bus resources and we are not just
-    probing the PCI buses, it makes sense to assign the unassigned resources
-    in pci_scan_root_bus().
-    
-    Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
-    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
-    CC: Arnd Bergmann <arnd at arndb.de>
-    CC: Jason Gunthorpe <jgunthorpe at obsidianresearch.com>
-    CC: Rob Herring <robh+dt at kernel.org>
-
-commit fe33bc876010c3ef700c863099f2c3c1a5e2c18b
-Author: Liviu Dudau <Liviu.Dudau at arm.com>
-Date:   Wed Sep 24 11:27:33 2014 -0600
-
-    of/pci: Add support for parsing PCI host bridge resources from DT
-    
-    Provide a function to parse the PCI DT ranges that can be used to create a
-    pci_host_bridge structure together with its associated bus.
-    
-    Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
-    [make io_base parameter optional]
-    Signed-off-by: Robert Richter <rrichter at cavium.com>
-    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
-    CC: Arnd Bergmann <arnd at arndb.de>
-    CC: Grant Likely <grant.likely at linaro.org>
-    CC: Rob Herring <robh+dt at kernel.org>
-    CC: Catalin Marinas <catalin.marinas at arm.com>
-
-commit 71094afda69ac873bb3d6486307e3048e21e912c
-Author: Liviu Dudau <Liviu.Dudau at arm.com>
-Date:   Tue Sep 23 20:01:10 2014 +0100
-
-    of/pci: Add of_pci_get_domain_nr() and of_get_pci_domain_nr()
-    
-    Add pci_get_new_domain_nr() to allocate a new domain number and
-    of_get_pci_domain_nr() to retrieve the PCI domain number of a given device
-    from DT.  Host bridge drivers or architecture-specific code can choose to
-    implement their PCI domain number policy using these two functions.
-    
-    Using of_get_pci_domain_nr() guarantees a stable PCI domain number on every
-    boot provided that all host bridge controllers are assigned a number in the
-    device tree using "linux,pci-domain" property.  Mixing use of
-    pci_get_new_domain_nr() and of_get_pci_domain_nr() is not recommended as it
-    can lead to potentially conflicting domain numbers being assigned to root
-    buses behind different host bridges.
-    
-    Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
-    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
-    CC: Arnd Bergmann <arnd at arndb.de>
-    CC: Grant Likely <grant.likely at linaro.org>
-    CC: Rob Herring <robh+dt at kernel.org>
-    CC: Catalin Marinas <catalin.marinas at arm.com>
-
-commit 6b385455f18d15da6b5d60a3b67fdb846ae1a3b1
-Author: Catalin Marinas <catalin.marinas at arm.com>
-Date:   Tue Sep 23 20:01:09 2014 +0100
-
-    PCI: Add generic domain handling
-    
-    The handling of PCI domains (or PCI segments in ACPI speak) is usually a
-    straightforward affair but its implementation is currently left to the
-    architectural code, with pci_domain_nr(b) querying the value of the domain
-    associated with bus b.
-    
-    This patch introduces CONFIG_PCI_DOMAINS_GENERIC as an option that can be
-    selected if an architecture wants a simple implementation where the value
-    of the domain associated with a bus is stored in struct pci_bus.
-    
-    The architectures that select CONFIG_PCI_DOMAINS_GENERIC will then have to
-    implement pci_bus_assign_domain_nr() as a way of setting the domain number
-    associated with a root bus.  All child buses except the root bus will
-    inherit the domain_nr value from their parent.
-    
-    Signed-off-by: Catalin Marinas <Catalin.Marinas at arm.com>
-    [Renamed pci_set_domain_nr() to pci_bus_assign_domain_nr()]
-    Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
-    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
-    CC: Arnd Bergmann <arnd at arndb.de>
-
-commit 04b36e0e1da5a96a58dec4f1b393090f00e5b635
-Author: Liviu Dudau <Liviu.Dudau at arm.com>
-Date:   Tue Sep 23 20:01:08 2014 +0100
-
-    PCI: Create pci_host_bridge before root bus
-    
-    Before 7b5436635800 ("PCI: add generic device into pci_host_bridge
-    struct"), the pci_host_bridge was created before the root bus.  Revert the
-    order of creation as we are going to depend on the pci_host_bridge
-    structure to retrieve the domain number of the root bus.
-    
-    [bhelgaas: changelog]
-    Tested-by: Tanmay Inamdar <tinamdar at apm.com>
-    Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
-    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
-    Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
-    Acked-by: Grant Likely <grant.likely at linaro.org>
-
-commit 7569c510218798bd7e5216bf14a42c656f14e891
-Author: Liviu Dudau <Liviu.Dudau at arm.com>
-Date:   Tue Sep 23 20:01:07 2014 +0100
-
-    of/pci: Fix the conversion of IO ranges into IO resources
-    
-    The ranges property for a host bridge controller in DT describes the
-    mapping between the PCI bus address and the CPU physical address.  The
-    resources framework however expects that the IO resources start at a pseudo
-    "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT.  The
-    conversion from PCI ranges to resources failed to take that into account,
-    returning a CPU physical address instead of a port number.
-    
-    Also fix all the drivers that depend on the old behaviour by fetching the
-    CPU physical address based on the port number where it is being needed.
-    
-    Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
-    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
-    Acked-by: Linus Walleij <linus.walleij at linaro.org>
-    CC: Grant Likely <grant.likely at linaro.org>
-    CC: Rob Herring <robh+dt at kernel.org>
-    CC: Arnd Bergmann <arnd at arndb.de>
-    CC: Thierry Reding <thierry.reding at gmail.com>
-    CC: Simon Horman <horms at verge.net.au>
-    CC: Catalin Marinas <catalin.marinas at arm.com>
-
-commit 1b381671c9dd2c82cd6f04bc1588d0fc4e1aea59
-Author: Liviu Dudau <Liviu.Dudau at arm.com>
-Date:   Tue Sep 23 20:01:06 2014 +0100
-
-    of/pci: Move of_pci_range_to_resources() to of/address.c
-    
-    We need to enhance of_pci_range_to_resources() enough that it won't make
-    sense for it to be inline anymore.  Move it to drivers/of/address.c,
-    keeping it under #ifdef CONFIG_PCI.
-    
-    [bhelgaas: drop extra detail from changelog, move def under CONFIG_PCI]
-    Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
-    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
-    CC: Grant Likely <grant.likely at linaro.org>
-    CC: Rob Herring <robh+dt at kernel.org>
-    CC: Arnd Bergmann <arnd at arndb.de>
-    CC: Catalin Marinas <catalin.marinas at arm.com>
-
-commit eedd8f88d4895d5c6bc46cf3ddeb114a0fafb7c3
-Author: Bjorn Helgaas <bhelgaas at google.com>
-Date:   Tue Sep 23 17:27:42 2014 -0600
-
-    of/pci: Define of_pci_range_to_resource() only when CONFIG_PCI=y
-    
-    of_pci_range_to_resource() was previously defined always, but it's only
-    used by PCI code, so move the definition inside the CONFIG_OF_ADDRESS &&
-    CONFIG_PCI block.
-    
-    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
-
-commit 4ac73f8ded507537318717bb2b5b6c765db633cd
-Author: Liviu Dudau <Liviu.Dudau at arm.com>
-Date:   Tue Sep 23 20:01:05 2014 +0100
-
-    ARM: Define PCI_IOBASE as the base of virtual PCI IO space
-    
-    This is needed for calls into OF code that parses PCI ranges.  It signals
-    support for memory mapped PCI I/O accesses that are described by device
-    trees.
-    
-    Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
-    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
-    Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
-    Acked-by: Arnd Bergmann <arnd at arndb.de>
-    CC: Russell King <linux at arm.linux.org.uk>
-    CC: Rob Herring <robh+dt at kernel.org>
-
-commit ce7af33b6db857c95ac3b65fef37e589e839cc79
-Author: Liviu Dudau <Liviu.Dudau at arm.com>
-Date:   Tue Sep 23 20:01:04 2014 +0100
-
-    of/pci: Add pci_register_io_range() and pci_pio_to_address()
-    
-    Some architectures do not have a simple view of the PCI I/O space and
-    instead use a range of CPU addresses that map to bus addresses.  For some
-    architectures these ranges will be expressed by OF bindings in a device
-    tree file.
-    
-    This patch introduces a pci_register_io_range() helper function with a
-    generic implementation that can be used by such architectures to keep track
-    of the I/O ranges described by the PCI bindings.  If the PCI_IOBASE macro
-    is not defined, that signals lack of support for PCI and we return an
-    error.
-    
-    In order to retrieve the CPU address associated with an I/O port, a new
-    helper function pci_pio_to_address() is introduced.  This will search in
-    the list of ranges registered with pci_register_io_range() and return the
-    CPU address that corresponds to the given port.
-    
-    Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
-    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
-    Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
-    Acked-by: Rob Herring <robh at kernel.org>
-    CC: Grant Likely <grant.likely at linaro.org>
-    CC: Arnd Bergmann <arnd at arndb.de>
-
-commit c5d57f95901af49149ebf6dfc3d7518157e41bfa
-Author: Liviu Dudau <Liviu.Dudau at arm.com>
-Date:   Tue Sep 23 20:01:03 2014 +0100
-
-    asm-generic/io.h: Fix ioport_map() for !CONFIG_GENERIC_IOMAP
-    
-    The !CONFIG_GENERIC_IOMAP version of ioport_map() is wrong.  It returns a
-    mapped, i.e., virtual, address that can start from zero and completely
-    ignores the PCI_IOBASE and IO_SPACE_LIMIT that most architectures that use
-    !CONFIG_GENERIC_MAP define.
-    
-    Tested-by: Tanmay Inamdar <tinamdar at apm.com>
-    Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
-    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
-    Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
-    Acked-by: Arnd Bergmann <arnd at arndb.de>
-
-commit a65e51156bec2c8d690b924bbddf1a740309e543
+commit 1029a72c660016d7b566f9b91156068f4a86ccb7
 Author: Mark Salter <msalter at redhat.com>
 Date:   Tue Jun 24 09:50:28 2014 -0400
 
@@ -1054,92 +1005,7 @@ Date:   Tue Jun 24 09:50:28 2014 -0400
     
     Signed-off-by: Mark Salter <msalter at redhat.com>
 
-commit c6b81122978c39e52021cc7308edafff88c8b87a
-Author: Ard Biesheuvel <ard.biesheuvel at linaro.org>
-Date:   Wed Jul 30 11:59:04 2014 +0100
-
-    arm64/efi: efistub: don't abort if base of DRAM is occupied
-    
-    If we cannot relocate the kernel Image to its preferred offset of base of DRAM
-    plus TEXT_OFFSET, instead relocate it to the lowest available 2 MB boundary plus
-    TEXT_OFFSET. We may lose a bit of memory at the low end, but we can still
-    proceed normally otherwise.
-    
-    Acked-by: Mark Salter <msalter at redhat.com>
-    Acked-by: Mark Rutland <mark.rutland at arm.com>
-    Acked-by: Leif Lindholm <leif.lindholm at linaro.org>
-    Tested-by: Leif Lindholm <leif.lindholm at linaro.org>
-    Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
-    Signed-off-by: Will Deacon <will.deacon at arm.com>
-
-commit 81fd1d315f3c5b13f9dcf71cce51dfd3a10331c3
-Author: Ard Biesheuvel <ard.biesheuvel at linaro.org>
-Date:   Wed Jul 30 11:59:03 2014 +0100
-
-    arm64/efi: efistub: cover entire static mem footprint in PE/COFF .text
-    
-    The static memory footprint of a kernel Image at boot is larger than the
-    Image file itself. Things like .bss data and initial page tables are allocated
-    statically but populated dynamically so their content is not contained in the
-    Image file.
-    
-    However, if EFI (or GRUB) has loaded the Image at precisely the desired offset
-    of base of DRAM + TEXT_OFFSET, the Image will be booted in place, and we have
-    to make sure that the allocation done by the PE/COFF loader is large enough.
-    
-    Fix this by growing the PE/COFF .text section to cover the entire static
-    memory footprint. The part of the section that is not covered by the payload
-    will be zero initialised by the PE/COFF loader.
-    
-    Acked-by: Mark Salter <msalter at redhat.com>
-    Acked-by: Mark Rutland <mark.rutland at arm.com>
-    Acked-by: Leif Lindholm <leif.lindholm at linaro.org>
-    Tested-by: Leif Lindholm <leif.lindholm at linaro.org>
-    Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
-    Signed-off-by: Will Deacon <will.deacon at arm.com>
-
-commit 8f5f73c2117c2dc4e8903d162023c34177327ae3
-Author: Mark Rutland <mark.rutland at arm.com>
-Date:   Wed Jul 30 11:59:02 2014 +0100
-
-    arm64: spin-table: handle unmapped cpu-release-addrs
-    
-    In certain cases the cpu-release-addr of a CPU may not fall in the
-    linear mapping (e.g. when the kernel is loaded above this address due to
-    the presence of other images in memory). This is problematic for the
-    spin-table code as it assumes that it can trivially convert a
-    cpu-release-addr to a valid VA in the linear map.
-    
-    This patch modifies the spin-table code to use a temporary cached
-    mapping to write to a given cpu-release-addr, enabling us to support
-    addresses regardless of whether they are covered by the linear mapping.
-    
-    Acked-by: Leif Lindholm <leif.lindholm at linaro.org>
-    Tested-by: Leif Lindholm <leif.lindholm at linaro.org>
-    Tested-by: Mark Salter <msalter at redhat.com>
-    Signed-off-by: Mark Rutland <mark.rutland at arm.com>
-    [ardb: added (__force void *) cast]
-    Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
-    Signed-off-by: Will Deacon <will.deacon at arm.com>
-
-commit b00c56bff1ffb6c77655479fb350ee3d5c8bcf63
-Author: Mark Salter <msalter at redhat.com>
-Date:   Tue Jun 24 23:16:45 2014 -0400
-
-    perf: fix arm64 build error
-    
-    I'm seeing the following build error on arm64:
-    
-      In file included from util/event.c:3:0:
-      util/event.h:95:17: error: 'PERF_REGS_MAX' undeclared here (not in a function)
-        u64 cache_regs[PERF_REGS_MAX];
-                     ^
-    
-    This patch adds a PEFF_REGS_MAX definition for arm64.
-    
-    Signed-off-by: Mark Salter <msalter at redhat.com>
-
-commit f440dcb067bf1367719e8a41b96a2a83c1232690
+commit 0fdae79847bdc64aee1a765c0bb5ee99ed95eb0e
 Author: Mark Salter <msalter at redhat.com>
 Date:   Thu Jul 17 13:34:50 2014 -0400
 
@@ -1157,7 +1023,7 @@ Date:   Thu Jul 17 13:34:50 2014 -0400
     
     Signed-off-by: Mark Salter <msalter at redhat.com>
 
-commit 93b44dc9e1d73d4864a9350888509792f25e4210
+commit 6e00476b0a33370988b3fee8551c0a8d98206bd2
 Author: Kyle McMartin <kmcmarti at redhat.com>
 Date:   Tue May 13 22:25:26 2014 -0400
 
@@ -1227,109 +1093,513 @@ Date:   Tue May 13 22:25:26 2014 -0400
     Signed-off-by: Kyle McMartin <kmcmarti at redhat.com>
     Signed-off-by: Donald Dutile <ddutile at redhat.com>
 
- Documentation/arm64/arm-acpi.txt                   | 218 +++++++
- .../devicetree/bindings/pci/xgene-pci.txt          |  57 ++
- Documentation/kernel-parameters.txt                |   3 +-
- MAINTAINERS                                        |   8 +
- arch/arm/include/asm/io.h                          |   1 +
- arch/arm/include/asm/kvm_mmu.h                     |  13 +
- arch/arm/kvm/arm.c                                 |  23 +-
- arch/arm/mach-integrator/pci_v3.c                  |  23 +-
- arch/arm64/Kconfig                                 |  28 +-
- arch/arm64/Makefile                                |   1 +
- arch/arm64/boot/dts/apm-mustang.dts                |   8 +
- arch/arm64/boot/dts/apm-storm.dtsi                 | 165 ++++++
- arch/arm64/include/asm/Kbuild                      |   1 +
- arch/arm64/include/asm/acenv.h                     |  18 +
- arch/arm64/include/asm/acpi.h                      |  99 ++++
- arch/arm64/include/asm/cpu_ops.h                   |   1 +
- arch/arm64/include/asm/elf.h                       |   3 +-
- arch/arm64/include/asm/io.h                        |   3 +-
- arch/arm64/include/asm/kvm_arm.h                   |  17 +-
- arch/arm64/include/asm/kvm_mmu.h                   |  75 +++
- arch/arm64/include/asm/pci.h                       |  37 ++
- arch/arm64/include/asm/pgtable.h                   |   2 +
- arch/arm64/include/asm/psci.h                      |   3 +-
- arch/arm64/include/asm/smp.h                       |  10 +-
- arch/arm64/kernel/Makefile                         |   5 +-
- arch/arm64/kernel/acpi.c                           | 397 +++++++++++++
- arch/arm64/kernel/cpu_ops.c                        |   8 +-
- arch/arm64/kernel/efi-stub.c                       |  16 +-
- arch/arm64/kernel/efi.c                            |  11 +
- arch/arm64/kernel/head.S                           |   6 +-
- arch/arm64/kernel/pci.c                            |  70 +++
- arch/arm64/kernel/process.c                        |   6 +
- arch/arm64/kernel/psci.c                           |  78 ++-
- arch/arm64/kernel/setup.c                          |  64 +-
- arch/arm64/kernel/smp.c                            |   2 +-
- arch/arm64/kernel/smp_parking_protocol.c           | 110 ++++
- arch/arm64/kernel/smp_spin_table.c                 |  22 +-
- arch/arm64/kernel/time.c                           |   7 +
- arch/arm64/kvm/hyp-init.S                          |  20 +-
- arch/arm64/mm/dma-mapping.c                        |  65 ++
- arch/arm64/pci/Makefile                            |   1 +
- arch/arm64/pci/pci.c                               |  28 +
- drivers/acpi/Kconfig                               |   6 +-
- drivers/acpi/Makefile                              |   6 +-
- drivers/acpi/acpica/utresrc.c                      |   4 +-
- drivers/acpi/bus.c                                 |   3 +
- drivers/acpi/internal.h                            |   5 +
- drivers/acpi/osl.c                                 |   6 +-
- drivers/acpi/processor_core.c                      |  37 ++
- drivers/acpi/sleep-arm.c                           |  28 +
- drivers/acpi/tables.c                              | 115 +++-
- drivers/acpi/utils.c                               |  26 +
- drivers/ata/Kconfig                                |   2 +-
- drivers/ata/ahci_platform.c                        |  13 +
- drivers/ata/ahci_xgene.c                           |  30 +-
- drivers/clocksource/arm_arch_timer.c               | 120 +++-
- drivers/irqchip/irq-gic-v3.c                       |  10 +
- drivers/irqchip/irq-gic.c                          | 116 ++++
- drivers/irqchip/irqchip.c                          |   3 +
- drivers/net/ethernet/amd/xgbe/xgbe-dev.c           |  12 +
- drivers/net/ethernet/amd/xgbe/xgbe-drv.c           |   3 +
- drivers/net/ethernet/amd/xgbe/xgbe-main.c          |   1 +
- drivers/net/ethernet/amd/xgbe/xgbe.h               |   3 +
- drivers/net/ethernet/smsc/smc91x.c                 |  10 +
- drivers/net/phy/amd-xgbe-phy.c                     | 408 +++++++------
- drivers/of/address.c                               | 154 +++++
- drivers/of/of_pci.c                                | 142 +++++
- drivers/pci/host/Kconfig                           |  10 +
- drivers/pci/host/Makefile                          |   1 +
- drivers/pci/host/pci-tegra.c                       |  10 +-
- drivers/pci/host/pci-xgene.c                       | 659 +++++++++++++++++++++
- drivers/pci/host/pcie-rcar.c                       |  21 +-
- drivers/pci/pci.c                                  |  40 ++
- drivers/pci/probe.c                                |  46 +-
- drivers/pnp/resource.c                             |   2 +
- drivers/tty/Kconfig                                |   6 +
- drivers/tty/Makefile                               |   1 +
- drivers/tty/sbsauart.c                             | 355 +++++++++++
- drivers/tty/serial/8250/8250_dw.c                  |   9 +
- drivers/virtio/virtio_mmio.c                       |  12 +-
- include/acpi/acnames.h                             |   4 +
- include/acpi/acpi_bus.h                            |   2 +
- include/acpi/acpi_io.h                             |   6 +
- include/acpi/acpixf.h                              |   2 +-
- include/acpi/actbl1.h                              |  19 +-
- include/acpi/actbl3.h                              |   9 +-
- include/asm-generic/io.h                           |   2 +-
- include/asm-generic/pgtable.h                      |   4 +
- include/kvm/arm_vgic.h                             |  20 +-
- include/linux/acpi.h                               |   5 +
- include/linux/clocksource.h                        |   6 +
- include/linux/irqchip/arm-gic-acpi.h               |  31 +
- include/linux/irqchip/arm-gic.h                    |   2 +
- include/linux/of_address.h                         |  17 +-
- include/linux/of_pci.h                             |  13 +
- include/linux/pci.h                                |  64 +-
- tools/perf/arch/arm64/include/perf_regs.h          |   2 +
- virt/kvm/arm/arch_timer.c                          | 108 ++--
- virt/kvm/arm/vgic-v2.c                             |  75 ++-
- virt/kvm/arm/vgic-v3.c                             |   8 +-
- virt/kvm/arm/vgic.c                                |  32 +-
- 101 files changed, 4112 insertions(+), 487 deletions(-)
-
+ Documentation/acpi/properties.txt                | 410 ++++++++++++
+ Documentation/arm64/arm-acpi.txt                 | 218 +++++++
+ Documentation/kernel-parameters.txt              |   3 +-
+ arch/arm64/Kconfig                               |   6 +
+ arch/arm64/Makefile                              |   1 +
+ arch/arm64/include/asm/acenv.h                   |  18 +
+ arch/arm64/include/asm/acpi.h                    |  99 +++
+ arch/arm64/include/asm/cpu_ops.h                 |   1 +
+ arch/arm64/include/asm/elf.h                     |   3 +-
+ arch/arm64/include/asm/psci.h                    |   3 +-
+ arch/arm64/include/asm/smp.h                     |  10 +-
+ arch/arm64/kernel/Makefile                       |   4 +-
+ arch/arm64/kernel/acpi.c                         | 397 ++++++++++++
+ arch/arm64/kernel/cpu_ops.c                      |   8 +-
+ arch/arm64/kernel/efi.c                          |  11 +
+ arch/arm64/kernel/process.c                      |   6 +
+ arch/arm64/kernel/psci.c                         |  78 ++-
+ arch/arm64/kernel/setup.c                        |  64 +-
+ arch/arm64/kernel/smp.c                          |   2 +-
+ arch/arm64/kernel/smp_parking_protocol.c         | 110 ++++
+ arch/arm64/kernel/time.c                         |   7 +
+ arch/arm64/mm/dma-mapping.c                      | 103 +++
+ arch/arm64/pci/Makefile                          |   1 +
+ arch/arm64/pci/pci.c                             |  28 +
+ drivers/acpi/Kconfig                             |   6 +-
+ drivers/acpi/Makefile                            |   7 +-
+ drivers/acpi/bus.c                               |   3 +
+ drivers/acpi/internal.h                          |  11 +
+ drivers/acpi/osl.c                               |   6 +-
+ drivers/acpi/processor_core.c                    |  37 ++
+ drivers/acpi/property.c                          | 586 +++++++++++++++++
+ drivers/acpi/scan.c                              |  93 ++-
+ drivers/acpi/sleep-arm.c                         |  28 +
+ drivers/acpi/tables.c                            | 115 +++-
+ drivers/acpi/utils.c                             |  26 +
+ drivers/ata/Kconfig                              |   2 +-
+ drivers/ata/ahci_platform.c                      |  13 +
+ drivers/ata/ahci_xgene.c                         |  30 +-
+ drivers/base/Makefile                            |   2 +-
+ drivers/base/property.c                          | 235 +++++++
+ drivers/clocksource/arm_arch_timer.c             | 131 +++-
+ drivers/gpio/devres.c                            |  34 +
+ drivers/gpio/gpio-sch.c                          | 293 ++++-----
+ drivers/gpio/gpiolib-acpi.c                      |  78 ++-
+ drivers/gpio/gpiolib.c                           |  86 ++-
+ drivers/gpio/gpiolib.h                           |   7 +-
+ drivers/input/keyboard/gpio_keys_polled.c        | 163 ++---
+ drivers/irqchip/irq-gic-v3.c                     |  10 +
+ drivers/irqchip/irq-gic.c                        | 116 ++++
+ drivers/irqchip/irqchip.c                        |   3 +
+ drivers/leds/leds-gpio.c                         | 185 +++---
+ drivers/misc/eeprom/at25.c                       |  41 +-
+ drivers/net/ethernet/amd/Kconfig                 |   2 +-
+ drivers/net/ethernet/amd/xgbe/xgbe-dev.c         |  16 +-
+ drivers/net/ethernet/amd/xgbe/xgbe-drv.c         |   3 +
+ drivers/net/ethernet/amd/xgbe/xgbe-main.c        | 294 +++++++--
+ drivers/net/ethernet/amd/xgbe/xgbe-mdio.c        |  20 +-
+ drivers/net/ethernet/amd/xgbe/xgbe-ptp.c         |   4 +-
+ drivers/net/ethernet/amd/xgbe/xgbe.h             |  13 +
+ drivers/net/ethernet/apm/xgene/xgene_enet_hw.c   |  77 ++-
+ drivers/net/ethernet/apm/xgene/xgene_enet_main.c |  68 +-
+ drivers/net/ethernet/apm/xgene/xgene_enet_main.h |   1 +
+ drivers/net/ethernet/smsc/smc91x.c               |  10 +
+ drivers/net/phy/Kconfig                          |   2 +-
+ drivers/net/phy/amd-xgbe-phy.c                   | 777 ++++++++++++-----------
+ drivers/of/base.c                                | 186 ++++++
+ drivers/pnp/resource.c                           |   2 +
+ drivers/tty/Kconfig                              |   6 +
+ drivers/tty/Makefile                             |   1 +
+ drivers/tty/sbsauart.c                           | 355 +++++++++++
+ drivers/tty/serial/8250/8250_dw.c                |   9 +
+ drivers/virtio/virtio_mmio.c                     |  12 +-
+ include/acpi/acpi_bus.h                          |  10 +
+ include/acpi/acpi_io.h                           |   6 +
+ include/kvm/arm_vgic.h                           |  20 +-
+ include/linux/acpi.h                             |  95 ++-
+ include/linux/clocksource.h                      |   6 +
+ include/linux/gpio/consumer.h                    |   5 +
+ include/linux/gpio_keys.h                        |   3 +
+ include/linux/irqchip/arm-gic-acpi.h             |  31 +
+ include/linux/irqchip/arm-gic.h                  |   2 +
+ include/linux/leds.h                             |   1 +
+ include/linux/of.h                               |  37 ++
+ include/linux/pci.h                              |  37 +-
+ include/linux/property.h                         | 207 ++++++
+ virt/kvm/arm/arch_timer.c                        | 108 ++--
+ virt/kvm/arm/vgic-v2.c                           |  75 ++-
+ virt/kvm/arm/vgic-v3.c                           |   8 +-
+ virt/kvm/arm/vgic.c                              |  32 +-
+ 89 files changed, 5425 insertions(+), 1054 deletions(-)
+
+diff --git a/Documentation/acpi/properties.txt b/Documentation/acpi/properties.txt
+new file mode 100644
+index 0000000..13a93c5
+--- /dev/null
++++ b/Documentation/acpi/properties.txt
+@@ -0,0 +1,410 @@
++ACPI device properties
++======================
++This document describes the format and interfaces of ACPI device
++properties as specified in "Device Properties UUID For _DSD" available
++here:
++
++http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
++
++1. Introduction
++---------------
++In systems that use ACPI and want to take advantage of device specific
++properties, there needs to be a standard way to return and extract
++name-value pairs for a given ACPI device.
++
++An ACPI device that wants to export its properties must implement a
++static name called _DSD that takes no arguments and returns a package of
++packages:
++
++	Name (_DSD, Package () {
++		ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
++		Package () {
++			Package () {"name1", <VALUE1>},
++			Package () {"name2", <VALUE2>}
++		}
++	})
++
++The UUID identifies contents of the following package. In case of ACPI
++device properties it is daffd814-6eba-4d8c-8a91-bc9bbf4aa301.
++
++In each returned package, the first item is the name and must be a string.
++The corresponding value can be a string, integer, reference, or package. If
++a package it may only contain strings, integers, and references.
++
++An example device where we might need properties is a device that uses
++GPIOs. In addition to the GpioIo/GpioInt resources the driver needs to
++know which GPIO is used for which purpose.
++
++To solve this we add the following ACPI device properties to the device:
++
++	Device (DEV0)
++	{
++		Name (_CRS, ResourceTemplate () {
++			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
++				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {0}
++			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
++				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {1}
++			...
++		})
++
++		Name (_DSD, Package () {
++			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
++			Package () {
++				Package () {"reset-gpio", {^DEV0, 0, 0, 0}},
++				Package () {"shutdown-gpio", {^DEV0, 1, 0, 0}},
++			}
++		})
++	}
++
++Now the device driver can reference the GPIOs using names instead of
++using indexes.
++
++If there is an existing Device Tree binding for a device, it is expected
++that the same bindings are used with ACPI properties, so that the driver
++dealing with the device needs only minor modifications if any.
++
++2. Formal definition of properties
++----------------------------------
++The following chapters define the currently supported properties. For
++these there exists a helper function that can be used to extract the
++property value.
++
++2.1 Integer types
++-----------------
++ACPI integers are always 64-bit. However, for drivers the full range is
++typically not needed so we provide a set of functions which convert the
++64-bit integer to a smaller Linux integer type.
++
++An integer property looks like this:
++
++	Package () {"i2c-sda-hold-time-ns", 300},
++	Package () {"clock-frequency", 400000},
++
++To read a property value, use a unified property accessor as shown
++below:
++
++	u32 val;
++	int ret;
++
++	ret = device_property_read_u32(dev, "clock-frequency", &val);
++	if (ret)
++		/* Handle error */
++
++The function returns 0 if the property is copied to 'val' or negative
++errno if something went wrong (or the property does not exist).
++
++2.2 Integer arrays
++------------------
++An integer array is a package holding only integers. Arrays can be used to
++represent different things like Linux input key codes to GPIO mappings, pin
++control settings, dma request lines, etc.
++
++An integer array looks like this:
++
++	Package () {
++		"max8952,dvs-mode-microvolt",
++		Package () {
++			1250000,
++			1200000,
++			1050000,
++			950000,
++		}
++	}
++
++The above array property can be accessed like:
++
++	u32 voltages[4];
++	int ret;
++
++	ret = device_property_read_u32_array(dev, "max8952,dvs-mode-microvolt",
++					     voltages, ARRAY_SIZE(voltages));
++	if (ret)
++		/* Handle error */
++
++
++All functions copy the resulting values cast to a requested type to the
++caller supplied array. If you pass NULL in the value pointer ('voltages' in
++this case), the function returns number of items in the array. This can be
++useful if caller does not know size of the array beforehand.
++
++2.3 Strings
++-----------
++String properties can be used to describe many things like labels for GPIO
++buttons, compability ids, etc.
++
++A string property looks like this:
++
++	Package () {"pwm-names", "backlight"},
++	Package () {"label", "Status-LED"},
++
++You can use device_property_read_string() to extract strings:
++
++	const char *val;
++	int ret;
++
++	ret = device_property_read_string(dev, "label", &val);
++	if (ret)
++		/* Handle error */
++
++Note that the function does not copy the returned string but instead the
++value is modified to point to the string property itself.
++
++The memory is owned by the associated ACPI device object and released
++when it is removed. The user need not free the associated memory.
++
++2.4 String arrays
++-----------------
++String arrays can be useful in describing a list of labels, names for
++DMA channels, etc.
++
++A string array property looks like this:
++
++	Package () {"dma-names", Package () {"tx", "rx", "rx-tx"}},
++	Package () {"clock-output-names", Package () {"pll", "pll-switched"}},
++
++And these can be read in similar way that the integer arrrays:
++
++	const char *dma_names[3];
++	int ret;
++
++	ret = device_property_read_string_array(dev, "dma-names", dma_names,
++						ARRAY_SIZE(dma_names));
++	if (ret)
++		/* Handle error */
++
++The memory management rules follow what is specified for single strings.
++Specifically the returned pointers should be treated as constant and not to
++be freed. That is done automatically when the correspondig ACPI device
++object is released.
++
++2.5 Object references
++---------------------
++An ACPI object reference is used to refer to some object in the
++namespace. For example, if a device has dependencies with some other
++object, an object reference can be used.
++
++An object reference looks like this:
++
++	Package () {"dev0", \_SB.DEV0},
++
++At the time of writing this, there is no unified device_property_* accessor
++for references so one needs to use the following ACPI helper function:
++
++	int acpi_dev_get_property_reference(struct acpi_device *adev,
++					    const char *name,
++					    const char *size_prop, int index,
++					    struct acpi_reference_args *args);
++
++The referenced ACPI device is returned in args->adev if found.
++
++In addition to simple object references it is also possible to have object
++references with arguments. These are represented in ASL as follows:
++
++	Device (\_SB.PCI0.PWM)
++	{
++		Name (_DSD, Package () {
++			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
++			Package () {
++				Package () {"#pwm-cells", 2}
++			}
++		})
++	}
++
++	Device (\_SB.PCI0.BL)
++	{
++		Name (_DSD, Package () {
++			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
++			Package () {
++				Package () {
++					"pwms",
++					Package () {
++						\_SB.PCI0.PWM, 0, 5000000,
++						\_SB.PCI0.PWM, 1, 4500000,
++					}
++				}
++			}
++		})
++	}
++
++In the above example, the referenced device declares a property that
++returns the number of expected arguments (here it is "#pwm-cells"). If
++no such property is given we assume that all the integers following the
++reference are arguments.
++
++In the above example PWM device expects 2 additional arguments. This
++will be validated by the ACPI property core.
++
++The additional arguments must be integers. Nothing else is supported.
++
++It is possible, as in the above example, to have multiple references
++with varying number of integer arguments. It is up to the referenced
++device to declare how many arguments it expects. The 'index' parameter
++selects which reference is returned.
++
++One can use acpi_dev_get_property_reference() as well to extract the
++information in additional parameters:
++
++	struct acpi_reference_args args;
++	struct acpi_device *adev = /* this will point to the BL device */
++	int ret;
++
++	/* extract the first reference */
++	acpi_dev_get_property_reference(adev, "pwms", "#pwm-cells", 0, &args);
++
++	BUG_ON(args.nargs != 2);
++	BUG_ON(args.args[0] != 0);
++	BUG_ON(args.args[1] != 5000000);
++
++	/* extract the second reference */
++	acpi_dev_get_property_reference(adev, "pwms", "#pwm-cells", 1, &args);
++
++	BUG_ON(args.nargs != 2);
++	BUG_ON(args.args[0] != 1);
++	BUG_ON(args.args[1] != 4500000);
++
++In addition to arguments, args.adev now points to the ACPI device that
++corresponds to \_SB.PCI0.PWM.
++
++It is intended that this function is not used directly but instead
++subsystems like pwm implement their ACPI support on top of this function
++in such way that it is hidden from the client drivers, such as via
++pwm_get().
++
++3. Device property hierarchies
++------------------------------
++Devices are organized in a tree within the Linux kernel. It follows that
++the configuration data would also be hierarchical. In order to reach
++equivalence with Device Tree, the ACPI mechanism must also provide some
++sort of tree-like representation. Fortunately, the ACPI namespace is
++already such a structure.
++
++For example, we could have the following device in ACPI namespace. The
++KEYS device is much like gpio_keys_polled.c in that it includes "pseudo"
++devices for each GPIO:
++
++	Device (KEYS)
++	{
++		Name (_CRS, ResourceTemplate () {
++			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
++				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {0}
++			GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly,
++				"\\_SB.PCI0.LPC", 0, ResourceConsumer) {1}
++			...
++		})
++
++		// "pseudo" devices declared under the parent device
++		Device (BTN0) {
++			Name (_DSD, Package () {
++				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
++				Package () {
++					Package () {"label", "minnow_btn0"}
++					Package () {"gpios", Package () {^KEYS, 0, 0, 1}}
++				}
++			})
++		}
++
++		Device (BTN1) {
++			Name (_DSD, Package () {
++				ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
++				Package () {
++					Package () {"label", "minnow_btn1"}
++					Package () {"gpios", Package () {^KEYS, 1, 0, 1}}
++				}
++			})
++		}
++	}
++
++We can extract the above in gpio_keys_polled.c like:
++
++	static int gpio_keys_polled_create_button(struct device *dev, void *child,
++						  void *data)
++	{
++		struct button_data *bdata = data;
++		const char *label = NULL;
++
++		/*
++		 * We need to use device_child_ variant here to access
++		 * properties of the child.
++		 */
++		device_child_property_read_string(dev, child, "label", &label);
++		/* and so on */
++	}
++
++	static void gpio_keys_polled_probe(struct device *dev)
++	{
++		/* Properties for the KEYS device itself */
++		device_property_read(dev, ...);
++
++		/*
++		 * Iterate over button devices and extract their
++		 * firmware configuration.
++		 */
++		ret = device_for_each_child_node(dev, gpio_keys_polled_create_button,
++						 &bdata);
++		if (ret)
++			/* Handle error */
++	}
++
++Note that you still need proper error handling which is omitted in the
++above example.
++
++4. Existing Device Tree enabled drivers
++---------------------------------------
++At the time of writing this, there are ~250 existing DT enabled drivers.
++Allocating _HID/_CID for each would not be feasible. To make sure that
++those drivers can still be used on ACPI systems, we provide an
++alternative way to get these matched.
++
++There is a special _HID "PRP0001" which means that use the DT bindings
++for matching this device to a driver. The driver needs to have
++.of_match_table filled in even when !CONFIG_OF.
++
++An example device would be leds that can be controlled via GPIOs. This
++is represented as "leds-gpio" device and looks like this in the ACPI
++namespace:
++
++	Device (LEDS)
++	{
++		Name (_DSD, Package () {
++			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
++			Package () {
++				Package () {"compatible", Package () {"gpio-leds"}},
++			}
++		})
++		...
++	}
++
++In order to get the existing drivers/leds/leds-gpio.c bound to this
++device, we take advantage of "PRP0001":
++
++	/* Following already exists in the driver */
++	static const struct of_device_id of_gpio_leds_match[] = {
++		{ .compatible = "gpio-leds", },
++		{},
++	};
++	MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
++
++	/* This we add to the driver to get it probed */
++	static const struct acpi_device_id acpi_gpio_leds_match[] = {
++		{ "PRP0001" }, /* Device Tree shoehorned into ACPI */
++		{},
++	};
++	MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match);
++
++	static struct platform_driver gpio_led_driver = {
++		.driver = {
++			/*
++			 * No of_match_ptr() here because we want this
++			 * table to be visible even when !CONFIG_OF to
++			 * match against "compatible" in _DSD.
++			 */
++			.of_match_table = of_gpio_leds_match,
++			.acpi_match_table = acpi_gpio_leds_match,
++		},
++	};
++
++Once ACPI core sees "PRP0001" and that the device has "compatible"
++property it will do the match using .of_match_table instead.
++
++It is preferred that new devices get a proper _HID allocated for them
++instead of inventing new DT "compatible" devices.
 diff --git a/Documentation/arm64/arm-acpi.txt b/Documentation/arm64/arm-acpi.txt
 new file mode 100644
 index 0000000..b7dc826
@@ -1554,71 +1824,8 @@ index 0000000..b7dc826
 +standards from UEFI ASWG. If there are features missing from ACPI to make it
 +function on a platform, ECRs should be submitted to ASWG and go through the
 +approval process.
-diff --git a/Documentation/devicetree/bindings/pci/xgene-pci.txt b/Documentation/devicetree/bindings/pci/xgene-pci.txt
-new file mode 100644
-index 0000000..1070b06
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pci/xgene-pci.txt
-@@ -0,0 +1,57 @@
-+* AppliedMicro X-Gene PCIe interface
-+
-+Required properties:
-+- device_type: set to "pci"
-+- compatible: should contain "apm,xgene-pcie" to identify the core.
-+- reg: A list of physical base address and length for each set of controller
-+       registers. Must contain an entry for each entry in the reg-names
-+       property.
-+- reg-names: Must include the following entries:
-+  "csr": controller configuration registers.
-+  "cfg": pcie configuration space registers.
-+- #address-cells: set to <3>
-+- #size-cells: set to <2>
-+- ranges: ranges for the outbound memory, I/O regions.
-+- dma-ranges: ranges for the inbound memory regions.
-+- #interrupt-cells: set to <1>
-+- interrupt-map-mask and interrupt-map: standard PCI properties
-+	to define the mapping of the PCIe interface to interrupt
-+	numbers.
-+- clocks: from common clock binding: handle to pci clock.
-+
-+Optional properties:
-+- status: Either "ok" or "disabled".
-+- dma-coherent: Present if dma operations are coherent
-+
-+Example:
-+
-+SoC specific DT Entry:
-+
-+	pcie0: pcie at 1f2b0000 {
-+		status = "disabled";
-+		device_type = "pci";
-+		compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie";
-+		#interrupt-cells = <1>;
-+		#size-cells = <2>;
-+		#address-cells = <3>;
-+		reg = < 0x00 0x1f2b0000 0x0 0x00010000   /* Controller registers */
-+			0xe0 0xd0000000 0x0 0x00040000>; /* PCI config space */
-+		reg-names = "csr", "cfg";
-+		ranges = <0x01000000 0x00 0x00000000 0xe0 0x10000000 0x00 0x00010000   /* io */
-+			  0x02000000 0x00 0x80000000 0xe1 0x80000000 0x00 0x80000000>; /* mem */
-+		dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
-+			      0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
-+		interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+		interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc2 0x1
-+				 0x0 0x0 0x0 0x2 &gic 0x0 0xc3 0x1
-+				 0x0 0x0 0x0 0x3 &gic 0x0 0xc4 0x1
-+				 0x0 0x0 0x0 0x4 &gic 0x0 0xc5 0x1>;
-+		dma-coherent;
-+		clocks = <&pcie0clk 0>;
-+	};
-+
-+
-+Board specific DT Entry:
-+	&pcie0 {
-+		status = "ok";
-+	};
 diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
-index 10d51c2..9464c6d 100644
+index 7dbe5ec..bb69b63 100644
 --- a/Documentation/kernel-parameters.txt
 +++ b/Documentation/kernel-parameters.txt
 @@ -165,7 +165,7 @@ multipliers 'Kilo', 'Mega', and 'Giga', equalling 2^10, 2^20, and 2^30
@@ -1638,510 +1845,70 @@ index 10d51c2..9464c6d 100644
  
  			See also Documentation/power/runtime_pm.txt, pci=noacpi
  
-diff --git a/MAINTAINERS b/MAINTAINERS
-index 3705430..f6b49e4 100644
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -6940,6 +6940,14 @@ L:	linux-pci at vger.kernel.org
- S:	Maintained
- F:	drivers/pci/host/*spear*
- 
-+PCI DRIVER FOR APPLIEDMICRO XGENE
-+M:	Tanmay Inamdar <tinamdar at apm.com>
-+L:	linux-pci at vger.kernel.org
-+L:	linux-arm-kernel at lists.infradead.org
-+S:	Maintained
-+F:	Documentation/devicetree/bindings/pci/xgene-pci.txt
-+F:	drivers/pci/host/pci-xgene.c
-+
- PCMCIA SUBSYSTEM
- P:	Linux PCMCIA Team
- L:	linux-pcmcia at lists.infradead.org
-diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
-index 3d23418..22b7529 100644
---- a/arch/arm/include/asm/io.h
-+++ b/arch/arm/include/asm/io.h
-@@ -178,6 +178,7 @@ static inline void __iomem *__typesafe_io(unsigned long addr)
- 
- /* PCI fixed i/o mapping */
- #define PCI_IO_VIRT_BASE	0xfee00000
-+#define PCI_IOBASE		PCI_IO_VIRT_BASE
- 
- #if defined(CONFIG_PCI)
- void pci_ioremap_set_mem_type(int mem_type);
-diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
-index 5cc0b0f..03a08bb 100644
---- a/arch/arm/include/asm/kvm_mmu.h
-+++ b/arch/arm/include/asm/kvm_mmu.h
-@@ -21,6 +21,7 @@
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index ac9afde..14423f3 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -1,5 +1,6 @@
+ config ARM64
+ 	def_bool y
++	select ACPI_REDUCED_HARDWARE_ONLY if ACPI
+ 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
+ 	select ARCH_HAS_SG_CHAIN
+ 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
+@@ -267,6 +268,9 @@ config SMP
  
- #include <asm/memory.h>
- #include <asm/page.h>
-+#include <asm/kvm_arm.h>
+ 	  If you don't know what to do here, say N.
  
- /*
-  * We directly use the kernel VA for the HYP, as we can directly share
-@@ -178,6 +179,18 @@ static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva,
++config ARM_PARKING_PROTOCOL
++	def_bool y if SMP
++
+ config SCHED_MC
+ 	bool "Multi-core scheduler support"
+ 	depends on SMP
+@@ -453,6 +457,8 @@ source "drivers/Kconfig"
  
- void stage2_flush_vm(struct kvm *kvm);
+ source "drivers/firmware/Kconfig"
  
-+static inline int kvm_get_phys_addr_shift(void)
-+{
-+	return KVM_PHYS_SHIFT;
-+}
++source "drivers/acpi/Kconfig"
 +
+ source "fs/Kconfig"
+ 
+ source "arch/arm64/kvm/Kconfig"
+diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
+index 20901ff..983d72a 100644
+--- a/arch/arm64/Makefile
++++ b/arch/arm64/Makefile
+@@ -49,6 +49,7 @@ core-$(CONFIG_NET) += arch/arm64/net/
+ core-$(CONFIG_KVM) += arch/arm64/kvm/
+ core-$(CONFIG_XEN) += arch/arm64/xen/
+ core-$(CONFIG_CRYPTO) += arch/arm64/crypto/
++drivers-$(CONFIG_PCI)	+= arch/arm64/pci/
+ libs-y		:= arch/arm64/lib/ $(libs-y)
+ libs-y		+= $(LIBGCC)
+ libs-$(CONFIG_EFI_STUB) += drivers/firmware/efi/libstub/
+diff --git a/arch/arm64/include/asm/acenv.h b/arch/arm64/include/asm/acenv.h
+new file mode 100644
+index 0000000..b49166f
+--- /dev/null
++++ b/arch/arm64/include/asm/acenv.h
+@@ -0,0 +1,18 @@
++/*
++ * ARM64 specific ACPICA environments and implementation
++ *
++ * Copyright (C) 2014, Linaro Ltd.
++ *   Author: Hanjun Guo <hanjun.guo at linaro.org>
++ *   Author: Graeme Gregory <graeme.gregory at linaro.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
 +
-+static inline u32 get_vttbr_baddr_mask(void)
-+{
-+	return VTTBR_BADDR_MASK;
-+}
++#ifndef _ASM_ACENV_H
++#define _ASM_ACENV_H
 +
-+
- #endif	/* !__ASSEMBLY__ */
- 
- #endif /* __ARM_KVM_MMU_H__ */
-diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
-index a99e0cd..d0fca8f 100644
---- a/arch/arm/kvm/arm.c
-+++ b/arch/arm/kvm/arm.c
-@@ -37,6 +37,7 @@
- #include <asm/mman.h>
- #include <asm/tlbflush.h>
- #include <asm/cacheflush.h>
-+#include <asm/cputype.h>
- #include <asm/virt.h>
- #include <asm/kvm_arm.h>
- #include <asm/kvm_asm.h>
-@@ -61,6 +62,12 @@ static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1);
- static u8 kvm_next_vmid;
- static DEFINE_SPINLOCK(kvm_vmid_lock);
- 
-+#ifdef CONFIG_ARM64
-+static u64 vttbr_baddr_mask;
-+#else
-+static u32 vttbr_baddr_mask;
-+#endif
-+
- static bool vgic_present;
- 
- static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu)
-@@ -429,8 +436,14 @@ static void update_vttbr(struct kvm *kvm)
- 	/* update vttbr to be used with the new vmid */
- 	pgd_phys = virt_to_phys(kvm->arch.pgd);
- 	vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK;
--	kvm->arch.vttbr = pgd_phys & VTTBR_BADDR_MASK;
--	kvm->arch.vttbr |= vmid;
-+
-+	/*
-+	 * If the VTTBR isn't aligned there is something wrong with the system
-+	 * or kernel.
-+	 */
-+	BUG_ON(pgd_phys & ~vttbr_baddr_mask);
-+
-+	kvm->arch.vttbr = pgd_phys | vmid;
- 
- 	spin_unlock(&kvm_vmid_lock);
- }
-@@ -1015,6 +1028,12 @@ int kvm_arch_init(void *opaque)
- 		}
- 	}
- 
-+	vttbr_baddr_mask = get_vttbr_baddr_mask();
-+	if (vttbr_baddr_mask == ~0) {
-+		kvm_err("Cannot set vttbr_baddr_mask\n");
-+		return -EINVAL;
-+	}
-+
- 	cpu_notifier_register_begin();
- 
- 	err = init_hyp_mode();
-diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
-index 05e1f73..c186a17 100644
---- a/arch/arm/mach-integrator/pci_v3.c
-+++ b/arch/arm/mach-integrator/pci_v3.c
-@@ -660,6 +660,7 @@ static void __init pci_v3_preinit(void)
- {
- 	unsigned long flags;
- 	unsigned int temp;
-+	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
- 
- 	pcibios_min_mem = 0x00100000;
- 
-@@ -701,7 +702,7 @@ static void __init pci_v3_preinit(void)
- 	/*
- 	 * Setup window 2 - PCI IO
- 	 */
--	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) |
-+	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_address) |
- 			V3_LB_BASE_ENABLE);
- 	v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
- 
-@@ -742,6 +743,7 @@ static void __init pci_v3_preinit(void)
- static void __init pci_v3_postinit(void)
- {
- 	unsigned int pci_cmd;
-+	phys_addr_t io_address = pci_pio_to_address(io_mem.start);
- 
- 	pci_cmd = PCI_COMMAND_MEMORY |
- 		  PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
-@@ -758,7 +760,7 @@ static void __init pci_v3_postinit(void)
- 		       "interrupt: %d\n", ret);
- #endif
- 
--	register_isa_ports(non_mem.start, io_mem.start, 0);
-+	register_isa_ports(non_mem.start, io_address, 0);
- }
- 
- /*
-@@ -867,33 +869,32 @@ static int __init pci_v3_probe(struct platform_device *pdev)
- 
- 	for_each_of_pci_range(&parser, &range) {
- 		if (!range.flags) {
--			of_pci_range_to_resource(&range, np, &conf_mem);
-+			ret = of_pci_range_to_resource(&range, np, &conf_mem);
- 			conf_mem.name = "PCIv3 config";
- 		}
- 		if (range.flags & IORESOURCE_IO) {
--			of_pci_range_to_resource(&range, np, &io_mem);
-+			ret = of_pci_range_to_resource(&range, np, &io_mem);
- 			io_mem.name = "PCIv3 I/O";
- 		}
- 		if ((range.flags & IORESOURCE_MEM) &&
- 			!(range.flags & IORESOURCE_PREFETCH)) {
- 			non_mem_pci = range.pci_addr;
- 			non_mem_pci_sz = range.size;
--			of_pci_range_to_resource(&range, np, &non_mem);
-+			ret = of_pci_range_to_resource(&range, np, &non_mem);
- 			non_mem.name = "PCIv3 non-prefetched mem";
- 		}
- 		if ((range.flags & IORESOURCE_MEM) &&
- 			(range.flags & IORESOURCE_PREFETCH)) {
- 			pre_mem_pci = range.pci_addr;
- 			pre_mem_pci_sz = range.size;
--			of_pci_range_to_resource(&range, np, &pre_mem);
-+			ret = of_pci_range_to_resource(&range, np, &pre_mem);
- 			pre_mem.name = "PCIv3 prefetched mem";
- 		}
--	}
- 
--	if (!conf_mem.start || !io_mem.start ||
--	    !non_mem.start || !pre_mem.start) {
--		dev_err(&pdev->dev, "missing ranges in device node\n");
--		return -EINVAL;
-+		if (ret < 0) {
-+			dev_err(&pdev->dev, "missing ranges in device node\n");
-+			return ret;
-+		}
- 	}
- 
- 	pci_v3.map_irq = of_irq_parse_and_map_pci;
-diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
-index fd4e81a..e57b91a 100644
---- a/arch/arm64/Kconfig
-+++ b/arch/arm64/Kconfig
-@@ -1,5 +1,6 @@
- config ARM64
- 	def_bool y
-+	select ACPI_REDUCED_HARDWARE_ONLY if ACPI
- 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
- 	select ARCH_HAS_SG_CHAIN
- 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
-@@ -81,7 +82,7 @@ config MMU
- 	def_bool y
- 
- config NO_IOPORT_MAP
--	def_bool y
-+	def_bool y if !PCI
- 
- config STACKTRACE_SUPPORT
- 	def_bool y
-@@ -156,6 +157,26 @@ menu "Bus support"
- config ARM_AMBA
- 	bool
- 
-+config PCI
-+	bool "PCI support"
-+	help
-+	  This feature enables support for PCI bus system. If you say Y
-+	  here, the kernel will include drivers and infrastructure code
-+	  to support PCI bus devices.
-+
-+config PCI_DOMAINS
-+	def_bool PCI
-+
-+config PCI_DOMAINS_GENERIC
-+	def_bool PCI
-+
-+config PCI_SYSCALL
-+	def_bool PCI
-+
-+source "drivers/pci/Kconfig"
-+source "drivers/pci/pcie/Kconfig"
-+source "drivers/pci/hotplug/Kconfig"
-+
- endmenu
- 
- menu "Kernel Features"
-@@ -235,6 +256,9 @@ config SMP
- 
- 	  If you don't know what to do here, say N.
- 
-+config ARM_PARKING_PROTOCOL
-+	def_bool y if SMP
-+
- config SCHED_MC
- 	bool "Multi-core scheduler support"
- 	depends on SMP
-@@ -421,6 +445,8 @@ source "drivers/Kconfig"
- 
- source "drivers/firmware/Kconfig"
- 
-+source "drivers/acpi/Kconfig"
-+
- source "fs/Kconfig"
- 
- source "arch/arm64/kvm/Kconfig"
-diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
-index 2df5e5d..bddd4e3 100644
---- a/arch/arm64/Makefile
-+++ b/arch/arm64/Makefile
-@@ -50,6 +50,7 @@ core-y		+= arch/arm64/kernel/ arch/arm64/mm/
- core-$(CONFIG_KVM) += arch/arm64/kvm/
- core-$(CONFIG_XEN) += arch/arm64/xen/
- core-$(CONFIG_CRYPTO) += arch/arm64/crypto/
-+drivers-$(CONFIG_PCI)	+= arch/arm64/pci/
- libs-y		:= arch/arm64/lib/ $(libs-y)
- libs-y		+= $(LIBGCC)
- libs-$(CONFIG_EFI_STUB) += drivers/firmware/efi/libstub/
-diff --git a/arch/arm64/boot/dts/apm-mustang.dts b/arch/arm64/boot/dts/apm-mustang.dts
-index b2f5622..f649000 100644
---- a/arch/arm64/boot/dts/apm-mustang.dts
-+++ b/arch/arm64/boot/dts/apm-mustang.dts
-@@ -25,6 +25,14 @@
- 	};
- };
- 
-+&pcie0clk {
-+	status = "ok";
-+};
-+
-+&pcie0 {
-+	status = "ok";
-+};
-+
- &serial0 {
- 	status = "ok";
- };
-diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi
-index c0aceef..403197a 100644
---- a/arch/arm64/boot/dts/apm-storm.dtsi
-+++ b/arch/arm64/boot/dts/apm-storm.dtsi
-@@ -269,6 +269,171 @@
- 				enable-mask = <0x2>;
- 				clock-output-names = "rtcclk";
- 			};
-+
-+			pcie0clk: pcie0clk at 1f2bc000 {
-+				status = "disabled";
-+				compatible = "apm,xgene-device-clock";
-+				#clock-cells = <1>;
-+				clocks = <&socplldiv2 0>;
-+				reg = <0x0 0x1f2bc000 0x0 0x1000>;
-+				reg-names = "csr-reg";
-+				clock-output-names = "pcie0clk";
-+			};
-+
-+			pcie1clk: pcie1clk at 1f2cc000 {
-+				status = "disabled";
-+				compatible = "apm,xgene-device-clock";
-+				#clock-cells = <1>;
-+				clocks = <&socplldiv2 0>;
-+				reg = <0x0 0x1f2cc000 0x0 0x1000>;
-+				reg-names = "csr-reg";
-+				clock-output-names = "pcie1clk";
-+			};
-+
-+			pcie2clk: pcie2clk at 1f2dc000 {
-+				status = "disabled";
-+				compatible = "apm,xgene-device-clock";
-+				#clock-cells = <1>;
-+				clocks = <&socplldiv2 0>;
-+				reg = <0x0 0x1f2dc000 0x0 0x1000>;
-+				reg-names = "csr-reg";
-+				clock-output-names = "pcie2clk";
-+			};
-+
-+			pcie3clk: pcie3clk at 1f50c000 {
-+				status = "disabled";
-+				compatible = "apm,xgene-device-clock";
-+				#clock-cells = <1>;
-+				clocks = <&socplldiv2 0>;
-+				reg = <0x0 0x1f50c000 0x0 0x1000>;
-+				reg-names = "csr-reg";
-+				clock-output-names = "pcie3clk";
-+			};
-+
-+			pcie4clk: pcie4clk at 1f51c000 {
-+				status = "disabled";
-+				compatible = "apm,xgene-device-clock";
-+				#clock-cells = <1>;
-+				clocks = <&socplldiv2 0>;
-+				reg = <0x0 0x1f51c000 0x0 0x1000>;
-+				reg-names = "csr-reg";
-+				clock-output-names = "pcie4clk";
-+			};
-+		};
-+
-+		pcie0: pcie at 1f2b0000 {
-+			status = "disabled";
-+			device_type = "pci";
-+			compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie";
-+			#interrupt-cells = <1>;
-+			#size-cells = <2>;
-+			#address-cells = <3>;
-+			reg = < 0x00 0x1f2b0000 0x0 0x00010000   /* Controller registers */
-+				0xe0 0xd0000000 0x0 0x00040000>; /* PCI config space */
-+			reg-names = "csr", "cfg";
-+			ranges = <0x01000000 0x00 0x00000000 0xe0 0x10000000 0x00 0x00010000   /* io */
-+				  0x02000000 0x00 0x80000000 0xe1 0x80000000 0x00 0x80000000>; /* mem */
-+			dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
-+				      0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
-+			interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+			interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc2 0x1
-+					 0x0 0x0 0x0 0x2 &gic 0x0 0xc3 0x1
-+					 0x0 0x0 0x0 0x3 &gic 0x0 0xc4 0x1
-+					 0x0 0x0 0x0 0x4 &gic 0x0 0xc5 0x1>;
-+			dma-coherent;
-+			clocks = <&pcie0clk 0>;
-+		};
-+
-+		pcie1: pcie at 1f2c0000 {
-+			status = "disabled";
-+			device_type = "pci";
-+			compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie";
-+			#interrupt-cells = <1>;
-+			#size-cells = <2>;
-+			#address-cells = <3>;
-+			reg = < 0x00 0x1f2c0000 0x0 0x00010000   /* Controller registers */
-+				0xd0 0xd0000000 0x0 0x00040000>; /* PCI config space */
-+			reg-names = "csr", "cfg";
-+			ranges = <0x01000000 0x0 0x00000000 0xd0 0x10000000 0x00 0x00010000   /* io  */
-+				  0x02000000 0x0 0x80000000 0xd1 0x80000000 0x00 0x80000000>; /* mem */
-+			dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
-+				      0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
-+			interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+			interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc8 0x1
-+					 0x0 0x0 0x0 0x2 &gic 0x0 0xc9 0x1
-+					 0x0 0x0 0x0 0x3 &gic 0x0 0xca 0x1
-+					 0x0 0x0 0x0 0x4 &gic 0x0 0xcb 0x1>;
-+			dma-coherent;
-+			clocks = <&pcie1clk 0>;
-+		};
-+
-+		pcie2: pcie at 1f2d0000 {
-+			status = "disabled";
-+			device_type = "pci";
-+			compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie";
-+			#interrupt-cells = <1>;
-+			#size-cells = <2>;
-+			#address-cells = <3>;
-+			reg =  < 0x00 0x1f2d0000 0x0 0x00010000   /* Controller registers */
-+				 0x90 0xd0000000 0x0 0x00040000>; /* PCI config space */
-+			reg-names = "csr", "cfg";
-+			ranges = <0x01000000 0x0 0x00000000 0x90 0x10000000 0x0 0x00010000   /* io  */
-+				  0x02000000 0x0 0x80000000 0x91 0x80000000 0x0 0x80000000>; /* mem */
-+			dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
-+				      0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
-+			interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+			interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xce 0x1
-+					 0x0 0x0 0x0 0x2 &gic 0x0 0xcf 0x1
-+					 0x0 0x0 0x0 0x3 &gic 0x0 0xd0 0x1
-+					 0x0 0x0 0x0 0x4 &gic 0x0 0xd1 0x1>;
-+			dma-coherent;
-+			clocks = <&pcie2clk 0>;
-+		};
-+
-+		pcie3: pcie at 1f500000 {
-+			status = "disabled";
-+			device_type = "pci";
-+			compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie";
-+			#interrupt-cells = <1>;
-+			#size-cells = <2>;
-+			#address-cells = <3>;
-+			reg = < 0x00 0x1f500000 0x0 0x00010000   /* Controller registers */
-+				0xa0 0xd0000000 0x0 0x00040000>; /* PCI config space */
-+			reg-names = "csr", "cfg";
-+			ranges = <0x01000000 0x0 0x00000000 0xa0 0x10000000 0x0 0x00010000   /* io   */
-+				  0x02000000 0x0 0x80000000 0xa1 0x80000000 0x0 0x80000000>; /* mem  */
-+			dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
-+				      0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
-+			interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+			interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xd4 0x1
-+					 0x0 0x0 0x0 0x2 &gic 0x0 0xd5 0x1
-+					 0x0 0x0 0x0 0x3 &gic 0x0 0xd6 0x1
-+					 0x0 0x0 0x0 0x4 &gic 0x0 0xd7 0x1>;
-+			dma-coherent;
-+			clocks = <&pcie3clk 0>;
-+		};
-+
-+		pcie4: pcie at 1f510000 {
-+			status = "disabled";
-+			device_type = "pci";
-+			compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie";
-+			#interrupt-cells = <1>;
-+			#size-cells = <2>;
-+			#address-cells = <3>;
-+			reg = < 0x00 0x1f510000 0x0 0x00010000   /* Controller registers */
-+				0xc0 0xd0000000 0x0 0x00200000>; /* PCI config space */
-+			reg-names = "csr", "cfg";
-+			ranges = <0x01000000 0x0 0x00000000 0xc0 0x10000000 0x0 0x00010000   /* io  */
-+				  0x02000000 0x0 0x80000000 0xc1 0x80000000 0x0 0x80000000>; /* mem */
-+			dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
-+				      0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
-+			interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+			interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xda 0x1
-+					 0x0 0x0 0x0 0x2 &gic 0x0 0xdb 0x1
-+					 0x0 0x0 0x0 0x3 &gic 0x0 0xdc 0x1
-+					 0x0 0x0 0x0 0x4 &gic 0x0 0xdd 0x1>;
-+			dma-coherent;
-+			clocks = <&pcie4clk 0>;
- 		};
- 
- 		serial0: serial at 1c020000 {
-diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
-index 0b3fcf8..07cb417 100644
---- a/arch/arm64/include/asm/Kbuild
-+++ b/arch/arm64/include/asm/Kbuild
-@@ -29,6 +29,7 @@ generic-y += mman.h
- generic-y += msgbuf.h
- generic-y += mutex.h
- generic-y += pci.h
-+generic-y += pci-bridge.h
- generic-y += poll.h
- generic-y += preempt.h
- generic-y += resource.h
-diff --git a/arch/arm64/include/asm/acenv.h b/arch/arm64/include/asm/acenv.h
-new file mode 100644
-index 0000000..b49166f
---- /dev/null
-+++ b/arch/arm64/include/asm/acenv.h
-@@ -0,0 +1,18 @@
-+/*
-+ * ARM64 specific ACPICA environments and implementation
-+ *
-+ * Copyright (C) 2014, Linaro Ltd.
-+ *   Author: Hanjun Guo <hanjun.guo at linaro.org>
-+ *   Author: Graeme Gregory <graeme.gregory at linaro.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#ifndef _ASM_ACENV_H
-+#define _ASM_ACENV_H
-+
-+/* It is required unconditionally by ACPI core, update it when needed. */
++/* It is required unconditionally by ACPI core, update it when needed. */
 +
 +#endif /* _ASM_ACENV_H */
 diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
@@ -2250,16 +2017,16 @@ index 0000000..7f6cd91
 +
 +#endif /*_ASM_ACPI_H*/
 diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
-index d7b4b38..d149580 100644
+index 6f8e2ef..978f567 100644
 --- a/arch/arm64/include/asm/cpu_ops.h
 +++ b/arch/arm64/include/asm/cpu_ops.h
-@@ -61,6 +61,7 @@ struct cpu_operations {
+@@ -64,6 +64,7 @@ struct cpu_operations {
  };
  
  extern const struct cpu_operations *cpu_ops[NR_CPUS];
 +const struct cpu_operations *cpu_get_ops(const char *name);
- extern int __init cpu_read_ops(struct device_node *dn, int cpu);
- extern void __init cpu_read_bootcpu_ops(void);
+ int __init cpu_read_ops(struct device_node *dn, int cpu);
+ void __init cpu_read_bootcpu_ops(void);
  
 diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
 index 01d3aab..8186df6 100644
@@ -2275,222 +2042,6 @@ index 01d3aab..8186df6 100644
  
  #define CORE_DUMP_USE_REGSET
  #define ELF_EXEC_PAGESIZE	PAGE_SIZE
-diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
-index e0ecdcf..f998d90 100644
---- a/arch/arm64/include/asm/io.h
-+++ b/arch/arm64/include/asm/io.h
-@@ -121,7 +121,8 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
- /*
-  *  I/O port access primitives.
-  */
--#define IO_SPACE_LIMIT		0xffff
-+#define arch_has_dev_port()	(1)
-+#define IO_SPACE_LIMIT		(SZ_32M - 1)
- #define PCI_IOBASE		((void __iomem *)(MODULES_VADDR - SZ_32M))
- 
- static inline u8 inb(unsigned long addr)
-diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
-index cc83520..ff4a4fa 100644
---- a/arch/arm64/include/asm/kvm_arm.h
-+++ b/arch/arm64/include/asm/kvm_arm.h
-@@ -95,7 +95,6 @@
- /* TCR_EL2 Registers bits */
- #define TCR_EL2_TBI	(1 << 20)
- #define TCR_EL2_PS	(7 << 16)
--#define TCR_EL2_PS_40B	(2 << 16)
- #define TCR_EL2_TG0	(1 << 14)
- #define TCR_EL2_SH0	(3 << 12)
- #define TCR_EL2_ORGN0	(3 << 10)
-@@ -104,8 +103,6 @@
- #define TCR_EL2_MASK	(TCR_EL2_TG0 | TCR_EL2_SH0 | \
- 			 TCR_EL2_ORGN0 | TCR_EL2_IRGN0 | TCR_EL2_T0SZ)
- 
--#define TCR_EL2_FLAGS	(TCR_EL2_PS_40B)
--
- /* VTCR_EL2 Registers bits */
- #define VTCR_EL2_PS_MASK	(7 << 16)
- #define VTCR_EL2_TG0_MASK	(1 << 14)
-@@ -120,36 +117,28 @@
- #define VTCR_EL2_SL0_MASK	(3 << 6)
- #define VTCR_EL2_SL0_LVL1	(1 << 6)
- #define VTCR_EL2_T0SZ_MASK	0x3f
--#define VTCR_EL2_T0SZ_40B	24
-+#define VTCR_EL2_T0SZ(bits)	(64 - (bits))
- 
- #ifdef CONFIG_ARM64_64K_PAGES
- /*
-  * Stage2 translation configuration:
-- * 40bits output (PS = 2)
-- * 40bits input  (T0SZ = 24)
-  * 64kB pages (TG0 = 1)
-  * 2 level page tables (SL = 1)
-  */
- #define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_64K | VTCR_EL2_SH0_INNER | \
- 				 VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
--				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B)
--#define VTTBR_X		(38 - VTCR_EL2_T0SZ_40B)
-+				 VTCR_EL2_SL0_LVL1)
- #else
- /*
-  * Stage2 translation configuration:
-- * 40bits output (PS = 2)
-- * 40bits input  (T0SZ = 24)
-  * 4kB pages (TG0 = 0)
-  * 3 level page tables (SL = 1)
-  */
- #define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_4K | VTCR_EL2_SH0_INNER | \
- 				 VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
--				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B)
--#define VTTBR_X		(37 - VTCR_EL2_T0SZ_40B)
-+				 VTCR_EL2_SL0_LVL1)
- #endif
- 
--#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
--#define VTTBR_BADDR_MASK  (((1LLU << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
- #define VTTBR_VMID_SHIFT  (48LLU)
- #define VTTBR_VMID_MASK	  (0xffLLU << VTTBR_VMID_SHIFT)
- 
-diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
-index 8e138c7..1c70b2f 100644
---- a/arch/arm64/include/asm/kvm_mmu.h
-+++ b/arch/arm64/include/asm/kvm_mmu.h
-@@ -167,5 +167,80 @@ static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva,
- 
- void stage2_flush_vm(struct kvm *kvm);
- 
-+/*
-+ * ARMv8 64K architecture limitations:
-+ * 16 <= T0SZ <= 21 is valid under 3 level of translation tables
-+ * 18 <= T0SZ <= 34 is valid under 2 level of translation tables
-+ * 31 <= T0SZ <= 39 is valid under 1 level of transltaion tables
-+ *
-+ * ARMv8 4K architecture limitations:
-+ * 16 <= T0SZ <= 24 is valid under 4 level of translation tables
-+ * 21 <= T0SZ <= 33 is valid under 3 level of translation tables
-+ * 30 <= T0SZ <= 39 is valid under 2 level of translation tables
-+ *
-+ * For 4K pages we only support 3 or 4 level, giving T0SZ a range of 16 to 33.
-+ * For 64K pages we only support 2 or 3 level, giving T0SZ a range of 16 to 34.
-+ *
-+ * See Table D4-23 and Table D4-25 in ARM DDI 0487A.b to figure out
-+ * the origin of the hardcoded values, 38 and 37.
-+ */
-+
-+#ifdef CONFIG_ARM64_64K_PAGES
-+static inline int t0sz_to_vttbr_x(int t0sz)
-+{
-+	if (t0sz < 16 || t0sz > 34) {
-+		kvm_err("Cannot support %d-bit address space\n", 64 - t0sz);
-+		return -EINVAL;
-+	}
-+
-+	return 38 - t0sz;
-+}
-+#else /* 4K pages */
-+static inline int t0sz_to_vttbr_x(int t0sz)
-+{
-+	if (t0sz < 16 || t0sz > 33) {
-+		kvm_err("Cannot support %d-bit address space\n", 64 - t0sz);
-+		return -EINVAL;
-+	}
-+	return 37 - t0sz;
-+}
-+#endif
-+static inline int kvm_get_phys_addr_shift(void)
-+{
-+	int pa_range = read_cpuid(ID_AA64MMFR0_EL1) & 0xf;
-+
-+	switch (pa_range) {
-+	case 0: return 32;
-+	case 1: return 36;
-+	case 2: return 40;
-+	case 3: return 42;
-+	case 4: return 44;
-+	case 5: return 48;
-+	default:
-+		BUG();
-+		return 0;
-+	}
-+}
-+
-+/**
-+ * get_vttbr_baddr_mask - get mask value for vttbr base address
-+ *
-+ * In ARMv8, vttbr_baddr_mask cannot be determined in compile time since the
-+ * stage2 input address size depends on hardware capability. Thus, we first
-+ * need to read ID_AA64MMFR0_EL1.PARange and then set vttbr_baddr_mask with
-+ * consideration of both the granule size and the level of translation tables.
-+ */
-+static inline u64 get_vttbr_baddr_mask(void)
-+{
-+	int t0sz, vttbr_x;
-+
-+	t0sz = VTCR_EL2_T0SZ(kvm_get_phys_addr_shift());
-+	vttbr_x = t0sz_to_vttbr_x(t0sz);
-+	if (vttbr_x < 0)
-+		return ~0;
-+	return GENMASK_ULL(48, (vttbr_x - 1));
-+
-+}
-+
- #endif /* __ASSEMBLY__ */
- #endif /* __ARM64_KVM_MMU_H__ */
-diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
-new file mode 100644
-index 0000000..872ba93
---- /dev/null
-+++ b/arch/arm64/include/asm/pci.h
-@@ -0,0 +1,37 @@
-+#ifndef __ASM_PCI_H
-+#define __ASM_PCI_H
-+#ifdef __KERNEL__
-+
-+#include <linux/types.h>
-+#include <linux/slab.h>
-+#include <linux/dma-mapping.h>
-+
-+#include <asm/io.h>
-+#include <asm-generic/pci-bridge.h>
-+#include <asm-generic/pci-dma-compat.h>
-+
-+#define PCIBIOS_MIN_IO		0x1000
-+#define PCIBIOS_MIN_MEM		0
-+
-+/*
-+ * Set to 1 if the kernel should re-assign all PCI bus numbers
-+ */
-+#define pcibios_assign_all_busses() \
-+	(pci_has_flag(PCI_REASSIGN_ALL_BUS))
-+
-+/*
-+ * PCI address space differs from physical memory address space
-+ */
-+#define PCI_DMA_BUS_IS_PHYS	(0)
-+
-+extern int isa_dma_bridge_buggy;
-+
-+#ifdef CONFIG_PCI
-+static inline int pci_proc_domain(struct pci_bus *bus)
-+{
-+	return 1;
-+}
-+#endif  /* CONFIG_PCI */
-+
-+#endif  /* __KERNEL__ */
-+#endif  /* __ASM_PCI_H */
-diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
-index ffe1ba0..a968523 100644
---- a/arch/arm64/include/asm/pgtable.h
-+++ b/arch/arm64/include/asm/pgtable.h
-@@ -296,6 +296,8 @@ static inline int has_transparent_hugepage(void)
- 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
- #define pgprot_writecombine(prot) \
- 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
-+#define pgprot_device(prot) \
-+	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
- #define __HAVE_PHYS_MEM_ACCESS_PROT
- struct file;
- extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 diff --git a/arch/arm64/include/asm/psci.h b/arch/arm64/include/asm/psci.h
 index e5312ea..2454bc5 100644
 --- a/arch/arm64/include/asm/psci.h
@@ -2505,7 +2056,7 @@ index e5312ea..2454bc5 100644
  
  #endif /* __ASM_PSCI_H */
 diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
-index a498f2c..2ebbd55 100644
+index 780f82c..3411561 100644
 --- a/arch/arm64/include/asm/smp.h
 +++ b/arch/arm64/include/asm/smp.h
 @@ -39,9 +39,10 @@ extern void show_ipi_list(struct seq_file *p, int prec);
@@ -2521,8 +2072,8 @@ index a498f2c..2ebbd55 100644
  
  /*
   * Provide a function to raise an IPI cross call on CPUs in callmap.
-@@ -49,6 +50,11 @@ extern void smp_init_cpus(void);
- extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int));
+@@ -51,6 +52,11 @@ extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int));
+ extern void (*__smp_cross_call)(const struct cpumask *, unsigned int);
  
  /*
 + * Provide a function to signal a parked secondary CPU.
@@ -2534,7 +2085,7 @@ index a498f2c..2ebbd55 100644
   */
  asmlinkage void secondary_start_kernel(void);
 diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
-index df7ef87..b0bad2e 100644
+index 5bd029b..f4ba4fe 100644
 --- a/arch/arm64/kernel/Makefile
 +++ b/arch/arm64/kernel/Makefile
 @@ -21,7 +21,8 @@ arm64-obj-$(CONFIG_COMPAT)		+= sys32.o kuser32.o signal32.o 	\
@@ -2547,11 +2098,10 @@ index df7ef87..b0bad2e 100644
  arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
  arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
  arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
-@@ -29,6 +30,8 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
- arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
+@@ -31,6 +32,7 @@ arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
  arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
  arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
-+arm64-obj-$(CONFIG_PCI)			+= pci.o
+ arm64-obj-$(CONFIG_PCI)			+= pci.o
 +arm64-obj-$(CONFIG_ACPI)		+= acpi.o
  
  obj-y					+= $(arm64-obj-y) vdso/
@@ -2989,37 +2539,6 @@ index cce9524..1d90f31 100644
  {
  	const struct cpu_operations **ops = supported_cpu_ops;
  
-diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c
-index 1317fef..d27dd98 100644
---- a/arch/arm64/kernel/efi-stub.c
-+++ b/arch/arm64/kernel/efi-stub.c
-@@ -28,20 +28,16 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
- 	kernel_size = _edata - _text;
- 	if (*image_addr != (dram_base + TEXT_OFFSET)) {
- 		kernel_memsize = kernel_size + (_end - _edata);
--		status = efi_relocate_kernel(sys_table, image_addr,
--					     kernel_size, kernel_memsize,
--					     dram_base + TEXT_OFFSET,
--					     PAGE_SIZE);
-+		status = efi_low_alloc(sys_table, kernel_memsize + TEXT_OFFSET,
-+				       SZ_2M, reserve_addr);
- 		if (status != EFI_SUCCESS) {
- 			pr_efi_err(sys_table, "Failed to relocate kernel\n");
- 			return status;
- 		}
--		if (*image_addr != (dram_base + TEXT_OFFSET)) {
--			pr_efi_err(sys_table, "Failed to alloc kernel memory\n");
--			efi_free(sys_table, kernel_memsize, *image_addr);
--			return EFI_LOAD_ERROR;
--		}
--		*image_size = kernel_memsize;
-+		memcpy((void *)*reserve_addr + TEXT_OFFSET, (void *)*image_addr,
-+		       kernel_size);
-+		*image_addr = *reserve_addr + TEXT_OFFSET;
-+		*reserve_size = kernel_memsize + TEXT_OFFSET;
- 	}
- 
- 
 diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
 index 03aaa99..6c4de44 100644
 --- a/arch/arm64/kernel/efi.c
@@ -3039,115 +2558,8 @@ index 03aaa99..6c4de44 100644
 +{
 +	return pm_power_off == NULL;
 +}
-diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
-index 8730690..0a6e4f9 100644
---- a/arch/arm64/kernel/head.S
-+++ b/arch/arm64/kernel/head.S
-@@ -151,7 +151,7 @@ optional_header:
- 	.short	0x20b				// PE32+ format
- 	.byte	0x02				// MajorLinkerVersion
- 	.byte	0x14				// MinorLinkerVersion
--	.long	_edata - stext			// SizeOfCode
-+	.long	_end - stext			// SizeOfCode
- 	.long	0				// SizeOfInitializedData
- 	.long	0				// SizeOfUninitializedData
- 	.long	efi_stub_entry - efi_head	// AddressOfEntryPoint
-@@ -169,7 +169,7 @@ extra_header_fields:
- 	.short	0				// MinorSubsystemVersion
- 	.long	0				// Win32VersionValue
- 
--	.long	_edata - efi_head		// SizeOfImage
-+	.long	_end - efi_head			// SizeOfImage
- 
- 	// Everything before the kernel image is considered part of the header
- 	.long	stext - efi_head		// SizeOfHeaders
-@@ -216,7 +216,7 @@ section_table:
- 	.byte	0
- 	.byte	0
- 	.byte	0        		// end of 0 padding of section name
--	.long	_edata - stext		// VirtualSize
-+	.long	_end - stext		// VirtualSize
- 	.long	stext - efi_head	// VirtualAddress
- 	.long	_edata - stext		// SizeOfRawData
- 	.long	stext - efi_head	// PointerToRawData
-diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
-new file mode 100644
-index 0000000..ce5836c
---- /dev/null
-+++ b/arch/arm64/kernel/pci.c
-@@ -0,0 +1,70 @@
-+/*
-+ * Code borrowed from powerpc/kernel/pci-common.c
-+ *
-+ * Copyright (C) 2003 Anton Blanchard <anton at au.ibm.com>, IBM
-+ * Copyright (C) 2014 ARM Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * version 2 as published by the Free Software Foundation.
-+ *
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/io.h>
-+#include <linux/kernel.h>
-+#include <linux/mm.h>
-+#include <linux/of_pci.h>
-+#include <linux/of_platform.h>
-+#include <linux/slab.h>
-+
-+#include <asm/pci-bridge.h>
-+
-+/*
-+ * Called after each bus is probed, but before its children are examined
-+ */
-+void pcibios_fixup_bus(struct pci_bus *bus)
-+{
-+	/* nothing to do, expected to be removed in the future */
-+}
-+
-+/*
-+ * We don't have to worry about legacy ISA devices, so nothing to do here
-+ */
-+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
-+				resource_size_t size, resource_size_t align)
-+{
-+	return res->start;
-+}
-+
-+/*
-+ * Try to assign the IRQ number from DT when adding a new device
-+ */
-+int pcibios_add_device(struct pci_dev *dev)
-+{
-+	dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
-+
-+	return 0;
-+}
-+
-+
-+#ifdef CONFIG_PCI_DOMAINS_GENERIC
-+static bool dt_domain_found = false;
-+
-+void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
-+{
-+	int domain = of_get_pci_domain_nr(parent->of_node);
-+
-+	if (domain >= 0) {
-+		dt_domain_found = true;
-+	} else if (dt_domain_found == true) {
-+		dev_err(parent, "Node %s is missing \"linux,pci-domain\" property in DT\n",
-+			parent->of_node->full_name);
-+		return;
-+	} else {
-+		domain = pci_get_new_domain_nr();
-+	}
-+
-+	bus->domain_nr = domain;
-+}
-+#endif
 diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
-index 29d4869..c0427bc 100644
+index c3065db..99edd1f 100644
 --- a/arch/arm64/kernel/process.c
 +++ b/arch/arm64/kernel/process.c
 @@ -43,6 +43,7 @@
@@ -3158,8 +2570,8 @@ index 29d4869..c0427bc 100644
  
  #include <asm/compat.h>
  #include <asm/cacheflush.h>
-@@ -182,6 +183,11 @@ void machine_restart(char *cmd)
- 		arm_pm_restart(reboot_mode, cmd);
+@@ -157,6 +158,11 @@ void machine_restart(char *cmd)
+ 		do_kernel_restart(cmd);
  
  	/*
 +	 * If all else fails, try EFI
@@ -3171,7 +2583,7 @@ index 29d4869..c0427bc 100644
  	 */
  	printk("Reboot failed -- System halted\n");
 diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
-index 5539547..15ba470 100644
+index 866c1c8..f8a981e 100644
 --- a/arch/arm64/kernel/psci.c
 +++ b/arch/arm64/kernel/psci.c
 @@ -15,6 +15,7 @@
@@ -3182,15 +2594,15 @@ index 5539547..15ba470 100644
  #include <linux/init.h>
  #include <linux/of.h>
  #include <linux/smp.h>
-@@ -23,6 +24,7 @@
- #include <linux/delay.h>
+@@ -24,6 +25,7 @@
+ #include <linux/slab.h>
  #include <uapi/linux/psci.h>
  
 +#include <asm/acpi.h>
  #include <asm/compiler.h>
  #include <asm/cpu_ops.h>
  #include <asm/errno.h>
-@@ -231,6 +233,33 @@ static void psci_sys_poweroff(void)
+@@ -304,6 +306,33 @@ static void psci_sys_poweroff(void)
  	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
  }
  
@@ -3224,7 +2636,7 @@ index 5539547..15ba470 100644
  /*
   * PSCI Function IDs for v0.2+ are well defined so use
   * standard values.
-@@ -264,29 +293,7 @@ static int __init psci_0_2_init(struct device_node *np)
+@@ -337,29 +366,7 @@ static int __init psci_0_2_init(struct device_node *np)
  		}
  	}
  
@@ -3255,7 +2667,7 @@ index 5539547..15ba470 100644
  
  out_put_node:
  	of_node_put(np);
-@@ -339,7 +346,7 @@ static const struct of_device_id psci_of_match[] __initconst = {
+@@ -412,7 +419,7 @@ static const struct of_device_id psci_of_match[] __initconst = {
  	{},
  };
  
@@ -3264,7 +2676,7 @@ index 5539547..15ba470 100644
  {
  	struct device_node *np;
  	const struct of_device_id *matched_np;
-@@ -354,6 +361,29 @@ int __init psci_init(void)
+@@ -427,6 +434,29 @@ int __init psci_init(void)
  	return init_fn(np);
  }
  
@@ -3295,7 +2707,7 @@ index 5539547..15ba470 100644
  
  static int __init cpu_psci_cpu_init(struct device_node *dn, unsigned int cpu)
 diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
-index edb146d..a793a20 100644
+index 2437196..c1144a1 100644
 --- a/arch/arm64/kernel/setup.c
 +++ b/arch/arm64/kernel/setup.c
 @@ -43,6 +43,7 @@
@@ -3317,9 +2729,9 @@ index edb146d..a793a20 100644
  
  unsigned int processor_id;
  EXPORT_SYMBOL(processor_id);
-@@ -385,22 +390,34 @@ void __init setup_arch(char **cmdline_p)
- 
- 	parse_early_param();
+@@ -386,22 +391,34 @@ void __init setup_arch(char **cmdline_p)
+ 	 */
+ 	local_async_enable();
  
 +	if (acpi_disabled)
 +		disable_acpi();
@@ -3358,7 +2770,7 @@ index edb146d..a793a20 100644
  	smp_build_mpidr_hash();
  #endif
  
-@@ -413,6 +430,19 @@ void __init setup_arch(char **cmdline_p)
+@@ -414,6 +431,19 @@ void __init setup_arch(char **cmdline_p)
  #endif
  }
  
@@ -3378,7 +2790,7 @@ index edb146d..a793a20 100644
  static int __init arm64_device_init(void)
  {
  	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-@@ -505,3 +535,25 @@ const struct seq_operations cpuinfo_op = {
+@@ -506,3 +536,25 @@ const struct seq_operations cpuinfo_op = {
  	.stop	= c_stop,
  	.show	= c_show
  };
@@ -3405,7 +2817,7 @@ index edb146d..a793a20 100644
 +}
 +early_initcall(arm64_console_setup);
 diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
-index 4743397..4e390ac 100644
+index b06d1d9..2988829 100644
 --- a/arch/arm64/kernel/smp.c
 +++ b/arch/arm64/kernel/smp.c
 @@ -321,7 +321,7 @@ void __init smp_prepare_boot_cpu(void)
@@ -3533,74 +2945,17 @@ index 0000000..e1153ce
 +	.cpu_prepare	= smp_parking_protocol_cpu_prepare,
 +	.cpu_boot	= smp_parking_protocol_cpu_boot,
 +};
-diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c
-index 0347d38..4f93c67 100644
---- a/arch/arm64/kernel/smp_spin_table.c
-+++ b/arch/arm64/kernel/smp_spin_table.c
-@@ -20,6 +20,7 @@
- #include <linux/init.h>
- #include <linux/of.h>
- #include <linux/smp.h>
-+#include <linux/types.h>
+diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
+index 1a7125c..42f9195 100644
+--- a/arch/arm64/kernel/time.c
++++ b/arch/arm64/kernel/time.c
+@@ -35,6 +35,7 @@
+ #include <linux/delay.h>
+ #include <linux/clocksource.h>
+ #include <linux/clk-provider.h>
++#include <linux/acpi.h>
  
- #include <asm/cacheflush.h>
- #include <asm/cpu_ops.h>
-@@ -65,12 +66,21 @@ static int smp_spin_table_cpu_init(struct device_node *dn, unsigned int cpu)
- 
- static int smp_spin_table_cpu_prepare(unsigned int cpu)
- {
--	void **release_addr;
-+	__le64 __iomem *release_addr;
- 
- 	if (!cpu_release_addr[cpu])
- 		return -ENODEV;
- 
--	release_addr = __va(cpu_release_addr[cpu]);
-+	/*
-+	 * The cpu-release-addr may or may not be inside the linear mapping.
-+	 * As ioremap_cache will either give us a new mapping or reuse the
-+	 * existing linear mapping, we can use it to cover both cases. In
-+	 * either case the memory will be MT_NORMAL.
-+	 */
-+	release_addr = ioremap_cache(cpu_release_addr[cpu],
-+				     sizeof(*release_addr));
-+	if (!release_addr)
-+		return -ENOMEM;
- 
- 	/*
- 	 * We write the release address as LE regardless of the native
-@@ -79,15 +89,17 @@ static int smp_spin_table_cpu_prepare(unsigned int cpu)
- 	 * boot-loader's endianess before jumping. This is mandated by
- 	 * the boot protocol.
- 	 */
--	release_addr[0] = (void *) cpu_to_le64(__pa(secondary_holding_pen));
--
--	__flush_dcache_area(release_addr, sizeof(release_addr[0]));
-+	writeq_relaxed(__pa(secondary_holding_pen), release_addr);
-+	__flush_dcache_area((__force void *)release_addr,
-+			    sizeof(*release_addr));
- 
- 	/*
- 	 * Send an event to wake up the secondary CPU.
- 	 */
- 	sev();
- 
-+	iounmap(release_addr);
-+
- 	return 0;
- }
- 
-diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
-index 1a7125c..42f9195 100644
---- a/arch/arm64/kernel/time.c
-+++ b/arch/arm64/kernel/time.c
-@@ -35,6 +35,7 @@
- #include <linux/delay.h>
- #include <linux/clocksource.h>
- #include <linux/clk-provider.h>
-+#include <linux/acpi.h>
- 
- #include <clocksource/arm_arch_timer.h>
+ #include <clocksource/arm_arch_timer.h>
  
 @@ -72,6 +73,12 @@ void __init time_init(void)
  
@@ -3615,99 +2970,36 @@ index 1a7125c..42f9195 100644
  	arch_timer_rate = arch_timer_get_rate();
  	if (!arch_timer_rate)
  		panic("Unable to initialise architected timer.\n");
-diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
-index c319116..fa7e67e 100644
---- a/arch/arm64/kvm/hyp-init.S
-+++ b/arch/arm64/kvm/hyp-init.S
-@@ -63,17 +63,21 @@ __do_hyp_init:
- 	mrs	x4, tcr_el1
- 	ldr	x5, =TCR_EL2_MASK
- 	and	x4, x4, x5
--	ldr	x5, =TCR_EL2_FLAGS
--	orr	x4, x4, x5
--	msr	tcr_el2, x4
--
--	ldr	x4, =VTCR_EL2_FLAGS
- 	/*
- 	 * Read the PARange bits from ID_AA64MMFR0_EL1 and set the PS bits in
--	 * VTCR_EL2.
-+	 * TCR_EL2 and both PS bits and T0SZ bits in VTCR_EL2.
- 	 */
- 	mrs	x5, ID_AA64MMFR0_EL1
- 	bfi	x4, x5, #16, #3
-+	msr	tcr_el2, x4
-+
-+	ldr	x4, =VTCR_EL2_FLAGS
-+	bfi	x4, x5, #16, #3
-+	and	x5, x5, #0xf
-+	adr	x6, t0sz
-+	add	x6, x6, x5, lsl #2
-+	ldr	w5, [x6]
-+	orr	x4, x4, x5
- 	msr	vtcr_el2, x4
- 
- 	mrs	x4, mair_el1
-@@ -113,6 +117,10 @@ target: /* We're now in the trampoline code, switch page tables */
- 
- 	/* Hello, World! */
- 	eret
-+
-+t0sz:
-+	.word	VTCR_EL2_T0SZ(32), VTCR_EL2_T0SZ(36), VTCR_EL2_T0SZ(40)
-+	.word	VTCR_EL2_T0SZ(42), VTCR_EL2_T0SZ(44), VTCR_EL2_T0SZ(48)
- ENDPROC(__kvm_hyp_init)
- 
- 	.ltorg
 diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
-index 4164c5a..b864a24 100644
+index d920942..fda70ab 100644
 --- a/arch/arm64/mm/dma-mapping.c
 +++ b/arch/arm64/mm/dma-mapping.c
-@@ -23,10 +23,13 @@
+@@ -23,8 +23,14 @@
+ #include <linux/genalloc.h>
  #include <linux/dma-mapping.h>
  #include <linux/dma-contiguous.h>
- #include <linux/of.h>
++#include <linux/of.h>
 +#include <linux/of_address.h>
- #include <linux/platform_device.h>
++#include <linux/platform_device.h>
  #include <linux/vmalloc.h>
  #include <linux/swiotlb.h>
- #include <linux/amba/bus.h>
++#include <linux/amba/bus.h>
 +#include <linux/acpi.h>
 +#include <linux/pci.h>
  
  #include <asm/cacheflush.h>
  
-@@ -319,6 +322,63 @@ static int dma_bus_notifier(struct notifier_block *nb,
- 	if (of_property_read_bool(dev->of_node, "dma-coherent"))
- 		set_dma_ops(dev, &coherent_swiotlb_dma_ops);
+@@ -423,10 +429,107 @@ out:
+ 	return -ENOMEM;
+ }
  
-+#ifdef CONFIG_ACPI
-+	else if (ACPI_HANDLE(dev)) {
-+		acpi_status status;
-+		int coherent;
-+
-+		/*
-+		 * Kernel defaults to noncoherent ops but ACPI 5.1 spec says arm64
-+		 * defaults to coherent. Set coherent ops if _CCA not found or _CCA
-+		 * found and non-zero.
-+		 */
-+		status =  acpi_check_coherency(ACPI_HANDLE(dev), &coherent);
-+		if (ACPI_FAILURE(status) || coherent)
-+			set_dma_ops(dev, &coherent_swiotlb_dma_ops);
-+	}
-+#endif
-+	return NOTIFY_OK;
-+}
-+
-+static int dma_bus_notifier_pci(struct notifier_block *nb,
-+				unsigned long event, void *_dev)
++#ifdef CONFIG_PCI
++static void arm64_of_set_dma_ops(void *_dev)
 +{
 +	struct device *dev = _dev;
 +
-+	if (event != BUS_NOTIFY_ADD_DEVICE)
-+		return NOTIFY_DONE;
-+
 +	/*
-+	 * PCI devices won't have an of_node but the bridge will.
++	 * PCI devices won't have an ACPI handle but the bridge will.
 +	 * Search up the device chain until we find an of_node
 +	 * to check.
 +	 */
@@ -3717,48 +3009,94 @@ index 4164c5a..b864a24 100644
 +				set_dma_ops(_dev, &coherent_swiotlb_dma_ops);
 +			break;
 +		}
++		dev = dev->parent;
++	}
++}
++#else
++static inline arm64_of_set_dma_ops(void *_dev) {}
++#endif
++
++
 +#ifdef CONFIG_ACPI
++static void arm64_acpi_set_dma_ops(void *_dev)
++{
++	struct device *dev = _dev;
++
++	/*
++	 * Kernel defaults to noncoherent ops but ACPI 5.1 spec says arm64
++	 * defaults to coherent. Set coherent ops if _CCA not found or _CCA
++	 * found and non-zero.
++	 *
++	 * PCI devices won't have an of_node but the bridge will.
++	 * Search up the device chain until we find an ACPI handle
++	 * to check.
++	 */
++	while (dev) {
 +		if (ACPI_HANDLE(dev)) {
 +			acpi_status status;
 +			int coherent;
-+
-+			/*
-+			 * Kernel defaults to noncoherent ops but ACPI 5.1 spec says arm64
-+			 * defaults to coherent. Set coherent ops if _CCA not found or _CCA
-+			 * found and non-zero.
-+			 */
-+			status =  acpi_check_coherency(ACPI_HANDLE(dev), &coherent);
-+			if (ACPI_FAILURE(status) || coherent) {
++			status =  acpi_check_coherency(ACPI_HANDLE(dev),
++						       &coherent);
++			if (ACPI_FAILURE(status) || coherent)
 +				set_dma_ops(dev, &coherent_swiotlb_dma_ops);
-+				break;
-+			}
++			break;
 +		}
-+#endif
 +		dev = dev->parent;
 +	}
++}
++#else
++static inline arm64_acpi_set_dma_ops(void *_dev) {}
++#endif
 +
- 	return NOTIFY_OK;
- }
- 
-@@ -330,6 +390,10 @@ static struct notifier_block amba_bus_nb = {
- 	.notifier_call = dma_bus_notifier,
- };
- 
++static int dma_bus_notifier(struct notifier_block *nb,
++			    unsigned long event, void *_dev)
++{
++	if (event != BUS_NOTIFY_ADD_DEVICE)
++		return NOTIFY_DONE;
++
++	if (acpi_disabled)
++		arm64_of_set_dma_ops(_dev);
++	else
++		arm64_acpi_set_dma_ops(_dev);
++
++	return NOTIFY_OK;
++}
++
++#ifdef CONFIG_ACPI
++static struct notifier_block platform_bus_nb = {
++	.notifier_call = dma_bus_notifier,
++};
++
++static struct notifier_block amba_bus_nb = {
++	.notifier_call = dma_bus_notifier,
++};
++#endif
++
++#ifdef CONFIG_PCI
 +static struct notifier_block pci_bus_nb = {
-+	.notifier_call = dma_bus_notifier_pci,
++	.notifier_call = dma_bus_notifier,
 +};
++#endif
 +
- extern int swiotlb_late_init_with_default_size(size_t default_size);
- 
  static int __init swiotlb_late_init(void)
-@@ -341,6 +405,7 @@ static int __init swiotlb_late_init(void)
- 	 */
- 	bus_register_notifier(&platform_bus_type, &platform_bus_nb);
- 	bus_register_notifier(&amba_bustype, &amba_bus_nb);
-+	bus_register_notifier(&pci_bus_type, &pci_bus_nb);
+ {
+ 	size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT);
  
++	/*
++	 * These must be registered before of_platform_populate().
++	 */
++#ifdef CONFIG_ACPI
++	bus_register_notifier(&platform_bus_type, &platform_bus_nb);
++	bus_register_notifier(&amba_bustype, &amba_bus_nb);
++#endif
++
++#ifdef CONFIG_PCI
++	bus_register_notifier(&pci_bus_type, &pci_bus_nb);
++#endif
++
  	dma_ops = &noncoherent_swiotlb_dma_ops;
  
+ 	return swiotlb_late_init_with_default_size(swiotlb_size);
 diff --git a/arch/arm64/pci/Makefile b/arch/arm64/pci/Makefile
 new file mode 100644
 index 0000000..b8d5dbd
@@ -3832,7 +3170,7 @@ index d0f3265..3343080 100644
  	help
  	  This driver creates entries in /sys/bus/pci/slots/ for all PCI
 diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
-index 505d4d7..6f3a74d 100644
+index 505d4d7..252d0ff 100644
 --- a/drivers/acpi/Makefile
 +++ b/drivers/acpi/Makefile
 @@ -23,7 +23,11 @@ acpi-y				+= nvs.o
@@ -3847,7 +3185,7 @@ index 505d4d7..6f3a74d 100644
  acpi-y				+= device_pm.o
  acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o
  
-@@ -39,7 +43,7 @@ acpi-y				+= processor_core.o
+@@ -39,13 +43,14 @@ acpi-y				+= processor_core.o
  acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o
  acpi-y				+= ec.o
  acpi-$(CONFIG_ACPI_DOCK)	+= dock.o
@@ -3856,21 +3194,13 @@ index 505d4d7..6f3a74d 100644
  acpi-y				+= acpi_lpss.o
  acpi-y				+= acpi_platform.o
  acpi-y				+= acpi_pnp.o
-diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c
-index 14cb6c0..5cd017c 100644
---- a/drivers/acpi/acpica/utresrc.c
-+++ b/drivers/acpi/acpica/utresrc.c
-@@ -87,7 +87,9 @@ const char *acpi_gbl_io_decode[] = {
- 
- const char *acpi_gbl_ll_decode[] = {
- 	"ActiveHigh",
--	"ActiveLow"
-+	"ActiveLow",
-+	"ActiveBoth",
-+	"Reserved"
- };
- 
- const char *acpi_gbl_max_decode[] = {
+ acpi-y				+= power.o
+ acpi-y				+= event.o
+ acpi-y				+= sysfs.o
++acpi-y				+= property.o
+ acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
+ acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
+ acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
 index 8b67bd0..c412fdb 100644
 --- a/drivers/acpi/bus.c
@@ -3886,7 +3216,7 @@ index 8b67bd0..c412fdb 100644
  		message = "platform specific model";
  		break;
 diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
-index 4c5cf77..e1e6487 100644
+index 4c5cf77..926ca5c 100644
 --- a/drivers/acpi/internal.h
 +++ b/drivers/acpi/internal.h
 @@ -26,8 +26,13 @@
@@ -3903,11 +3233,22 @@ index 4c5cf77..e1e6487 100644
  void acpi_processor_init(void);
  void acpi_platform_init(void);
  void acpi_pnp_init(void);
+@@ -181,4 +186,10 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev);
+ bool acpi_osi_is_win8(void);
+ #endif
+ 
++/*--------------------------------------------------------------------------
++				Device properties
++  -------------------------------------------------------------------------- */
++void acpi_init_properties(struct acpi_device *adev);
++void acpi_free_properties(struct acpi_device *adev);
++
+ #endif /* _ACPI_INTERNAL_H_ */
 diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
-index 3abe9b2..c50757b 100644
+index 9964f70..5c480d5 100644
 --- a/drivers/acpi/osl.c
 +++ b/drivers/acpi/osl.c
-@@ -326,11 +326,11 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
+@@ -336,11 +336,11 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
  	return NULL;
  }
  
@@ -3923,7 +3264,7 @@ index 3abe9b2..c50757b 100644
  
  static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz)
 diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
-index e32321c..4007313 100644
+index ef58f46..5c84e0d 100644
 --- a/drivers/acpi/processor_core.c
 +++ b/drivers/acpi/processor_core.c
 @@ -64,6 +64,38 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
@@ -3984,2747 +3325,5402 @@ index e32321c..4007313 100644
  	}
  
  exit:
-diff --git a/drivers/acpi/sleep-arm.c b/drivers/acpi/sleep-arm.c
+diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
 new file mode 100644
-index 0000000..54578ef
+index 0000000..ff53eb8
 --- /dev/null
-+++ b/drivers/acpi/sleep-arm.c
-@@ -0,0 +1,28 @@
++++ b/drivers/acpi/property.c
+@@ -0,0 +1,586 @@
 +/*
-+ *  ARM64 Specific Sleep Functionality
++ * ACPI device specific properties support.
 + *
-+ *  Copyright (C) 2013-2014, Linaro Ltd.
-+ *      Author: Graeme Gregory <graeme.gregory at linaro.org>
++ * Copyright (C) 2014, Intel Corporation
++ * All rights reserved.
 + *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License version 2 as
-+ *  published by the Free Software Foundation.
++ * Authors: Mika Westerberg <mika.westerberg at linux.intel.com>
++ *          Darren Hart <dvhart at linux.intel.com>
++ *          Rafael J. Wysocki <rafael.j.wysocki at intel.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
 + */
 +
 +#include <linux/acpi.h>
++#include <linux/device.h>
++#include <linux/export.h>
 +
-+/*
-+ * Currently the ACPI 5.1 standard does not define S states in a
-+ * manner which is usable for ARM64. These two stubs are sufficient
-+ * that system initialises and device PM works.
-+ */
-+u32 acpi_target_system_state(void)
++#include "internal.h"
++
++/* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
++static const u8 prp_uuid[16] = {
++	0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
++	0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
++};
++
++static bool acpi_property_value_ok(const union acpi_object *value)
 +{
-+	return ACPI_STATE_S0;
++	int j;
++
++	/*
++	 * The value must be an integer, a string, a reference, or a package
++	 * whose every element must be an integer, a string, or a reference.
++	 */
++	switch (value->type) {
++	case ACPI_TYPE_INTEGER:
++	case ACPI_TYPE_STRING:
++	case ACPI_TYPE_LOCAL_REFERENCE:
++		return true;
++
++	case ACPI_TYPE_PACKAGE:
++		for (j = 0; j < value->package.count; j++)
++			switch (value->package.elements[j].type) {
++			case ACPI_TYPE_INTEGER:
++			case ACPI_TYPE_STRING:
++			case ACPI_TYPE_LOCAL_REFERENCE:
++				continue;
++
++			default:
++				return false;
++			}
++
++		return true;
++	}
++	return false;
 +}
-+EXPORT_SYMBOL_GPL(acpi_target_system_state);
 +
-+int __init acpi_sleep_init(void)
++static bool acpi_properties_format_valid(const union acpi_object *properties)
 +{
-+	return -ENOSYS;
++	int i;
++
++	for (i = 0; i < properties->package.count; i++) {
++		const union acpi_object *property;
++
++		property = &properties->package.elements[i];
++		/*
++		 * Only two elements allowed, the first one must be a string and
++		 * the second one has to satisfy certain conditions.
++		 */
++		if (property->package.count != 2
++		    || property->package.elements[0].type != ACPI_TYPE_STRING
++		    || !acpi_property_value_ok(&property->package.elements[1]))
++			return false;
++	}
++	return true;
 +}
-diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
-index 6d5a6cd..47f36d4 100644
---- a/drivers/acpi/tables.c
-+++ b/drivers/acpi/tables.c
-@@ -183,6 +183,49 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
- 		}
- 		break;
- 
-+	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
-+		{
-+			struct acpi_madt_generic_interrupt *p =
-+				(struct acpi_madt_generic_interrupt *)header;
-+			pr_info("GICC (acpi_id[0x%04x] address[%p] MPDIR[0x%llx] %s)\n",
-+				p->uid, (void *)(unsigned long)p->base_address,
-+				p->arm_mpidr,
-+				(p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
 +
-+		}
-+		break;
++static void acpi_init_of_compatible(struct acpi_device *adev)
++{
++	const union acpi_object *of_compatible;
++	struct acpi_hardware_id *hwid;
++	bool acpi_of = false;
 +
-+	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
-+		{
-+			struct acpi_madt_generic_distributor *p =
-+				(struct acpi_madt_generic_distributor *)header;
-+			pr_info("GIC Distributor (gic_id[0x%04x] address[%p] gsi_base[%d])\n",
-+				p->gic_id,
-+				(void *)(unsigned long)p->base_address,
-+				p->global_irq_base);
++	/*
++	 * Check if the special PRP0001 ACPI ID is present and in that
++	 * case we fill in Device Tree compatible properties for this
++	 * device.
++	 */
++	list_for_each_entry(hwid, &adev->pnp.ids, list) {
++		if (!strcmp(hwid->id, "PRP0001")) {
++			acpi_of = true;
++			break;
 +		}
-+		break;
++	}
 +
-+	case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
-+		{
-+			struct acpi_madt_generic_msi_frame *p =
-+				(struct acpi_madt_generic_msi_frame *)header;
-+			pr_info("GIC MSI Frame (msi_fame_id[%d] address[%p])\n",
-+				p->msi_frame_id,
-+				(void *)(unsigned long)p->base_address);
-+		}
-+		break;
++	if (!acpi_of)
++		return;
 +
-+	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
-+		{
-+			struct acpi_madt_generic_redistributor *p =
-+				(struct acpi_madt_generic_redistributor *)header;
-+			pr_info("GIC Redistributor (address[%p] region_size[0x%x])\n",
-+				(void *)(unsigned long)p->base_address,
-+				p->length);
-+		}
-+		break;
++	if (acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING,
++					&of_compatible)) {
++		acpi_handle_warn(adev->handle,
++				 "PRP0001 requires compatible property\n");
++		return;
++	}
 +
- 	default:
- 		pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
- 			header->type);
-@@ -192,17 +235,14 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
- 
- 
- int __init
--acpi_table_parse_entries(char *id,
--			     unsigned long table_size,
--			     int entry_id,
--			     acpi_tbl_entry_handler handler,
--			     unsigned int max_entries)
-+acpi_parse_entries(unsigned long table_size,
-+		acpi_tbl_entry_handler handler,
-+		struct acpi_table_header *table_header,
-+		int entry_id, unsigned int max_entries)
- {
--	struct acpi_table_header *table_header = NULL;
- 	struct acpi_subtable_header *entry;
--	unsigned int count = 0;
-+	int count = 0;
- 	unsigned long table_end;
--	acpi_size tbl_size;
- 
- 	if (acpi_disabled)
- 		return -ENODEV;
-@@ -210,13 +250,11 @@ acpi_table_parse_entries(char *id,
- 	if (!handler)
- 		return -EINVAL;
- 
--	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
--		acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
--	else
--		acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
-+	if (!table_size)
-+		return -EINVAL;
- 
- 	if (!table_header) {
--		pr_warn("%4.4s not present\n", id);
-+		pr_warn("Table header not present\n");
- 		return -ENODEV;
- 	}
- 
-@@ -230,32 +268,67 @@ acpi_table_parse_entries(char *id,
- 	while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
- 	       table_end) {
- 		if (entry->type == entry_id
--		    && (!max_entries || count++ < max_entries))
-+		    && (!max_entries || count < max_entries)) {
- 			if (handler(entry, table_end))
--				goto err;
-+				return -EINVAL;
++	adev->data.of_compatible = of_compatible;
++}
 +
-+			count++;
-+		}
- 
- 		/*
- 		 * If entry->length is 0, break from this loop to avoid
- 		 * infinite loop.
- 		 */
- 		if (entry->length == 0) {
--			pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
--			goto err;
-+			pr_err("[0x%02x] Invalid zero length\n", entry_id);
-+			return -EINVAL;
- 		}
- 
- 		entry = (struct acpi_subtable_header *)
- 		    ((unsigned long)entry + entry->length);
- 	}
++void acpi_init_properties(struct acpi_device *adev)
++{
++	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
++	const union acpi_object *desc;
++	acpi_status status;
++	int i;
 +
- 	if (max_entries && count > max_entries) {
- 		pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n",
--			id, entry_id, count - max_entries, count);
-+			table_header->signature, entry_id, count - max_entries,
-+			count);
- 	}
- 
--	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
- 	return count;
--err:
++	status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf,
++					    ACPI_TYPE_PACKAGE);
++	if (ACPI_FAILURE(status))
++		return;
++
++	desc = buf.pointer;
++	if (desc->package.count % 2)
++		goto fail;
++
++	/* Look for the device properties UUID. */
++	for (i = 0; i < desc->package.count; i += 2) {
++		const union acpi_object *uuid, *properties;
++
++		uuid = &desc->package.elements[i];
++		properties = &desc->package.elements[i + 1];
++
++		/*
++		 * The first element must be a UUID and the second one must be
++		 * a package.
++		 */
++		if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16
++		    || properties->type != ACPI_TYPE_PACKAGE)
++			break;
++
++		if (memcmp(uuid->buffer.pointer, prp_uuid, sizeof(prp_uuid)))
++			continue;
++
++		/*
++		 * We found the matching UUID. Now validate the format of the
++		 * package immediately following it.
++		 */
++		if (!acpi_properties_format_valid(properties))
++			break;
++
++		adev->data.pointer = buf.pointer;
++		adev->data.properties = properties;
++
++		acpi_init_of_compatible(adev);
++		return;
++	}
++
++ fail:
++	dev_warn(&adev->dev, "Returned _DSD data is not valid, skipping\n");
++	ACPI_FREE(buf.pointer);
 +}
 +
-+int __init
-+acpi_table_parse_entries(char *id,
-+			 unsigned long table_size,
-+			 int entry_id,
-+			 acpi_tbl_entry_handler handler,
-+			 unsigned int max_entries)
++void acpi_free_properties(struct acpi_device *adev)
 +{
-+	struct acpi_table_header *table_header = NULL;
-+	acpi_size tbl_size;
-+	int count;
++	ACPI_FREE((void *)adev->data.pointer);
++	adev->data.of_compatible = NULL;
++	adev->data.pointer = NULL;
++	adev->data.properties = NULL;
++}
 +
-+	if (acpi_disabled)
-+		return -ENODEV;
++/**
++ * acpi_dev_get_property - return an ACPI property with given name
++ * @adev: ACPI device to get property
++ * @name: Name of the property
++ * @type: Expected property type
++ * @obj: Location to store the property value (if not %NULL)
++ *
++ * Look up a property with @name and store a pointer to the resulting ACPI
++ * object at the location pointed to by @obj if found.
++ *
++ * Callers must not attempt to free the returned objects.  These objects will be
++ * freed by the ACPI core automatically during the removal of @adev.
++ *
++ * Return: %0 if property with @name has been found (success),
++ *         %-EINVAL if the arguments are invalid,
++ *         %-ENODATA if the property doesn't exist,
++ *         %-EPROTO if the property value type doesn't match @type.
++ */
++int acpi_dev_get_property(struct acpi_device *adev, const char *name,
++			  acpi_object_type type, const union acpi_object **obj)
++{
++	const union acpi_object *properties;
++	int i;
 +
-+	if (!handler)
++	if (!adev || !name)
 +		return -EINVAL;
 +
-+	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
-+		acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
-+	else
-+		acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
++	if (!adev->data.pointer || !adev->data.properties)
++		return -ENODATA;
 +
-+	if (!table_header) {
-+		pr_warn("%4.4s not present\n", id);
-+		return -ENODEV;
++	properties = adev->data.properties;
++	for (i = 0; i < properties->package.count; i++) {
++		const union acpi_object *propname, *propvalue;
++		const union acpi_object *property;
++
++		property = &properties->package.elements[i];
++
++		propname = &property->package.elements[0];
++		propvalue = &property->package.elements[1];
++
++		if (!strcmp(name, propname->string.pointer)) {
++			if (type != ACPI_TYPE_ANY && propvalue->type != type)
++				return -EPROTO;
++			else if (obj)
++				*obj = propvalue;
++
++			return 0;
++		}
 +	}
++	return -ENODATA;
++}
++EXPORT_SYMBOL_GPL(acpi_dev_get_property);
 +
-+	count = acpi_parse_entries(table_size, handler, table_header,
-+			entry_id, max_entries);
++/**
++ * acpi_dev_get_property_array - return an ACPI array property with given name
++ * @adev: ACPI device to get property
++ * @name: Name of the property
++ * @type: Expected type of array elements
++ * @obj: Location to store a pointer to the property value (if not NULL)
++ *
++ * Look up an array property with @name and store a pointer to the resulting
++ * ACPI object at the location pointed to by @obj if found.
++ *
++ * Callers must not attempt to free the returned objects.  Those objects will be
++ * freed by the ACPI core automatically during the removal of @adev.
++ *
++ * Return: %0 if array property (package) with @name has been found (success),
++ *         %-EINVAL if the arguments are invalid,
++ *         %-ENODATA if the property doesn't exist,
++ *         %-EPROTO if the property is not a package or the type of its elements
++ *           doesn't match @type.
++ */
++int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
++				acpi_object_type type,
++				const union acpi_object **obj)
++{
++	const union acpi_object *prop;
++	int ret, i;
 +
- 	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
--	return -EINVAL;
-+	return count;
- }
- 
- int __init
-diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
-index 07c8c5a..aec9656 100644
---- a/drivers/acpi/utils.c
-+++ b/drivers/acpi/utils.c
-@@ -698,3 +698,29 @@ bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs)
- 	return false;
- }
- EXPORT_SYMBOL(acpi_check_dsm);
++	ret = acpi_dev_get_property(adev, name, ACPI_TYPE_PACKAGE, &prop);
++	if (ret)
++		return ret;
++
++	if (type != ACPI_TYPE_ANY) {
++		/* Check that all elements are of correct type. */
++		for (i = 0; i < prop->package.count; i++)
++			if (prop->package.elements[i].type != type)
++				return -EPROTO;
++	}
++	if (obj)
++		*obj = prop;
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(acpi_dev_get_property_array);
 +
 +/**
-+ * acpi_check_coherency - check for memory coherency of a device
-+ * @handle: ACPI device handle
-+ * @val:    Pointer to returned value
++ * acpi_dev_get_property_reference - returns handle to the referenced object
++ * @adev: ACPI device to get property
++ * @name: Name of the property
++ * @size_prop: Name of the "size" property in referenced object
++ * @index: Index of the reference to return
++ * @args: Location to store the returned reference with optional arguments
 + *
-+ * Search a device and its parents for a _CCA method and return
-+ * its value.
++ * Find property with @name, verifify that it is a package containing at least
++ * one object reference and if so, store the ACPI device object pointer to the
++ * target object in @args->adev.
++ *
++ * If the reference includes arguments (@size_prop is not %NULL) follow the
++ * reference and check whether or not there is an integer property @size_prop
++ * under the target object and if so, whether or not its value matches the
++ * number of arguments that follow the reference.  If there's more than one
++ * reference in the property value package, @index is used to select the one to
++ * return.
++ *
++ * Return: %0 on success, negative error code on failure.
 + */
-+acpi_status acpi_check_coherency(acpi_handle handle, int *val)
++int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name,
++				    const char *size_prop, size_t index,
++				    struct acpi_reference_args *args)
 +{
-+	unsigned long long data;
-+	acpi_status status;
++	const union acpi_object *element, *end;
++	const union acpi_object *obj;
++	struct acpi_device *device;
++	int ret, idx = 0;
 +
-+	do {
-+		status = acpi_evaluate_integer(handle, "_CCA", NULL, &data);
-+		if (!ACPI_FAILURE(status)) {
-+			*val = data;
++	ret = acpi_dev_get_property(adev, name, ACPI_TYPE_ANY, &obj);
++	if (ret)
++		return ret;
++
++	/*
++	 * The simplest case is when the value is a single reference.  Just
++	 * return that reference then.
++	 */
++	if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
++		if (size_prop || index)
++			return -EINVAL;
++
++		ret = acpi_bus_get_device(obj->reference.handle, &device);
++		if (ret)
++			return ret;
++
++		args->adev = device;
++		args->nargs = 0;
++		return 0;
++	}
++
++	/*
++	 * If it is not a single reference, then it is a package of
++	 * references followed by number of ints as follows:
++	 *
++	 *  Package () { REF, INT, REF, INT, INT }
++	 *
++	 * The index argument is then used to determine which reference
++	 * the caller wants (along with the arguments).
++	 */
++	if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count)
++		return -EPROTO;
++
++	element = obj->package.elements;
++	end = element + obj->package.count;
++
++	while (element < end) {
++		u32 nargs, i;
++
++		if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
++			return -EPROTO;
++
++		ret = acpi_bus_get_device(element->reference.handle, &device);
++		if (ret)
++			return -ENODEV;
++
++		element++;
++		nargs = 0;
++
++		if (size_prop) {
++			const union acpi_object *prop;
++
++			/*
++			 * Find out how many arguments the refenced object
++			 * expects by reading its size_prop property.
++			 */
++			ret = acpi_dev_get_property(device, size_prop,
++						    ACPI_TYPE_INTEGER, &prop);
++			if (ret)
++				return ret;
++
++			nargs = prop->integer.value;
++			if (nargs > MAX_ACPI_REFERENCE_ARGS
++			    || element + nargs > end)
++				return -EPROTO;
++
++			/*
++			 * Skip to the start of the arguments and verify
++			 * that they all are in fact integers.
++			 */
++			for (i = 0; i < nargs; i++)
++				if (element[i].type != ACPI_TYPE_INTEGER)
++					return -EPROTO;
++		} else {
++			/* assume following integer elements are all args */
++			for (i = 0; element + i < end; i++) {
++				int type = element[i].type;
++
++				if (type == ACPI_TYPE_INTEGER)
++					nargs++;
++				else if (type == ACPI_TYPE_LOCAL_REFERENCE)
++					break;
++				else
++					return -EPROTO;
++			}
++		}
++
++		if (idx++ == index) {
++			args->adev = device;
++			args->nargs = nargs;
++			for (i = 0; i < nargs; i++)
++				args->args[i] = element[i].integer.value;
++
++			return 0;
++		}
++
++		element += nargs;
++	}
++
++	return -EPROTO;
++}
++EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference);
++
++int acpi_dev_prop_get(struct acpi_device *adev, const char *propname,
++		      void **valptr)
++{
++	return acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY,
++				     (const union acpi_object **)valptr);
++}
++
++int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
++		       enum dev_prop_type proptype, void *val)
++{
++	const union acpi_object *obj;
++	int ret = -EINVAL;
++
++	if (!val)
++		return -EINVAL;
++
++	if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
++		ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_INTEGER, &obj);
++		if (ret)
++			return ret;
++
++		switch (proptype) {
++		case DEV_PROP_U8:
++			if (obj->integer.value > U8_MAX)
++				return -EOVERFLOW;
++			*(u8 *)val = obj->integer.value;
++			break;
++		case DEV_PROP_U16:
++			if (obj->integer.value > U16_MAX)
++				return -EOVERFLOW;
++			*(u16 *)val = obj->integer.value;
++			break;
++		case DEV_PROP_U32:
++			if (obj->integer.value > U32_MAX)
++				return -EOVERFLOW;
++			*(u32 *)val = obj->integer.value;
++			break;
++		default:
++			*(u64 *)val = obj->integer.value;
 +			break;
 +		}
-+		status = acpi_get_parent(handle, &handle);
-+	} while (!ACPI_FAILURE(status));
++	} else if (proptype == DEV_PROP_STRING) {
++		ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_STRING, &obj);
++		if (ret)
++			return ret;
 +
-+	return status;
++		*(char **)val = obj->string.pointer;
++	}
++	return ret;
 +}
-+EXPORT_SYMBOL(acpi_check_coherency);
-diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
-index e1b9278..f2e6c9e 100644
---- a/drivers/ata/Kconfig
-+++ b/drivers/ata/Kconfig
-@@ -48,7 +48,7 @@ config ATA_VERBOSE_ERROR
- 
- config ATA_ACPI
- 	bool "ATA ACPI Support"
--	depends on ACPI && PCI
-+	depends on ACPI
- 	default y
- 	help
- 	  This option adds support for ATA-related ACPI objects.
-diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
-index f61ddb9..3499bab 100644
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -20,6 +20,9 @@
- #include <linux/platform_device.h>
- #include <linux/libata.h>
- #include <linux/ahci_platform.h>
-+#ifdef CONFIG_ATA_ACPI
-+#include <linux/acpi.h>
-+#endif
- #include "ahci.h"
- 
- static const struct ata_port_info ahci_port_info = {
-@@ -87,6 +90,13 @@ static const struct of_device_id ahci_of_match[] = {
- };
- MODULE_DEVICE_TABLE(of, ahci_of_match);
- 
-+#ifdef CONFIG_ATA_ACPI
-+static const struct acpi_device_id ahci_acpi_match[] = {
-+	{ "AMDI0600", 0 }, /* AMD Seattle AHCI */
-+	{ },
-+};
-+#endif
 +
- static struct platform_driver ahci_driver = {
- 	.probe = ahci_probe,
- 	.remove = ata_platform_remove_one,
-@@ -94,6 +104,9 @@ static struct platform_driver ahci_driver = {
- 		.name = "ahci",
- 		.owner = THIS_MODULE,
- 		.of_match_table = ahci_of_match,
-+#ifdef CONFIG_ATA_ACPI
-+		.acpi_match_table = ACPI_PTR(ahci_acpi_match),
-+#endif
- 		.pm = &ahci_pm_ops,
- 	},
- };
-diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
-index f03aab1..b02ba9d 100644
---- a/drivers/ata/ahci_xgene.c
-+++ b/drivers/ata/ahci_xgene.c
-@@ -28,6 +28,7 @@
- #include <linux/of_address.h>
- #include <linux/of_irq.h>
- #include <linux/phy/phy.h>
-+#include <linux/acpi.h>
- #include "ahci.h"
- 
- /* Max # of disk per a controller */
-@@ -137,7 +138,8 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc)
- 	struct xgene_ahci_context *ctx = hpriv->plat_data;
- 	int rc = 0;
- 
--	if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA))
-+	if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA ||
-+		     ctx->last_cmd[ap->port_no] == ATA_CMD_SMART))
- 		xgene_ahci_restart_engine(ap);
- 
- 	rc = ahci_qc_issue(qc);
-@@ -148,14 +150,6 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc)
- 	return rc;
- }
- 
--static bool xgene_ahci_is_memram_inited(struct xgene_ahci_context *ctx)
--{
--	void __iomem *diagcsr = ctx->csr_diag;
--
--	return (readl(diagcsr + CFG_MEM_RAM_SHUTDOWN) == 0 &&
--	        readl(diagcsr + BLOCK_MEM_RDY) == 0xFFFFFFFF);
--}
--
- /**
-  * xgene_ahci_read_id - Read ID data from the specified device
-  * @dev: device
-@@ -495,11 +489,6 @@ static int xgene_ahci_probe(struct platform_device *pdev)
- 		return -ENODEV;
- 	}
- 
--	if (xgene_ahci_is_memram_inited(ctx)) {
--		dev_info(dev, "skip clock and PHY initialization\n");
--		goto skip_clk_phy;
--	}
--
- 	/* Due to errata, HW requires full toggle transition */
- 	rc = ahci_platform_enable_clks(hpriv);
- 	if (rc)
-@@ -512,7 +501,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
- 
- 	/* Configure the host controller */
- 	xgene_ahci_hw_init(hpriv);
--skip_clk_phy:
++static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val,
++				       size_t nval)
++{
++	int i;
 +
- 	hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_NCQ;
- 
- 	rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info);
-@@ -527,6 +516,16 @@ disable_resources:
- 	return rc;
- }
- 
-+#ifdef CONFIG_ACPI
-+static const struct acpi_device_id xgene_ahci_acpi_match[] = {
-+	{ "APMC0D00", },
-+	{ "APMC0D0D", },
-+	{ "APMC0D09", },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(acpi, xgene_ahci_acpi_match);
-+#endif
++	for (i = 0; i < nval; i++) {
++		if (items[i].type != ACPI_TYPE_INTEGER)
++			return -EPROTO;
++		if (items[i].integer.value > U8_MAX)
++			return -EOVERFLOW;
 +
- static const struct of_device_id xgene_ahci_of_match[] = {
- 	{.compatible = "apm,xgene-ahci"},
- 	{},
-@@ -540,6 +539,7 @@ static struct platform_driver xgene_ahci_driver = {
- 		.name = "xgene-ahci",
- 		.owner = THIS_MODULE,
- 		.of_match_table = xgene_ahci_of_match,
-+		.acpi_match_table = ACPI_PTR(xgene_ahci_acpi_match),
- 	},
- };
- 
-diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
-index 5163ec1..1bec05b 100644
---- a/drivers/clocksource/arm_arch_timer.c
-+++ b/drivers/clocksource/arm_arch_timer.c
-@@ -21,6 +21,7 @@
- #include <linux/io.h>
- #include <linux/slab.h>
- #include <linux/sched_clock.h>
-+#include <linux/acpi.h>
- 
- #include <asm/arch_timer.h>
- #include <asm/virt.h>
-@@ -61,7 +62,8 @@ enum ppi_nr {
- 	MAX_TIMER_PPI
- };
- 
--static int arch_timer_ppi[MAX_TIMER_PPI];
-+int arch_timer_ppi[MAX_TIMER_PPI];
-+EXPORT_SYMBOL(arch_timer_ppi);
- 
- static struct clock_event_device __percpu *arch_timer_evt;
- 
-@@ -338,8 +340,12 @@ arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
- 	if (arch_timer_rate)
- 		return;
- 
--	/* Try to determine the frequency from the device tree or CNTFRQ */
--	if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
-+	/*
-+	 * Try to determine the frequency from the device tree or CNTFRQ,
-+	 * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
-+	 */
-+	if (!acpi_disabled ||
-+	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
- 		if (cntbase)
- 			arch_timer_rate = readl_relaxed(cntbase + CNTFRQ);
- 		else
-@@ -635,20 +641,8 @@ static void __init arch_timer_common_init(void)
- 	arch_timer_arch_init();
- }
- 
--static void __init arch_timer_init(struct device_node *np)
-+static void __init arch_timer_init(void)
- {
--	int i;
--
--	if (arch_timers_present & ARCH_CP15_TIMER) {
--		pr_warn("arch_timer: multiple nodes in dt, skipping\n");
--		return;
--	}
--
--	arch_timers_present |= ARCH_CP15_TIMER;
--	for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
--		arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
--	arch_timer_detect_rate(NULL, np);
--
- 	/*
- 	 * If HYP mode is available, we know that the physical timer
- 	 * has been configured to be accessible from PL1. Use it, so
-@@ -667,13 +661,31 @@ static void __init arch_timer_init(struct device_node *np)
- 		}
- 	}
- 
--	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
--
- 	arch_timer_register();
- 	arch_timer_common_init();
- }
--CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_init);
--CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_init);
++		val[i] = items[i].integer.value;
++	}
++	return 0;
++}
 +
-+static void __init arch_timer_of_init(struct device_node *np)
++static int acpi_copy_property_array_u16(const union acpi_object *items,
++					u16 *val, size_t nval)
 +{
 +	int i;
 +
-+	if (arch_timers_present & ARCH_CP15_TIMER) {
-+		pr_warn("arch_timer: multiple nodes in dt, skipping\n");
-+		return;
-+	}
++	for (i = 0; i < nval; i++) {
++		if (items[i].type != ACPI_TYPE_INTEGER)
++			return -EPROTO;
++		if (items[i].integer.value > U16_MAX)
++			return -EOVERFLOW;
 +
-+	arch_timers_present |= ARCH_CP15_TIMER;
-+	for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
-+		arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
++		val[i] = items[i].integer.value;
++	}
++	return 0;
++}
 +
-+	arch_timer_detect_rate(NULL, np);
++static int acpi_copy_property_array_u32(const union acpi_object *items,
++					u32 *val, size_t nval)
++{
++	int i;
 +
-+	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
++	for (i = 0; i < nval; i++) {
++		if (items[i].type != ACPI_TYPE_INTEGER)
++			return -EPROTO;
++		if (items[i].integer.value > U32_MAX)
++			return -EOVERFLOW;
 +
-+	arch_timer_init();
++		val[i] = items[i].integer.value;
++	}
++	return 0;
 +}
-+CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init);
-+CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init);
- 
- static void __init arch_timer_mem_init(struct device_node *np)
- {
-@@ -740,3 +752,71 @@ static void __init arch_timer_mem_init(struct device_node *np)
- }
- CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem",
- 		       arch_timer_mem_init);
 +
-+#ifdef CONFIG_ACPI
-+static int __init
-+map_generic_timer_interrupt(u32 interrupt, u32 flags)
++static int acpi_copy_property_array_u64(const union acpi_object *items,
++					u64 *val, size_t nval)
 +{
-+	int trigger, polarity;
++	int i;
 +
-+	if (!interrupt)
-+		return 0;
++	for (i = 0; i < nval; i++) {
++		if (items[i].type != ACPI_TYPE_INTEGER)
++			return -EPROTO;
 +
-+	trigger = (flags & ACPI_GTDT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE
-+			: ACPI_LEVEL_SENSITIVE;
++		val[i] = items[i].integer.value;
++	}
++	return 0;
++}
 +
-+	polarity = (flags & ACPI_GTDT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW
-+			: ACPI_ACTIVE_HIGH;
++static int acpi_copy_property_array_string(const union acpi_object *items,
++					   char **val, size_t nval)
++{
++	int i;
 +
-+	return acpi_register_gsi(NULL, interrupt, trigger, polarity);
++	for (i = 0; i < nval; i++) {
++		if (items[i].type != ACPI_TYPE_STRING)
++			return -EPROTO;
++
++		val[i] = items[i].string.pointer;
++	}
++	return 0;
 +}
 +
-+/* Initialize per-processor generic timer */
-+static int __init arch_timer_acpi_init(struct acpi_table_header *table)
++int acpi_dev_prop_read_array(struct acpi_device *adev, const char *propname,
++			     enum dev_prop_type proptype, void *val,
++			     size_t nval)
 +{
-+	struct acpi_table_gtdt *gtdt;
++	const union acpi_object *obj;
++	const union acpi_object *items;
++	int ret;
 +
-+	if (arch_timers_present & ARCH_CP15_TIMER) {
-+		pr_warn("arch_timer: already initialized, skipping\n");
-+		return -EINVAL;
++	ret = acpi_dev_get_property_array(adev, propname, ACPI_TYPE_ANY, &obj);
++	if (ret)
++		return ret;
++
++	if (!val)
++		return obj->package.count;
++
++	if (nval > obj->package.count)
++		nval = obj->package.count;
++
++	items = obj->package.elements;
++	switch (proptype) {
++	case DEV_PROP_U8:
++		ret = acpi_copy_property_array_u8(items, (u8 *)val, nval);
++		break;
++	case DEV_PROP_U16:
++		ret = acpi_copy_property_array_u16(items, (u16 *)val, nval);
++		break;
++	case DEV_PROP_U32:
++		ret = acpi_copy_property_array_u32(items, (u32 *)val, nval);
++		break;
++	case DEV_PROP_U64:
++		ret = acpi_copy_property_array_u64(items, (u64 *)val, nval);
++		break;
++	case DEV_PROP_STRING:
++		ret = acpi_copy_property_array_string(items, (char **)val, nval);
++		break;
++	default:
++		ret = -EINVAL;
++		break;
 +	}
++	return ret;
++}
 +
-+	gtdt = container_of(table, struct acpi_table_gtdt, header);
++int acpi_for_each_child_node(struct device *dev,
++			int (*fn)(struct device *dev, void *child, void *data),
++			void *data)
++{
++	struct acpi_device *adev = ACPI_COMPANION(dev);
++	struct acpi_device *child;
++	int ret = 0;
 +
-+	arch_timers_present |= ARCH_CP15_TIMER;
++	if (!adev)
++		return -EINVAL;
 +
-+	arch_timer_ppi[PHYS_SECURE_PPI] =
-+		map_generic_timer_interrupt(gtdt->secure_el1_interrupt,
-+		gtdt->secure_el1_flags);
++	list_for_each_entry(child, &adev->children, node) {
++		ret = fn(dev, child, data);
++		if (ret)
++			break;
++	}
++	return ret;
++}
+diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
+index ae44d86..4da55d8 100644
+--- a/drivers/acpi/scan.c
++++ b/drivers/acpi/scan.c
+@@ -124,17 +124,43 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
+ 	if (list_empty(&acpi_dev->pnp.ids))
+ 		return 0;
+ 
+-	len = snprintf(modalias, size, "acpi:");
+-	size -= len;
++	/*
++	 * If the device has PRP0001 we expose DT compatible modalias
++	 * instead.
++	 */
++	if (acpi_dev->data.of_compatible) {
++		const union acpi_object *of_compatible, *obj;
++		int i;
++
++		len = snprintf(modalias, size, "of:Nprp0001Tacpi");
++
++		of_compatible = acpi_dev->data.of_compatible;
++		for (i = 0; i < of_compatible->package.count; i++) {
++			obj = &of_compatible->package.elements[i];
+ 
+-	list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
+-		count = snprintf(&modalias[len], size, "%s:", id->id);
+-		if (count < 0)
+-			return -EINVAL;
+-		if (count >= size)
+-			return -ENOMEM;
+-		len += count;
+-		size -= count;
++			count = snprintf(&modalias[len], size, "C%s",
++					 obj->string.pointer);
++			if (count < 0)
++				return -EINVAL;
++			if (count >= size)
++				return -ENOMEM;
 +
-+	arch_timer_ppi[PHYS_NONSECURE_PPI] =
-+		map_generic_timer_interrupt(gtdt->non_secure_el1_interrupt,
-+		gtdt->non_secure_el1_flags);
++			len += count;
++			size -= count;
++		}
++	} else {
++		len = snprintf(modalias, size, "acpi:");
++		size -= len;
 +
-+	arch_timer_ppi[VIRT_PPI] =
-+		map_generic_timer_interrupt(gtdt->virtual_timer_interrupt,
-+		gtdt->virtual_timer_flags);
++		list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
++			count = snprintf(&modalias[len], size, "%s:", id->id);
++			if (count < 0)
++				return -EINVAL;
++			if (count >= size)
++				return -ENOMEM;
++			len += count;
++			size -= count;
++		}
+ 	}
+ 
+ 	modalias[len] = '\0';
+@@ -864,6 +890,51 @@ int acpi_match_device_ids(struct acpi_device *device,
+ }
+ EXPORT_SYMBOL(acpi_match_device_ids);
+ 
++/* Performs match for special "PRP0001" shoehorn ACPI ID */
++static bool acpi_of_driver_match_device(struct device *dev,
++					const struct device_driver *drv)
++{
++	struct acpi_device *adev = ACPI_COMPANION(dev);
++	const union acpi_object *of_compatible;
++	int i;
 +
-+	arch_timer_ppi[HYP_PPI] =
-+		map_generic_timer_interrupt(gtdt->non_secure_el2_interrupt,
-+		gtdt->non_secure_el2_flags);
++	/*
++	 * If the ACPI device does not have corresponding compatible
++	 * property or the driver in question does not have DT matching
++	 * table we consider the match succesful (matches the ACPI ID).
++	 */
++	of_compatible = adev->data.of_compatible;
++	if (!drv->of_match_table || !of_compatible)
++		return true;
 +
-+	/* Get the frequency from CNTFRQ */
-+	arch_timer_detect_rate(NULL, NULL);
++	/* Now we can look for the driver DT compatible strings */
++	for (i = 0; i < of_compatible->package.count; i++) {
++		const struct of_device_id *id;
++		const union acpi_object *obj;
 +
-+	/* Always-on capability */
-+	arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON);
++		obj = &of_compatible->package.elements[i];
 +
-+	arch_timer_init();
-+	return 0;
++		for (id = drv->of_match_table; id->compatible[0]; id++)
++			if (!strcasecmp(obj->string.pointer, id->compatible))
++				return true;
++	}
++
++	return false;
 +}
 +
-+/* Initialize all the generic timers presented in GTDT */
-+void __init acpi_generic_timer_init(void)
++bool acpi_driver_match_device(struct device *dev,
++			      const struct device_driver *drv)
 +{
-+	if (acpi_disabled)
-+		return;
++	const struct acpi_device_id *id;
 +
-+	acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
-+}
-+#endif
-diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
-index a0698b4..d2da911 100644
---- a/drivers/irqchip/irq-gic-v3.c
-+++ b/drivers/irqchip/irq-gic-v3.c
-@@ -490,9 +490,19 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
- 	isb();
- }
- 
-+#ifdef CONFIG_ARM_PARKING_PROTOCOL
-+static void gic_wakeup_parked_cpu(int cpu)
-+{
-+	gic_raise_softirq(cpumask_of(cpu), 0);
++	id = acpi_match_device(drv->acpi_match_table, dev);
++	if (!id)
++		return false;
++
++	return acpi_of_driver_match_device(dev, drv);
 +}
-+#endif
++EXPORT_SYMBOL_GPL(acpi_driver_match_device);
 +
- static void gic_smp_init(void)
+ static void acpi_free_power_resources_lists(struct acpi_device *device)
  {
- 	set_smp_cross_call(gic_raise_softirq);
-+#ifdef CONFIG_ARM_PARKING_PROTOCOL
-+	set_smp_boot_wakeup_call(gic_wakeup_parked_cpu);
-+#endif
- 	register_cpu_notifier(&gic_cpu_notifier);
- }
- 
-diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
-index dda6dbc..5d9bdd3 100644
---- a/drivers/irqchip/irq-gic.c
-+++ b/drivers/irqchip/irq-gic.c
-@@ -33,12 +33,14 @@
- #include <linux/of.h>
- #include <linux/of_address.h>
- #include <linux/of_irq.h>
+ 	int i;
+@@ -884,6 +955,7 @@ static void acpi_device_release(struct device *dev)
+ {
+ 	struct acpi_device *acpi_dev = to_acpi_device(dev);
+ 
++	acpi_free_properties(acpi_dev);
+ 	acpi_free_pnp_ids(&acpi_dev->pnp);
+ 	acpi_free_power_resources_lists(acpi_dev);
+ 	kfree(acpi_dev);
+@@ -1888,6 +1960,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
+ 	acpi_set_device_status(device, sta);
+ 	acpi_device_get_busid(device);
+ 	acpi_set_pnp_ids(handle, &device->pnp, type);
++	acpi_init_properties(device);
+ 	acpi_bus_get_flags(device);
+ 	device->flags.match_driver = false;
+ 	device->flags.initialized = true;
+diff --git a/drivers/acpi/sleep-arm.c b/drivers/acpi/sleep-arm.c
+new file mode 100644
+index 0000000..54578ef
+--- /dev/null
++++ b/drivers/acpi/sleep-arm.c
+@@ -0,0 +1,28 @@
++/*
++ *  ARM64 Specific Sleep Functionality
++ *
++ *  Copyright (C) 2013-2014, Linaro Ltd.
++ *      Author: Graeme Gregory <graeme.gregory at linaro.org>
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License version 2 as
++ *  published by the Free Software Foundation.
++ */
++
 +#include <linux/acpi.h>
- #include <linux/irqdomain.h>
- #include <linux/interrupt.h>
- #include <linux/percpu.h>
- #include <linux/slab.h>
- #include <linux/irqchip/chained_irq.h>
- #include <linux/irqchip/arm-gic.h>
-+#include <linux/irqchip/arm-gic-acpi.h>
- 
- #include <asm/cputype.h>
- #include <asm/irq.h>
-@@ -622,6 +624,13 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
- 
- 	raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
- }
 +
-+#ifdef CONFIG_ARM_PARKING_PROTOCOL
-+static void gic_wakeup_parked_cpu(int cpu)
++/*
++ * Currently the ACPI 5.1 standard does not define S states in a
++ * manner which is usable for ARM64. These two stubs are sufficient
++ * that system initialises and device PM works.
++ */
++u32 acpi_target_system_state(void)
 +{
-+	gic_raise_softirq(cpumask_of(cpu), GIC_DIST_SOFTINT_NSATT);
++	return ACPI_STATE_S0;
 +}
-+#endif
- #endif
- 
- #ifdef CONFIG_BL_SWITCHER
-@@ -977,6 +986,9 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
- #ifdef CONFIG_SMP
- 		set_smp_cross_call(gic_raise_softirq);
- 		register_cpu_notifier(&gic_cpu_notifier);
-+#ifdef CONFIG_ARM_PARKING_PROTOCOL
-+		set_smp_boot_wakeup_call(gic_wakeup_parked_cpu);
-+#endif
- #endif
- 		set_handle_irq(gic_handle_irq);
- 	}
-@@ -1029,3 +1041,107 @@ IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
- IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
++EXPORT_SYMBOL_GPL(acpi_target_system_state);
++
++int __init acpi_sleep_init(void)
++{
++	return -ENOSYS;
++}
+diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
+index 6d5a6cd..47f36d4 100644
+--- a/drivers/acpi/tables.c
++++ b/drivers/acpi/tables.c
+@@ -183,6 +183,49 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
+ 		}
+ 		break;
  
- #endif
++	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
++		{
++			struct acpi_madt_generic_interrupt *p =
++				(struct acpi_madt_generic_interrupt *)header;
++			pr_info("GICC (acpi_id[0x%04x] address[%p] MPDIR[0x%llx] %s)\n",
++				p->uid, (void *)(unsigned long)p->base_address,
++				p->arm_mpidr,
++				(p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
 +
-+#ifdef CONFIG_ACPI
-+static phys_addr_t dist_phy_base, cpu_phy_base;
-+static int cpu_base_assigned;
++		}
++		break;
 +
-+static int __init
-+gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
-+			const unsigned long end)
-+{
-+	struct acpi_madt_generic_interrupt *processor;
-+	phys_addr_t gic_cpu_base;
++	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
++		{
++			struct acpi_madt_generic_distributor *p =
++				(struct acpi_madt_generic_distributor *)header;
++			pr_info("GIC Distributor (gic_id[0x%04x] address[%p] gsi_base[%d])\n",
++				p->gic_id,
++				(void *)(unsigned long)p->base_address,
++				p->global_irq_base);
++		}
++		break;
 +
-+	processor = (struct acpi_madt_generic_interrupt *)header;
++	case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
++		{
++			struct acpi_madt_generic_msi_frame *p =
++				(struct acpi_madt_generic_msi_frame *)header;
++			pr_info("GIC MSI Frame (msi_fame_id[%d] address[%p])\n",
++				p->msi_frame_id,
++				(void *)(unsigned long)p->base_address);
++		}
++		break;
 +
-+	if (BAD_MADT_ENTRY(processor, end))
++	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
++		{
++			struct acpi_madt_generic_redistributor *p =
++				(struct acpi_madt_generic_redistributor *)header;
++			pr_info("GIC Redistributor (address[%p] region_size[0x%x])\n",
++				(void *)(unsigned long)p->base_address,
++				p->length);
++		}
++		break;
++
+ 	default:
+ 		pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
+ 			header->type);
+@@ -192,17 +235,14 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
+ 
+ 
+ int __init
+-acpi_table_parse_entries(char *id,
+-			     unsigned long table_size,
+-			     int entry_id,
+-			     acpi_tbl_entry_handler handler,
+-			     unsigned int max_entries)
++acpi_parse_entries(unsigned long table_size,
++		acpi_tbl_entry_handler handler,
++		struct acpi_table_header *table_header,
++		int entry_id, unsigned int max_entries)
+ {
+-	struct acpi_table_header *table_header = NULL;
+ 	struct acpi_subtable_header *entry;
+-	unsigned int count = 0;
++	int count = 0;
+ 	unsigned long table_end;
+-	acpi_size tbl_size;
+ 
+ 	if (acpi_disabled)
+ 		return -ENODEV;
+@@ -210,13 +250,11 @@ acpi_table_parse_entries(char *id,
+ 	if (!handler)
+ 		return -EINVAL;
+ 
+-	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
+-		acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
+-	else
+-		acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
++	if (!table_size)
 +		return -EINVAL;
+ 
+ 	if (!table_header) {
+-		pr_warn("%4.4s not present\n", id);
++		pr_warn("Table header not present\n");
+ 		return -ENODEV;
+ 	}
+ 
+@@ -230,32 +268,67 @@ acpi_table_parse_entries(char *id,
+ 	while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
+ 	       table_end) {
+ 		if (entry->type == entry_id
+-		    && (!max_entries || count++ < max_entries))
++		    && (!max_entries || count < max_entries)) {
+ 			if (handler(entry, table_end))
+-				goto err;
++				return -EINVAL;
 +
-+	/*
-+	 * There is no support for non-banked GICv1/2 register in ACPI spec.
-+	 * All CPU interface addresses have to be the same.
-+	 */
-+	gic_cpu_base = processor->base_address;
-+	if (cpu_base_assigned && gic_cpu_base != cpu_phy_base)
-+		return -EFAULT;
++			count++;
++		}
+ 
+ 		/*
+ 		 * If entry->length is 0, break from this loop to avoid
+ 		 * infinite loop.
+ 		 */
+ 		if (entry->length == 0) {
+-			pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
+-			goto err;
++			pr_err("[0x%02x] Invalid zero length\n", entry_id);
++			return -EINVAL;
+ 		}
+ 
+ 		entry = (struct acpi_subtable_header *)
+ 		    ((unsigned long)entry + entry->length);
+ 	}
 +
-+	cpu_phy_base = gic_cpu_base;
-+	cpu_base_assigned = 1;
-+	return 0;
+ 	if (max_entries && count > max_entries) {
+ 		pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n",
+-			id, entry_id, count - max_entries, count);
++			table_header->signature, entry_id, count - max_entries,
++			count);
+ 	}
+ 
+-	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
+ 	return count;
+-err:
 +}
 +
-+static int __init
-+gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
-+				const unsigned long end)
++int __init
++acpi_table_parse_entries(char *id,
++			 unsigned long table_size,
++			 int entry_id,
++			 acpi_tbl_entry_handler handler,
++			 unsigned int max_entries)
 +{
-+	struct acpi_madt_generic_distributor *dist;
++	struct acpi_table_header *table_header = NULL;
++	acpi_size tbl_size;
++	int count;
 +
-+	dist = (struct acpi_madt_generic_distributor *)header;
++	if (acpi_disabled)
++		return -ENODEV;
 +
-+	if (BAD_MADT_ENTRY(dist, end))
++	if (!handler)
 +		return -EINVAL;
 +
-+	dist_phy_base = dist->base_address;
-+	return 0;
-+}
-+
-+int __init
-+gic_v2_acpi_init(struct acpi_table_header *table)
-+{
-+	void __iomem *cpu_base, *dist_base;
-+	int count;
-+
-+	/* Collect CPU base addresses */
-+	count = acpi_parse_entries(sizeof(struct acpi_table_madt),
-+				   gic_acpi_parse_madt_cpu, table,
-+				   ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
-+	if (count < 0) {
-+		pr_err("Error during GICC entries parsing\n");
-+		return -EFAULT;
-+	} else if (!count) {
-+		pr_err("No valid GICC entries exist\n");
-+		return -EINVAL;
-+	}
-+
-+	/*
-+	 * Find distributor base address. We expect one distributor entry since
-+	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
-+	 */
-+	count = acpi_parse_entries(sizeof(struct acpi_table_madt),
-+				   gic_acpi_parse_madt_distributor, table,
-+				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
-+	if (count <= 0) {
-+		pr_err("Error during GICD entries parsing\n");
-+		return -EFAULT;
-+	} else if (!count) {
-+		pr_err("No valid GICD entries exist\n");
-+		return -EINVAL;
-+	} else if (count > 1) {
-+		pr_err("More than one GICD entry detected\n");
-+		return -EINVAL;
-+	}
-+
-+	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
-+	if (!cpu_base) {
-+		pr_err("Unable to map GICC registers\n");
-+		return -ENOMEM;
-+	}
++	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
++		acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
++	else
++		acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
 +
-+	dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
-+	if (!dist_base) {
-+		pr_err("Unable to map GICD registers\n");
-+		iounmap(cpu_base);
-+		return -ENOMEM;
++	if (!table_header) {
++		pr_warn("%4.4s not present\n", id);
++		return -ENODEV;
 +	}
 +
-+	/*
-+	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
-+	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
-+	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
-+	 */
-+	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
-+	irq_set_default_host(gic_data[0].domain);
-+	return 0;
-+}
-+#endif
-diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c
-index 0fe2f71..9106c6d 100644
---- a/drivers/irqchip/irqchip.c
-+++ b/drivers/irqchip/irqchip.c
-@@ -11,6 +11,7 @@
- #include <linux/init.h>
- #include <linux/of_irq.h>
- #include <linux/irqchip.h>
-+#include <linux/irqchip/arm-gic-acpi.h>
- 
- /*
-  * This special of_device_id is the sentinel at the end of the
-@@ -26,4 +27,6 @@ extern struct of_device_id __irqchip_of_table[];
- void __init irqchip_init(void)
- {
- 	of_irq_init(__irqchip_of_table);
++	count = acpi_parse_entries(table_size, handler, table_header,
++			entry_id, max_entries);
 +
-+	acpi_gic_init();
+ 	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
+-	return -EINVAL;
++	return count;
  }
-diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
-index ea27383..d0d3ab5 100644
---- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
-+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
-@@ -696,6 +696,18 @@ static int xgbe_read_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
- 	else
- 		mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff);
  
-+	if (XGBE_SEATTLE_A0) {
-+		/* The PCS implementation has reversed the devices in
-+		 * package registers so we need to change 05 to 06 and
-+		 * 06 to 05 if being read (these registers are readonly
-+		 * so no need to do this in the write function)
-+		 */
-+		if ((mmd_address & 0xffff) == 0x05)
-+			mmd_address = (mmd_address & ~0xffff) | 0x06;
-+		else if ((mmd_address & 0xffff) == 0x06)
-+			mmd_address = (mmd_address & ~0xffff) | 0x05;
-+	}
+ int __init
+diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
+index 834f35c..b163f73 100644
+--- a/drivers/acpi/utils.c
++++ b/drivers/acpi/utils.c
+@@ -697,3 +697,29 @@ bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs)
+ 	return false;
+ }
+ EXPORT_SYMBOL(acpi_check_dsm);
 +
- 	/* The PCS registers are accessed using mmio. The underlying APB3
- 	 * management interface uses indirect addressing to access the MMD
- 	 * register sets. This requires accessing of the PCS register in two
-diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
-index b26d758..ca7895c 100644
---- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
-+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
-@@ -426,6 +426,9 @@ void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata)
- 	hw_feat->rx_ch_cnt++;
- 	hw_feat->tx_ch_cnt++;
- 
-+	/* A0 does not support NUMTC, hardcode it for now */
-+	hw_feat->tc_cnt = XGBE_TC_CNT;
++/**
++ * acpi_check_coherency - check for memory coherency of a device
++ * @handle: ACPI device handle
++ * @val:    Pointer to returned value
++ *
++ * Search a device and its parents for a _CCA method and return
++ * its value.
++ */
++acpi_status acpi_check_coherency(acpi_handle handle, int *val)
++{
++	unsigned long long data;
++	acpi_status status;
 +
- 	DBGPR("<--xgbe_get_all_hw_features\n");
- }
- 
-diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
-index bdf9cfa..ba53e41 100644
---- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
-+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
-@@ -533,6 +533,7 @@ static int xgbe_resume(struct device *dev)
- #endif /* CONFIG_PM */
- 
- static const struct of_device_id xgbe_of_match[] = {
-+	{ .compatible = "amd,xgbe-seattle-v0a", },
- 	{ .compatible = "amd,xgbe-seattle-v1a", },
- 	{},
- };
-diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
-index e9fe6e6..389bfec 100644
---- a/drivers/net/ethernet/amd/xgbe/xgbe.h
-+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
-@@ -187,8 +187,11 @@
- #define XGBE_FIFO_SIZE_B(x)	(x)
- #define XGBE_FIFO_SIZE_KB(x)	(x * 1024)
- 
-+#define XGBE_TC_CNT		2
- #define XGBE_TC_MIN_QUANTUM	10
- 
-+#define XGBE_SEATTLE_A0		((read_cpuid_id() & 0x00f0000f) == 0)
++	do {
++		status = acpi_evaluate_integer(handle, "_CCA", NULL, &data);
++		if (!ACPI_FAILURE(status)) {
++			*val = data;
++			break;
++		}
++		status = acpi_get_parent(handle, &handle);
++	} while (!ACPI_FAILURE(status));
 +
- /* Helper macro for descriptor handling
-  *  Always use XGBE_GET_DESC_DATA to access the descriptor data
-  *  since the index is free-running and needs to be and-ed
-diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
-index bcaa41a..ebad872 100644
---- a/drivers/net/ethernet/smsc/smc91x.c
-+++ b/drivers/net/ethernet/smsc/smc91x.c
-@@ -81,6 +81,7 @@ static const char version[] =
- #include <linux/workqueue.h>
- #include <linux/of.h>
- #include <linux/of_device.h>
++	return status;
++}
++EXPORT_SYMBOL(acpi_check_coherency);
+diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
+index cd4cccb..edb00c6 100644
+--- a/drivers/ata/Kconfig
++++ b/drivers/ata/Kconfig
+@@ -48,7 +48,7 @@ config ATA_VERBOSE_ERROR
+ 
+ config ATA_ACPI
+ 	bool "ATA ACPI Support"
+-	depends on ACPI && PCI
++	depends on ACPI
+ 	default y
+ 	help
+ 	  This option adds support for ATA-related ACPI objects.
+diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
+index 06f1d59..df2ea85 100644
+--- a/drivers/ata/ahci_platform.c
++++ b/drivers/ata/ahci_platform.c
+@@ -20,6 +20,9 @@
+ #include <linux/platform_device.h>
+ #include <linux/libata.h>
+ #include <linux/ahci_platform.h>
++#ifdef CONFIG_ATA_ACPI
 +#include <linux/acpi.h>
++#endif
+ #include "ahci.h"
  
- #include <linux/netdevice.h>
- #include <linux/etherdevice.h>
-@@ -2408,6 +2409,14 @@ static struct dev_pm_ops smc_drv_pm_ops = {
- 	.resume		= smc_drv_resume,
+ static const struct ata_port_info ahci_port_info = {
+@@ -71,6 +74,13 @@ static const struct of_device_id ahci_of_match[] = {
  };
+ MODULE_DEVICE_TABLE(of, ahci_of_match);
  
-+#ifdef CONFIG_ACPI
-+static const struct acpi_device_id smc91x_acpi_match[] = {
-+	{ "LNRO0003", },
-+	{ }
++#ifdef CONFIG_ATA_ACPI
++static const struct acpi_device_id ahci_acpi_match[] = {
++	{ "AMDI0600", 0 }, /* AMD Seattle AHCI */
++	{ },
 +};
-+MODULE_DEVICE_TABLE(acpi, smc91x_acpi_match);
 +#endif
 +
- static struct platform_driver smc_driver = {
- 	.probe		= smc_drv_probe,
- 	.remove		= smc_drv_remove,
-@@ -2416,6 +2425,7 @@ static struct platform_driver smc_driver = {
- 		.owner	= THIS_MODULE,
- 		.pm	= &smc_drv_pm_ops,
- 		.of_match_table = of_match_ptr(smc91x_match),
-+		.acpi_match_table = ACPI_PTR(smc91x_acpi_match),
+ static struct platform_driver ahci_driver = {
+ 	.probe = ahci_probe,
+ 	.remove = ata_platform_remove_one,
+@@ -78,6 +88,9 @@ static struct platform_driver ahci_driver = {
+ 		.name = "ahci",
+ 		.owner = THIS_MODULE,
+ 		.of_match_table = ahci_of_match,
++#ifdef CONFIG_ATA_ACPI
++		.acpi_match_table = ACPI_PTR(ahci_acpi_match),
++#endif
+ 		.pm = &ahci_pm_ops,
  	},
  };
+diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
+index 0f8538f..2d8103a 100644
+--- a/drivers/ata/ahci_xgene.c
++++ b/drivers/ata/ahci_xgene.c
+@@ -28,6 +28,7 @@
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
+ #include <linux/phy/phy.h>
++#include <linux/acpi.h>
+ #include "ahci.h"
  
-diff --git a/drivers/net/phy/amd-xgbe-phy.c b/drivers/net/phy/amd-xgbe-phy.c
-index f3230ee..90145d9 100644
---- a/drivers/net/phy/amd-xgbe-phy.c
-+++ b/drivers/net/phy/amd-xgbe-phy.c
-@@ -78,12 +78,14 @@
+ /* Max # of disk per a controller */
+@@ -137,7 +138,8 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc)
+ 	struct xgene_ahci_context *ctx = hpriv->plat_data;
+ 	int rc = 0;
  
- MODULE_AUTHOR("Tom Lendacky <thomas.lendacky at amd.com>");
- MODULE_LICENSE("Dual BSD/GPL");
--MODULE_VERSION("1.0.0-a");
-+MODULE_VERSION("0.0.0-a");
- MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
+-	if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA))
++	if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA ||
++		     ctx->last_cmd[ap->port_no] == ATA_CMD_SMART))
+ 		xgene_ahci_restart_engine(ap);
  
--#define XGBE_PHY_ID	0x000162d0
-+#define XGBE_PHY_ID	0x7996ced0
- #define XGBE_PHY_MASK	0xfffffff0
+ 	rc = ahci_qc_issue(qc);
+@@ -148,14 +150,6 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc)
+ 	return rc;
+ }
  
-+#define XGBE_PHY_SERDES_RETRY		32
-+#define XGBE_PHY_CHANNEL_PROPERTY	"amd,serdes-channel"
- #define XGBE_PHY_SPEEDSET_PROPERTY	"amd,speed-set"
+-static bool xgene_ahci_is_memram_inited(struct xgene_ahci_context *ctx)
+-{
+-	void __iomem *diagcsr = ctx->csr_diag;
+-
+-	return (readl(diagcsr + CFG_MEM_RAM_SHUTDOWN) == 0 &&
+-	        readl(diagcsr + BLOCK_MEM_RDY) == 0xFFFFFFFF);
+-}
+-
+ /**
+  * xgene_ahci_read_id - Read ID data from the specified device
+  * @dev: device
+@@ -501,11 +495,6 @@ static int xgene_ahci_probe(struct platform_device *pdev)
+ 		return -ENODEV;
+ 	}
  
- #define XGBE_AN_INT_CMPLT		0x01
-@@ -118,77 +120,6 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
- #define MDIO_CTRL1_SPEED1G		(MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100)
- #endif
+-	if (xgene_ahci_is_memram_inited(ctx)) {
+-		dev_info(dev, "skip clock and PHY initialization\n");
+-		goto skip_clk_phy;
+-	}
+-
+ 	/* Due to errata, HW requires full toggle transition */
+ 	rc = ahci_platform_enable_clks(hpriv);
+ 	if (rc)
+@@ -518,7 +507,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
  
--/* SerDes integration register offsets */
--#define SIR0_KR_RT_1			0x002c
--#define SIR0_STATUS			0x0040
--#define SIR1_SPEED			0x0000
+ 	/* Configure the host controller */
+ 	xgene_ahci_hw_init(hpriv);
+-skip_clk_phy:
++
+ 	hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_NCQ;
+ 
+ 	rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info);
+@@ -533,6 +522,16 @@ disable_resources:
+ 	return rc;
+ }
+ 
++#ifdef CONFIG_ACPI
++static const struct acpi_device_id xgene_ahci_acpi_match[] = {
++	{ "APMC0D00", },
++	{ "APMC0D0D", },
++	{ "APMC0D09", },
++	{ }
++};
++MODULE_DEVICE_TABLE(acpi, xgene_ahci_acpi_match);
++#endif
++
+ static const struct of_device_id xgene_ahci_of_match[] = {
+ 	{.compatible = "apm,xgene-ahci"},
+ 	{},
+@@ -546,6 +545,7 @@ static struct platform_driver xgene_ahci_driver = {
+ 		.name = "xgene-ahci",
+ 		.owner = THIS_MODULE,
+ 		.of_match_table = xgene_ahci_of_match,
++		.acpi_match_table = ACPI_PTR(xgene_ahci_acpi_match),
+ 	},
+ };
+ 
+diff --git a/drivers/base/Makefile b/drivers/base/Makefile
+index 6922cd6..53c3fe1 100644
+--- a/drivers/base/Makefile
++++ b/drivers/base/Makefile
+@@ -4,7 +4,7 @@ obj-y			:= component.o core.o bus.o dd.o syscore.o \
+ 			   driver.o class.o platform.o \
+ 			   cpu.o firmware.o init.o map.o devres.o \
+ 			   attribute_container.o transport_class.o \
+-			   topology.o container.o
++			   topology.o container.o property.o
+ obj-$(CONFIG_DEVTMPFS)	+= devtmpfs.o
+ obj-$(CONFIG_DMA_CMA) += dma-contiguous.o
+ obj-y			+= power/
+diff --git a/drivers/base/property.c b/drivers/base/property.c
+new file mode 100644
+index 0000000..7bf5708
+--- /dev/null
++++ b/drivers/base/property.c
+@@ -0,0 +1,235 @@
++/*
++ * property.c - Unified device property interface.
++ *
++ * Copyright (C) 2014, Intel Corporation
++ * Authors: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
++ *          Mika Westerberg <mika.westerberg at linux.intel.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/property.h>
++#include <linux/export.h>
++#include <linux/acpi.h>
++#include <linux/of.h>
++
++/**
++ * device_get_property - return a raw property of a device
++ * @dev: Device get the property of
++ * @propname: Name of the property
++ * @valptr: The raw property value is stored here
++ *
++ * Function reads property @propname from the device firmware description and
++ * stores the raw value into @valptr if found.  Otherwise returns a negative
++ * errno as specified below.
++ *
++ * Return: %0 if the property was found (success),
++ *	   %-EINVAL if given arguments are not valid,
++ *	   %-ENODATA if the property does not exist.
++ */
++int device_get_property(struct device *dev, const char *propname, void **valptr)
++{
++	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
++		return of_dev_prop_get(dev->of_node, propname, valptr);
++
++	return acpi_dev_prop_get(ACPI_COMPANION(dev), propname, valptr);
++}
++EXPORT_SYMBOL_GPL(device_get_property);
++
++/**
++ * device_get_child_property - return a raw property of a device's child
++ * @dev: Parent device
++ * @child: Child to get a property of
++ * @propname: Name of the property
++ * @valptr: The raw property value is stored here
++ *
++ * Function reads property @propname from the firmware description of @child and
++ * stores the raw value into @valptr if found.  Otherwise returns a negative
++ * errno as specified below.
++ *
++ * Return: %0 if the property was found (success),
++ *	   %-EINVAL if given arguments are not valid,
++ *	   %-ENODATA if the property does not exist.
++ */
++int device_get_child_property(struct device *dev, void *child,
++			      const char *propname, void **valptr)
++{
++	if (!child)
++		return -EINVAL;
++
++	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
++		return of_dev_prop_get(child, propname, valptr);
++	else if (ACPI_COMPANION(dev))
++		return acpi_dev_prop_get(child, propname, valptr);
++
++	return -ENODATA;
++}
++EXPORT_SYMBOL_GPL(device_get_child_property);
++
++/**
++ * device_read_property - read a typed property of a device
++ * @dev: Device to get the property of
++ * @propname: Name of the property
++ * @proptype: Type of the property
++ * @val: The value is stored here
++ *
++ * Function reads property @propname from the device firmware description and
++ * stores the value into @val if found. The value is checked to be of type
++ * @proptype.
++ *
++ * Return: %0 if the property was found (success),
++ *	   %-EINVAL if given arguments are not valid,
++ *	   %-ENODATA if the property does not exist,
++ *	   %-EPROTO if the property type does not match @proptype,
++ *	   %-EOVERFLOW if the property value is out of bounds of @proptype.
++ */
++int device_read_property(struct device *dev, const char *propname,
++			 enum dev_prop_type proptype, void *val)
++{
++	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
++		return of_dev_prop_read(dev->of_node, propname, proptype, val);
++
++	return acpi_dev_prop_read(ACPI_COMPANION(dev), propname, proptype, val);
++}
++EXPORT_SYMBOL_GPL(device_read_property);
++
++/**
++ * device_read_child_property - read a typed property of a device's child
++ * @dev: Parent device
++ * @child: Child to read a property of
++ * @propname: Name of the property
++ * @proptype: Type of the property
++ * @val: The value is stored here
++ *
++ * Function reads property @propname from the firmware description of @child and
++ * stores the value into @val if found. The value is checked to be of type
++ * @proptype.
++ *
++ * Return: %0 if the property was found (success),
++ *	   %-EINVAL if given arguments are not valid,
++ *	   %-ENODATA if the property does not exist,
++ *	   %-EPROTO if the property type does not match @proptype,
++ *	   %-EOVERFLOW if the property value is out of bounds of @proptype.
++ */
++int device_read_child_property(struct device *dev, void *child,
++			       const char *propname, enum dev_prop_type proptype,
++			       void *val)
++{
++	if (!child)
++		return -EINVAL;
++
++	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
++		return of_dev_prop_read(child, propname, proptype, val);
++	else if (ACPI_COMPANION(dev))
++		return acpi_dev_prop_read(child, propname, proptype, val);
++
++	return -ENODATA;
++}
++EXPORT_SYMBOL_GPL(device_read_child_property);
++
++/**
++ * device_read_property_array - read an array property of a device
++ * @dev: Device to get the property of
++ * @propname: Name of the property
++ * @proptype: Type of the property
++ * @val: The values are stored here
++ * @nval: Size of the @val array
++ *
++ * Function reads an array of properties with @propname from the device
++ * firmware description and stores them to @val if found. All the values
++ * in the array must be of type @proptype.
++ *
++ * Return: %0 if the property was found (success),
++ *	   %-EINVAL if given arguments are not valid,
++ *	   %-ENODATA if the property does not exist,
++ *	   %-EPROTO if the property type does not match @proptype,
++ *	   %-EOVERFLOW if the property value is out of bounds of @proptype.
++ */
++int device_read_property_array(struct device *dev, const char *propname,
++			       enum dev_prop_type proptype, void *val,
++			       size_t nval)
++{
++	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
++		return of_dev_prop_read_array(dev->of_node, propname, proptype,
++					      val, nval);
++
++	return acpi_dev_prop_read_array(ACPI_COMPANION(dev), propname, proptype,
++					val, nval);
++}
++EXPORT_SYMBOL_GPL(device_read_property_array);
++
++/**
++ * device_read_child_property_array - read an array property of a device's child
++ * @dev: Parent device
++ * @child: Child to get the property of
++ * @propname: Name of the property
++ * @proptype: Type of the property
++ * @val: The values are stored here
++ * @nval: Size of the @val array
++ *
++ * Function reads an array of properties with @propname from the firmware
++ * description of @child and stores them to @val if found. All the values
++ * in the array must be of type @proptype.
++ *
++ * Return: %0 if the property was found (success),
++ *	   %-EINVAL if given arguments are not valid,
++ *	   %-ENODATA if the property does not exist,
++ *	   %-EPROTO if the property type does not match @proptype,
++ *	   %-EOVERFLOW if the property value is out of bounds of @proptype.
++ */
++int device_read_child_property_array(struct device *dev, void *child,
++				     const char *propname,
++				     enum dev_prop_type proptype, void *val,
++				     size_t nval)
++{
++	if (!child)
++		return -EINVAL;
++
++	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
++		return of_dev_prop_read_array(child, propname, proptype,
++					      val, nval);
++	else if (ACPI_COMPANION(dev))
++		return acpi_dev_prop_read_array(child, propname, proptype,
++						val, nval);
++
++	return -ENODATA;
++}
++EXPORT_SYMBOL_GPL(device_read_child_property_array);
++
++/**
++ * device_for_each_child_node - execute function for each child node of device
++ * @dev: Device to run the function for
++ * @fn: Function to run
++ * @data: Additional data to pass to the function
++ */
++int device_for_each_child_node(struct device *dev,
++			int (*fn)(struct device *dev, void *child, void *data),
++			void *data)
++{
++	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
++		return of_for_each_child_node(dev, fn, data);
++
++	return acpi_for_each_child_node(dev, fn, data);
++}
++EXPORT_SYMBOL_GPL(device_for_each_child_node);
++
++static int increment_count(struct device *dev, void *child, void *data)
++{
++	*((unsigned int *)data) += 1;
++	return 0;
++}
++
++/**
++ * device_get_child_node_count - return the number of child nodes for device
++ * @dev: Device to cound the child nodes for
++ */
++unsigned int device_get_child_node_count(struct device *dev)
++{
++	unsigned int count = 0;
++
++	device_for_each_child_node(dev, increment_count, &count);
++	return count;
++}
++EXPORT_SYMBOL_GPL(device_get_child_node_count);
+diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
+index 2133f9d..b73392b 100644
+--- a/drivers/clocksource/arm_arch_timer.c
++++ b/drivers/clocksource/arm_arch_timer.c
+@@ -21,6 +21,7 @@
+ #include <linux/io.h>
+ #include <linux/slab.h>
+ #include <linux/sched_clock.h>
++#include <linux/acpi.h>
+ 
+ #include <asm/arch_timer.h>
+ #include <asm/virt.h>
+@@ -61,7 +62,8 @@ enum ppi_nr {
+ 	MAX_TIMER_PPI
+ };
+ 
+-static int arch_timer_ppi[MAX_TIMER_PPI];
++int arch_timer_ppi[MAX_TIMER_PPI];
++EXPORT_SYMBOL(arch_timer_ppi);
+ 
+ static struct clock_event_device __percpu *arch_timer_evt;
+ 
+@@ -370,8 +372,12 @@ arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np)
+ 	if (arch_timer_rate)
+ 		return;
+ 
+-	/* Try to determine the frequency from the device tree or CNTFRQ */
+-	if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
++	/*
++	 * Try to determine the frequency from the device tree or CNTFRQ,
++	 * if ACPI is enabled, get the frequency from CNTFRQ ONLY.
++	 */
++	if (!acpi_disabled ||
++	    of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) {
+ 		if (cntbase)
+ 			arch_timer_rate = readl_relaxed(cntbase + CNTFRQ);
+ 		else
+@@ -660,13 +666,14 @@ static bool __init
+ arch_timer_probed(int type, const struct of_device_id *matches)
+ {
+ 	struct device_node *dn;
+-	bool probed = false;
++	bool probed = true;
+ 
+ 	dn = of_find_matching_node(NULL, matches);
+-	if (dn && of_device_is_available(dn) && (arch_timers_present & type))
+-		probed = true;
+-	of_node_put(dn);
 -
--/* SerDes integration register entry bit positions and sizes */
--#define SIR0_KR_RT_1_RESET_INDEX	11
--#define SIR0_KR_RT_1_RESET_WIDTH	1
--#define SIR0_STATUS_RX_READY_INDEX	0
--#define SIR0_STATUS_RX_READY_WIDTH	1
--#define SIR0_STATUS_TX_READY_INDEX	8
--#define SIR0_STATUS_TX_READY_WIDTH	1
--#define SIR1_SPEED_DATARATE_INDEX	4
--#define SIR1_SPEED_DATARATE_WIDTH	2
--#define SIR1_SPEED_PI_SPD_SEL_INDEX	12
--#define SIR1_SPEED_PI_SPD_SEL_WIDTH	4
--#define SIR1_SPEED_PLLSEL_INDEX		3
--#define SIR1_SPEED_PLLSEL_WIDTH		1
--#define SIR1_SPEED_RATECHANGE_INDEX	6
--#define SIR1_SPEED_RATECHANGE_WIDTH	1
--#define SIR1_SPEED_TXAMP_INDEX		8
--#define SIR1_SPEED_TXAMP_WIDTH		4
--#define SIR1_SPEED_WORDMODE_INDEX	0
--#define SIR1_SPEED_WORDMODE_WIDTH	3
++	if (dn) {
++		if (of_device_is_available(dn) && !(arch_timers_present & type))
++			probed = false;
++		of_node_put(dn);
++	}
+ 	return probed;
+ }
+ 
+@@ -687,20 +694,8 @@ static void __init arch_timer_common_init(void)
+ 	arch_timer_arch_init();
+ }
+ 
+-static void __init arch_timer_init(struct device_node *np)
++static void __init arch_timer_init(void)
+ {
+-	int i;
 -
--#define SPEED_10000_CDR			0x7
--#define SPEED_10000_PLL			0x1
--#define SPEED_10000_RATE		0x0
--#define SPEED_10000_TXAMP		0xa
--#define SPEED_10000_WORD		0x7
+-	if (arch_timers_present & ARCH_CP15_TIMER) {
+-		pr_warn("arch_timer: multiple nodes in dt, skipping\n");
+-		return;
+-	}
 -
--#define SPEED_2500_CDR			0x2
--#define SPEED_2500_PLL			0x0
--#define SPEED_2500_RATE			0x1
--#define SPEED_2500_TXAMP		0xf
--#define SPEED_2500_WORD			0x1
+-	arch_timers_present |= ARCH_CP15_TIMER;
+-	for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
+-		arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
+-	arch_timer_detect_rate(NULL, np);
 -
--#define SPEED_1000_CDR			0x2
--#define SPEED_1000_PLL			0x0
--#define SPEED_1000_RATE			0x3
--#define SPEED_1000_TXAMP		0xf
--#define SPEED_1000_WORD			0x1
+ 	/*
+ 	 * If HYP mode is available, we know that the physical timer
+ 	 * has been configured to be accessible from PL1. Use it, so
+@@ -719,13 +714,31 @@ static void __init arch_timer_init(struct device_node *np)
+ 		}
+ 	}
+ 
+-	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
+-
+ 	arch_timer_register();
+ 	arch_timer_common_init();
+ }
+-CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_init);
+-CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_init);
++
++static void __init arch_timer_of_init(struct device_node *np)
++{
++	int i;
++
++	if (arch_timers_present & ARCH_CP15_TIMER) {
++		pr_warn("arch_timer: multiple nodes in dt, skipping\n");
++		return;
++	}
++
++	arch_timers_present |= ARCH_CP15_TIMER;
++	for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
++		arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
++
++	arch_timer_detect_rate(NULL, np);
++
++	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
++
++	arch_timer_init();
++}
++CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init);
++CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init);
+ 
+ static void __init arch_timer_mem_init(struct device_node *np)
+ {
+@@ -792,3 +805,71 @@ static void __init arch_timer_mem_init(struct device_node *np)
+ }
+ CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem",
+ 		       arch_timer_mem_init);
++
++#ifdef CONFIG_ACPI
++static int __init
++map_generic_timer_interrupt(u32 interrupt, u32 flags)
++{
++	int trigger, polarity;
++
++	if (!interrupt)
++		return 0;
++
++	trigger = (flags & ACPI_GTDT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE
++			: ACPI_LEVEL_SENSITIVE;
++
++	polarity = (flags & ACPI_GTDT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW
++			: ACPI_ACTIVE_HIGH;
++
++	return acpi_register_gsi(NULL, interrupt, trigger, polarity);
++}
++
++/* Initialize per-processor generic timer */
++static int __init arch_timer_acpi_init(struct acpi_table_header *table)
++{
++	struct acpi_table_gtdt *gtdt;
++
++	if (arch_timers_present & ARCH_CP15_TIMER) {
++		pr_warn("arch_timer: already initialized, skipping\n");
++		return -EINVAL;
++	}
++
++	gtdt = container_of(table, struct acpi_table_gtdt, header);
++
++	arch_timers_present |= ARCH_CP15_TIMER;
++
++	arch_timer_ppi[PHYS_SECURE_PPI] =
++		map_generic_timer_interrupt(gtdt->secure_el1_interrupt,
++		gtdt->secure_el1_flags);
++
++	arch_timer_ppi[PHYS_NONSECURE_PPI] =
++		map_generic_timer_interrupt(gtdt->non_secure_el1_interrupt,
++		gtdt->non_secure_el1_flags);
++
++	arch_timer_ppi[VIRT_PPI] =
++		map_generic_timer_interrupt(gtdt->virtual_timer_interrupt,
++		gtdt->virtual_timer_flags);
++
++	arch_timer_ppi[HYP_PPI] =
++		map_generic_timer_interrupt(gtdt->non_secure_el2_interrupt,
++		gtdt->non_secure_el2_flags);
++
++	/* Get the frequency from CNTFRQ */
++	arch_timer_detect_rate(NULL, NULL);
++
++	/* Always-on capability */
++	arch_timer_c3stop = !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON);
++
++	arch_timer_init();
++	return 0;
++}
++
++/* Initialize all the generic timers presented in GTDT */
++void __init acpi_generic_timer_init(void)
++{
++	if (acpi_disabled)
++		return;
++
++	acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
++}
++#endif
+diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c
+index 954b9f6..a1f7e55 100644
+--- a/drivers/gpio/devres.c
++++ b/drivers/gpio/devres.c
+@@ -109,6 +109,40 @@ struct gpio_desc *__must_check __devm_gpiod_get_index(struct device *dev,
+ EXPORT_SYMBOL(__devm_gpiod_get_index);
+ 
+ /**
++ * devm_get_named_gpiod_from_child - managed dev_get_named_gpiod_from_child()
++ * @dev:	GPIO consumer
++ * @child:	firmware node (child of @dev)
++ * @propname:	name of the firmware property
++ * @index:	index of the GPIO in the property value in case of many
++ *
++ * GPIO descriptors returned from this function are automatically disposed on
++ * driver detach.
++ */
++struct gpio_desc *devm_get_named_gpiod_from_child(struct device *dev, void *child,
++						  const char *propname, int index)
++{
++	struct gpio_desc **dr;
++	struct gpio_desc *desc;
++
++	dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
++			  GFP_KERNEL);
++	if (!dr)
++		return ERR_PTR(-ENOMEM);
++
++	desc = dev_get_named_gpiod_from_child(dev, child, propname, index);
++	if (IS_ERR(desc)) {
++		devres_free(dr);
++		return desc;
++	}
++
++	*dr = desc;
++	devres_add(dev, dr);
++
++	return desc;
++}
++EXPORT_SYMBOL(devm_get_named_gpiod_from_child);
++
++/**
+  * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
+  * @dev: GPIO consumer
+  * @con_id: function within the GPIO consumer
+diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
+index 41e91d7..99720c8 100644
+--- a/drivers/gpio/gpio-sch.c
++++ b/drivers/gpio/gpio-sch.c
+@@ -29,290 +29,221 @@
+ 
+ #include <linux/gpio.h>
+ 
+-static DEFINE_SPINLOCK(gpio_lock);
 -
+-#define CGEN	(0x00)
+-#define CGIO	(0x04)
+-#define CGLV	(0x08)
 -
--/* SerDes RxTx register offsets */
--#define RXTX_REG20			0x0050
--#define RXTX_REG114			0x01c8
+-#define RGEN	(0x20)
+-#define RGIO	(0x24)
+-#define RGLV	(0x28)
+-
+-static unsigned short gpio_ba;
+-
+-static int sch_gpio_core_direction_in(struct gpio_chip *gc, unsigned  gpio_num)
+-{
+-	u8 curr_dirs;
+-	unsigned short offset, bit;
+-
+-	spin_lock(&gpio_lock);
+-
+-	offset = CGIO + gpio_num / 8;
+-	bit = gpio_num % 8;
+-
+-	curr_dirs = inb(gpio_ba + offset);
+-
+-	if (!(curr_dirs & (1 << bit)))
+-		outb(curr_dirs | (1 << bit), gpio_ba + offset);
++#define GEN	0x00
++#define GIO	0x04
++#define GLV	0x08
++
++struct sch_gpio {
++	struct gpio_chip chip;
++	spinlock_t lock;
++	unsigned short iobase;
++	unsigned short core_base;
++	unsigned short resume_base;
++};
+ 
+-	spin_unlock(&gpio_lock);
+-	return 0;
+-}
++#define to_sch_gpio(c)	container_of(c, struct sch_gpio, chip)
+ 
+-static int sch_gpio_core_get(struct gpio_chip *gc, unsigned gpio_num)
++static unsigned sch_gpio_offset(struct sch_gpio *sch, unsigned gpio,
++				unsigned reg)
+ {
+-	int res;
+-	unsigned short offset, bit;
++	unsigned base = 0;
+ 
+-	offset = CGLV + gpio_num / 8;
+-	bit = gpio_num % 8;
++	if (gpio >= sch->resume_base) {
++		gpio -= sch->resume_base;
++		base += 0x20;
++	}
+ 
+-	res = !!(inb(gpio_ba + offset) & (1 << bit));
+-	return res;
++	return base + reg + gpio / 8;
+ }
+ 
+-static void sch_gpio_core_set(struct gpio_chip *gc, unsigned gpio_num, int val)
++static unsigned sch_gpio_bit(struct sch_gpio *sch, unsigned gpio)
+ {
+-	u8 curr_vals;
+-	unsigned short offset, bit;
+-
+-	spin_lock(&gpio_lock);
+-
+-	offset = CGLV + gpio_num / 8;
+-	bit = gpio_num % 8;
+-
+-	curr_vals = inb(gpio_ba + offset);
+-
+-	if (val)
+-		outb(curr_vals | (1 << bit), gpio_ba + offset);
+-	else
+-		outb((curr_vals & ~(1 << bit)), gpio_ba + offset);
+-	spin_unlock(&gpio_lock);
++	if (gpio >= sch->resume_base)
++		gpio -= sch->resume_base;
++	return gpio % 8;
+ }
+ 
+-static int sch_gpio_core_direction_out(struct gpio_chip *gc,
+-					unsigned gpio_num, int val)
++static void sch_gpio_enable(struct sch_gpio *sch, unsigned gpio)
+ {
+-	u8 curr_dirs;
+ 	unsigned short offset, bit;
++	u8 enable;
+ 
+-	spin_lock(&gpio_lock);
++	spin_lock(&sch->lock);
+ 
+-	offset = CGIO + gpio_num / 8;
+-	bit = gpio_num % 8;
+-
+-	curr_dirs = inb(gpio_ba + offset);
+-	if (curr_dirs & (1 << bit))
+-		outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
++	offset = sch_gpio_offset(sch, gpio, GEN);
++	bit = sch_gpio_bit(sch, gpio);
+ 
+-	spin_unlock(&gpio_lock);
++	enable = inb(sch->iobase + offset);
++	if (!(enable & (1 << bit)))
++		outb(enable | (1 << bit), sch->iobase + offset);
+ 
+-	/*
+-	 * according to the datasheet, writing to the level register has no
+-	 * effect when GPIO is programmed as input.
+-	 * Actually the the level register is read-only when configured as input.
+-	 * Thus presetting the output level before switching to output is _NOT_ possible.
+-	 * Hence we set the level after configuring the GPIO as output.
+-	 * But we cannot prevent a short low pulse if direction is set to high
+-	 * and an external pull-up is connected.
+-	 */
+-	sch_gpio_core_set(gc, gpio_num, val);
+-	return 0;
++	spin_unlock(&sch->lock);
+ }
+ 
+-static struct gpio_chip sch_gpio_core = {
+-	.label			= "sch_gpio_core",
+-	.owner			= THIS_MODULE,
+-	.direction_input	= sch_gpio_core_direction_in,
+-	.get			= sch_gpio_core_get,
+-	.direction_output	= sch_gpio_core_direction_out,
+-	.set			= sch_gpio_core_set,
+-};
+-
+-static int sch_gpio_resume_direction_in(struct gpio_chip *gc,
+-					unsigned gpio_num)
++static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned  gpio_num)
+ {
++	struct sch_gpio *sch = to_sch_gpio(gc);
+ 	u8 curr_dirs;
+ 	unsigned short offset, bit;
+ 
+-	spin_lock(&gpio_lock);
++	spin_lock(&sch->lock);
+ 
+-	offset = RGIO + gpio_num / 8;
+-	bit = gpio_num % 8;
++	offset = sch_gpio_offset(sch, gpio_num, GIO);
++	bit = sch_gpio_bit(sch, gpio_num);
+ 
+-	curr_dirs = inb(gpio_ba + offset);
++	curr_dirs = inb(sch->iobase + offset);
+ 
+ 	if (!(curr_dirs & (1 << bit)))
+-		outb(curr_dirs | (1 << bit), gpio_ba + offset);
++		outb(curr_dirs | (1 << bit), sch->iobase + offset);
+ 
+-	spin_unlock(&gpio_lock);
++	spin_unlock(&sch->lock);
+ 	return 0;
+ }
+ 
+-static int sch_gpio_resume_get(struct gpio_chip *gc, unsigned gpio_num)
++static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
+ {
++	struct sch_gpio *sch = to_sch_gpio(gc);
++	int res;
+ 	unsigned short offset, bit;
+ 
+-	offset = RGLV + gpio_num / 8;
+-	bit = gpio_num % 8;
++	offset = sch_gpio_offset(sch, gpio_num, GLV);
++	bit = sch_gpio_bit(sch, gpio_num);
++
++	res = !!(inb(sch->iobase + offset) & (1 << bit));
+ 
+-	return !!(inb(gpio_ba + offset) & (1 << bit));
++	return res;
+ }
+ 
+-static void sch_gpio_resume_set(struct gpio_chip *gc,
+-				unsigned gpio_num, int val)
++static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
+ {
++	struct sch_gpio *sch = to_sch_gpio(gc);
+ 	u8 curr_vals;
+ 	unsigned short offset, bit;
+ 
+-	spin_lock(&gpio_lock);
++	spin_lock(&sch->lock);
+ 
+-	offset = RGLV + gpio_num / 8;
+-	bit = gpio_num % 8;
++	offset = sch_gpio_offset(sch, gpio_num, GLV);
++	bit = sch_gpio_bit(sch, gpio_num);
+ 
+-	curr_vals = inb(gpio_ba + offset);
++	curr_vals = inb(sch->iobase + offset);
+ 
+ 	if (val)
+-		outb(curr_vals | (1 << bit), gpio_ba + offset);
++		outb(curr_vals | (1 << bit), sch->iobase + offset);
+ 	else
+-		outb((curr_vals & ~(1 << bit)), gpio_ba + offset);
++		outb((curr_vals & ~(1 << bit)), sch->iobase + offset);
+ 
+-	spin_unlock(&gpio_lock);
++	spin_unlock(&sch->lock);
+ }
+ 
+-static int sch_gpio_resume_direction_out(struct gpio_chip *gc,
+-					unsigned gpio_num, int val)
++static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
++				  int val)
+ {
++	struct sch_gpio *sch = to_sch_gpio(gc);
+ 	u8 curr_dirs;
+ 	unsigned short offset, bit;
+ 
+-	offset = RGIO + gpio_num / 8;
+-	bit = gpio_num % 8;
++	spin_lock(&sch->lock);
+ 
+-	spin_lock(&gpio_lock);
++	offset = sch_gpio_offset(sch, gpio_num, GIO);
++	bit = sch_gpio_bit(sch, gpio_num);
+ 
+-	curr_dirs = inb(gpio_ba + offset);
++	curr_dirs = inb(sch->iobase + offset);
+ 	if (curr_dirs & (1 << bit))
+-		outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
++		outb(curr_dirs & ~(1 << bit), sch->iobase + offset);
+ 
+-	spin_unlock(&gpio_lock);
++	spin_unlock(&sch->lock);
+ 
+ 	/*
+-	* according to the datasheet, writing to the level register has no
+-	* effect when GPIO is programmed as input.
+-	* Actually the the level register is read-only when configured as input.
+-	* Thus presetting the output level before switching to output is _NOT_ possible.
+-	* Hence we set the level after configuring the GPIO as output.
+-	* But we cannot prevent a short low pulse if direction is set to high
+-	* and an external pull-up is connected.
+-	*/
+-	sch_gpio_resume_set(gc, gpio_num, val);
++	 * according to the datasheet, writing to the level register has no
++	 * effect when GPIO is programmed as input.
++	 * Actually the the level register is read-only when configured as input.
++	 * Thus presetting the output level before switching to output is _NOT_ possible.
++	 * Hence we set the level after configuring the GPIO as output.
++	 * But we cannot prevent a short low pulse if direction is set to high
++	 * and an external pull-up is connected.
++	 */
++	sch_gpio_set(gc, gpio_num, val);
+ 	return 0;
+ }
+ 
+-static struct gpio_chip sch_gpio_resume = {
+-	.label			= "sch_gpio_resume",
++static struct gpio_chip sch_gpio_chip = {
++	.label			= "sch_gpio",
+ 	.owner			= THIS_MODULE,
+-	.direction_input	= sch_gpio_resume_direction_in,
+-	.get			= sch_gpio_resume_get,
+-	.direction_output	= sch_gpio_resume_direction_out,
+-	.set			= sch_gpio_resume_set,
++	.direction_input	= sch_gpio_direction_in,
++	.get			= sch_gpio_get,
++	.direction_output	= sch_gpio_direction_out,
++	.set			= sch_gpio_set,
+ };
+ 
+ static int sch_gpio_probe(struct platform_device *pdev)
+ {
++	struct sch_gpio *sch;
+ 	struct resource *res;
+-	int err, id;
+ 
+-	id = pdev->id;
+-	if (!id)
+-		return -ENODEV;
++	sch = devm_kzalloc(&pdev->dev, sizeof(*sch), GFP_KERNEL);
++	if (!sch)
++		return -ENOMEM;
+ 
+ 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ 	if (!res)
+ 		return -EBUSY;
+ 
+-	if (!request_region(res->start, resource_size(res), pdev->name))
++	if (!devm_request_region(&pdev->dev, res->start, resource_size(res),
++				 pdev->name))
+ 		return -EBUSY;
+ 
+-	gpio_ba = res->start;
++	spin_lock_init(&sch->lock);
++	sch->iobase = res->start;
++	sch->chip = sch_gpio_chip;
++	sch->chip.label = dev_name(&pdev->dev);
++	sch->chip.dev = &pdev->dev;
+ 
+-	switch (id) {
++	switch (pdev->id) {
+ 	case PCI_DEVICE_ID_INTEL_SCH_LPC:
+-		sch_gpio_core.base = 0;
+-		sch_gpio_core.ngpio = 10;
+-		sch_gpio_resume.base = 10;
+-		sch_gpio_resume.ngpio = 4;
++		sch->core_base = 0;
++		sch->resume_base = 10;
++		sch->chip.ngpio = 14;
++
+ 		/*
+ 		 * GPIO[6:0] enabled by default
+ 		 * GPIO7 is configured by the CMC as SLPIOVR
+ 		 * Enable GPIO[9:8] core powered gpios explicitly
+ 		 */
+-		outb(0x3, gpio_ba + CGEN + 1);
++		sch_gpio_enable(sch, 8);
++		sch_gpio_enable(sch, 9);
+ 		/*
+ 		 * SUS_GPIO[2:0] enabled by default
+ 		 * Enable SUS_GPIO3 resume powered gpio explicitly
+ 		 */
+-		outb(0x8, gpio_ba + RGEN);
++		sch_gpio_enable(sch, 13);
+ 		break;
+ 
+ 	case PCI_DEVICE_ID_INTEL_ITC_LPC:
+-		sch_gpio_core.base = 0;
+-		sch_gpio_core.ngpio = 5;
+-		sch_gpio_resume.base = 5;
+-		sch_gpio_resume.ngpio = 9;
++		sch->core_base = 0;
++		sch->resume_base = 5;
++		sch->chip.ngpio = 14;
+ 		break;
+ 
+ 	case PCI_DEVICE_ID_INTEL_CENTERTON_ILB:
+-		sch_gpio_core.base = 0;
+-		sch_gpio_core.ngpio = 21;
+-		sch_gpio_resume.base = 21;
+-		sch_gpio_resume.ngpio = 9;
++		sch->core_base = 0;
++		sch->resume_base = 21;
++		sch->chip.ngpio = 30;
+ 		break;
+ 
+ 	default:
+-		err = -ENODEV;
+-		goto err_sch_gpio_core;
++		return -ENODEV;
+ 	}
+ 
+-	sch_gpio_core.dev = &pdev->dev;
+-	sch_gpio_resume.dev = &pdev->dev;
+-
+-	err = gpiochip_add(&sch_gpio_core);
+-	if (err < 0)
+-		goto err_sch_gpio_core;
++	platform_set_drvdata(pdev, sch);
+ 
+-	err = gpiochip_add(&sch_gpio_resume);
+-	if (err < 0)
+-		goto err_sch_gpio_resume;
+-
+-	return 0;
 -
--/* SerDes RxTx register entry bit positions and sizes */
--#define RXTX_REG20_BLWC_ENA_INDEX	2
--#define RXTX_REG20_BLWC_ENA_WIDTH	1
--#define RXTX_REG114_PQ_REG_INDEX	9
--#define RXTX_REG114_PQ_REG_WIDTH	7
+-err_sch_gpio_resume:
+-	gpiochip_remove(&sch_gpio_core);
 -
--#define RXTX_10000_BLWC			0
--#define RXTX_10000_PQ			0x1e
+-err_sch_gpio_core:
+-	release_region(res->start, resource_size(res));
+-	gpio_ba = 0;
 -
--#define RXTX_2500_BLWC			1
--#define RXTX_2500_PQ			0xa
+-	return err;
++	return gpiochip_add(&sch->chip);
+ }
+ 
+ static int sch_gpio_remove(struct platform_device *pdev)
+ {
+-	struct resource *res;
+-	if (gpio_ba) {
 -
--#define RXTX_1000_BLWC			1
--#define RXTX_1000_PQ			0xa
+-		gpiochip_remove(&sch_gpio_core);
+-		gpiochip_remove(&sch_gpio_resume);
 -
--/* Bit setting and getting macros
-- *  The get macro will extract the current bit field value from within
-- *  the variable
-- *
-- *  The set macro will clear the current bit field value within the
-- *  variable and then set the bit field of the variable to the
-- *  specified value
-- */
- #define GET_BITS(_var, _index, _width)					\
- 	(((_var) >> (_index)) & ((0x1 << (_width)) - 1))
+-		res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+-
+-		release_region(res->start, resource_size(res));
+-		gpio_ba = 0;
+-	}
++	struct sch_gpio *sch = platform_get_drvdata(pdev);
  
-@@ -198,71 +129,12 @@ do {									\
- 	(_var) |= (((_val) & ((0x1 << (_width)) - 1)) << (_index));	\
- } while (0)
++	gpiochip_remove(&sch->chip);
+ 	return 0;
+ }
  
--#define XSIR_GET_BITS(_var, _prefix, _field)				\
--	GET_BITS((_var),						\
--		 _prefix##_##_field##_INDEX,				\
--		 _prefix##_##_field##_WIDTH)
+diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
+index 05c6275..8aa6ca4 100644
+--- a/drivers/gpio/gpiolib-acpi.c
++++ b/drivers/gpio/gpiolib-acpi.c
+@@ -290,6 +290,7 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
+ struct acpi_gpio_lookup {
+ 	struct acpi_gpio_info info;
+ 	int index;
++	int pin_index;
+ 	struct gpio_desc *desc;
+ 	int n;
+ };
+@@ -303,13 +304,24 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
+ 
+ 	if (lookup->n++ == lookup->index && !lookup->desc) {
+ 		const struct acpi_resource_gpio *agpio = &ares->data.gpio;
++		int pin_index = lookup->pin_index;
++
++		if (pin_index >= agpio->pin_table_length)
++			return 1;
+ 
+ 		lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
+-					      agpio->pin_table[0]);
++					      agpio->pin_table[pin_index]);
+ 		lookup->info.gpioint =
+ 			agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
+-		lookup->info.active_low =
+-			agpio->polarity == ACPI_ACTIVE_LOW;
++
++		/*
++		 * ActiveLow is only specified for GpioInt resource. If
++		 * GpioIo is used then the only way to set the flag is
++		 * to use _DSD "gpios" property.
++		 */
++		if (lookup->info.gpioint)
++			lookup->info.active_low =
++				agpio->polarity == ACPI_ACTIVE_LOW;
+ 	}
+ 
+ 	return 1;
+@@ -317,40 +329,75 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
+ 
+ /**
+  * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources
+- * @dev: pointer to a device to get GPIO from
++ * @adev: pointer to a ACPI device to get GPIO from
++ * @propname: Property name of the GPIO (optional)
+  * @index: index of GpioIo/GpioInt resource (starting from %0)
+  * @info: info pointer to fill in (optional)
+  *
+- * Function goes through ACPI resources for @dev and based on @index looks
++ * Function goes through ACPI resources for @adev and based on @index looks
+  * up a GpioIo/GpioInt resource, translates it to the Linux GPIO descriptor,
+  * and returns it. @index matches GpioIo/GpioInt resources only so if there
+  * are total %3 GPIO resources, the index goes from %0 to %2.
+  *
++ * If @propname is specified the GPIO is looked using device property. In
++ * that case @index is used to select the GPIO entry in the property value
++ * (in case of multiple).
++ *
+  * If the GPIO cannot be translated or there is an error an ERR_PTR is
+  * returned.
+  *
+  * Note: if the GPIO resource has multiple entries in the pin list, this
+  * function only returns the first.
+  */
+-struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
++struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
++					  const char *propname, int index,
+ 					  struct acpi_gpio_info *info)
+ {
+ 	struct acpi_gpio_lookup lookup;
+ 	struct list_head resource_list;
+-	struct acpi_device *adev;
+-	acpi_handle handle;
++	bool active_low = false;
+ 	int ret;
+ 
+-	if (!dev)
+-		return ERR_PTR(-EINVAL);
 -
--#define XSIR_SET_BITS(_var, _prefix, _field, _val)			\
--	SET_BITS((_var),						\
--		 _prefix##_##_field##_INDEX,				\
--		 _prefix##_##_field##_WIDTH, (_val))
-+#define XCMU_IOREAD(_priv, _reg)					\
-+	ioread16((_priv)->cmu_regs + _reg)
+-	handle = ACPI_HANDLE(dev);
+-	if (!handle || acpi_bus_get_device(handle, &adev))
++	if (!adev)
+ 		return ERR_PTR(-ENODEV);
  
--/* Macros for reading or writing SerDes integration registers
-- *  The ioread macros will get bit fields or full values using the
-- *  register definitions formed using the input names
-- *
-- *  The iowrite macros will set bit fields or full values using the
-- *  register definitions formed using the input names
-- */
--#define XSIR0_IOREAD(_priv, _reg)					\
--	ioread16((_priv)->sir0_regs + _reg)
-+#define XCMU_IOWRITE(_priv, _reg, _val)					\
-+	iowrite16((_val), (_priv)->cmu_regs + _reg)
+ 	memset(&lookup, 0, sizeof(lookup));
+ 	lookup.index = index;
  
--#define XSIR0_IOREAD_BITS(_priv, _reg, _field)				\
--	GET_BITS(XSIR0_IOREAD((_priv), _reg),				\
--		 _reg##_##_field##_INDEX,				\
--		 _reg##_##_field##_WIDTH)
++	if (propname) {
++		struct acpi_reference_args args;
++
++		dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname);
++
++		memset(&args, 0, sizeof(args));
++		ret = acpi_dev_get_property_reference(adev, propname, NULL,
++						      index, &args);
++		if (ret)
++			return ERR_PTR(ret);
++
++		/*
++		 * The property was found and resolved so need to
++		 * lookup the GPIO based on returned args instead.
++		 */
++		adev = args.adev;
++		if (args.nargs >= 2) {
++			lookup.index = args.args[0];
++			lookup.pin_index = args.args[1];
++			/*
++			 * 3rd argument, if present is used to
++			 * specify active_low.
++			 */
++			if (args.nargs >= 3)
++				active_low = !!args.args[2];
++		}
++
++		dev_dbg(&adev->dev, "GPIO: _DSD returned %s %zd %llu %llu %llu\n",
++			dev_name(&adev->dev), args.nargs,
++			args.args[0], args.args[1], args.args[2]);
++	} else {
++		dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index);
++	}
++
+ 	INIT_LIST_HEAD(&resource_list);
+ 	ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio,
+ 				     &lookup);
+@@ -359,8 +406,11 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
+ 
+ 	acpi_dev_free_resource_list(&resource_list);
+ 
+-	if (lookup.desc && info)
++	if (lookup.desc && info) {
+ 		*info = lookup.info;
++		if (active_low)
++			info->active_low = active_low;
++	}
+ 
+ 	return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT);
+ }
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index e8e98ca..0fa5f79 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -1505,14 +1505,36 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id,
+ 					unsigned int idx,
+ 					enum gpio_lookup_flags *flags)
+ {
++	static const char * const suffixes[] = { "gpios", "gpio" };
++	struct acpi_device *adev = ACPI_COMPANION(dev);
+ 	struct acpi_gpio_info info;
+ 	struct gpio_desc *desc;
++	char propname[32];
++	int i;
+ 
+-	desc = acpi_get_gpiod_by_index(dev, idx, &info);
+-	if (IS_ERR(desc))
+-		return desc;
++	/* Try first from _DSD */
++	for (i = 0; i < ARRAY_SIZE(suffixes); i++) {
++		if (con_id && strcmp(con_id, "gpios")) {
++			snprintf(propname, sizeof(propname), "%s-%s",
++				 con_id, suffixes[i]);
++		} else {
++			snprintf(propname, sizeof(propname), "%s",
++				 suffixes[i]);
++		}
++
++		desc = acpi_get_gpiod_by_index(adev, propname, 0, &info);
++		if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER))
++			break;
++	}
+ 
+-	if (info.gpioint && info.active_low)
++	/* Then from plain _CRS GPIOs */
++	if (IS_ERR(desc)) {
++		desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info);
++		if (IS_ERR(desc))
++			return desc;
++	}
++
++	if (info.active_low)
+ 		*flags |= GPIO_ACTIVE_LOW;
+ 
+ 	return desc;
+@@ -1713,6 +1735,62 @@ struct gpio_desc *__must_check __gpiod_get_index(struct device *dev,
+ EXPORT_SYMBOL_GPL(__gpiod_get_index);
+ 
+ /**
++ * dev_get_named_gpiod_from_child - obtain a GPIO from firmware node
++ * @dev:	parent device
++ * @child:	firmware node (child of @dev)
++ * @propname:	name of the firmware property
++ * @idx:	index of the GPIO in the property value in case of many
++ *
++ * This function can be used for drivers that get their configuration
++ * from firmware in such a way that some properties are described as child
++ * nodes for the parent device in DT or ACPI.
++ *
++ * Function properly finds the corresponding GPIO using whatever is the
++ * underlying firmware interface and then makes sure that the GPIO
++ * descriptor is requested before it is returned to the caller.
++ *
++ * In case of error an ERR_PTR() is returned.
++ */
++struct gpio_desc *dev_get_named_gpiod_from_child(struct device *dev, void *child,
++						 const char *propname, int index)
++{
++	struct gpio_desc *desc = ERR_PTR(-ENODEV);
++	bool active_low = false;
++	int ret;
++
++	if (!child)
++		return ERR_PTR(-EINVAL);
++
++	if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
++		enum of_gpio_flags flags;
++
++		desc = of_get_named_gpiod_flags(child, propname, index, &flags);
++		if (!IS_ERR(desc))
++			active_low = flags & OF_GPIO_ACTIVE_LOW;
++	} else if (ACPI_COMPANION(dev)) {
++		struct acpi_gpio_info info;
++
++		desc = acpi_get_gpiod_by_index(child, propname, index, &info);
++		if (!IS_ERR(desc))
++			active_low = info.active_low;
++	}
++
++	if (IS_ERR(desc))
++		return desc;
++
++	ret = gpiod_request(desc, NULL);
++	if (ret)
++		return ERR_PTR(ret);
++
++	/* Only value flag can be set from both DT and ACPI is active_low */
++	if (active_low)
++		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
++
++	return desc;
++}
++EXPORT_SYMBOL_GPL(dev_get_named_gpiod_from_child);
++
++/**
+  * gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO
+  *                            function
+  * @dev: GPIO consumer, can be NULL for system-global GPIOs
+diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
+index 9db2b6a..e3a5211 100644
+--- a/drivers/gpio/gpiolib.h
++++ b/drivers/gpio/gpiolib.h
+@@ -34,7 +34,8 @@ void acpi_gpiochip_remove(struct gpio_chip *chip);
+ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip);
+ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
+ 
+-struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
++struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
++					  const char *propname, int index,
+ 					  struct acpi_gpio_info *info);
+ #else
+ static inline void acpi_gpiochip_add(struct gpio_chip *chip) { }
+@@ -47,8 +48,8 @@ static inline void
+ acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { }
+ 
+ static inline struct gpio_desc *
+-acpi_get_gpiod_by_index(struct device *dev, int index,
+-			struct acpi_gpio_info *info)
++acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname,
++			int index, struct acpi_gpio_info *info)
+ {
+ 	return ERR_PTR(-ENOSYS);
+ }
+diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c
+index 432d363..3563850 100644
+--- a/drivers/input/keyboard/gpio_keys_polled.c
++++ b/drivers/input/keyboard/gpio_keys_polled.c
+@@ -23,10 +23,9 @@
+ #include <linux/ioport.h>
+ #include <linux/platform_device.h>
+ #include <linux/gpio.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/gpio_keys.h>
+-#include <linux/of.h>
+-#include <linux/of_platform.h>
+-#include <linux/of_gpio.h>
++#include <linux/property.h>
+ 
+ #define DRV_NAME	"gpio-keys-polled"
+ 
+@@ -51,15 +50,14 @@ static void gpio_keys_polled_check_state(struct input_dev *input,
+ 	int state;
+ 
+ 	if (bdata->can_sleep)
+-		state = !!gpio_get_value_cansleep(button->gpio);
++		state = !!gpiod_get_value_cansleep(button->gpiod);
+ 	else
+-		state = !!gpio_get_value(button->gpio);
++		state = !!gpiod_get_value(button->gpiod);
+ 
+ 	if (state != bdata->last_state) {
+ 		unsigned int type = button->type ?: EV_KEY;
+ 
+-		input_event(input, type, button->code,
+-			    !!(state ^ button->active_low));
++		input_event(input, type, button->code, state);
+ 		input_sync(input);
+ 		bdata->count = 0;
+ 		bdata->last_state = state;
+@@ -102,21 +100,57 @@ static void gpio_keys_polled_close(struct input_polled_dev *dev)
+ 		pdata->disable(bdev->dev);
+ }
+ 
+-#ifdef CONFIG_OF
++static int gpio_keys_polled_get_button(struct device *dev, void *child,
++				       void *data)
++{
++	struct gpio_keys_platform_data *pdata = data;
++	struct gpio_keys_button *button;
++	struct gpio_desc *desc;
++
++	desc = devm_get_named_gpiod_from_child(dev, child, "gpios", 0);
++	if (IS_ERR(desc)) {
++		int err = PTR_ERR(desc);
++
++		if (err != -EPROBE_DEFER)
++			dev_err(dev, "Failed to get gpio flags, error: %d\n",
++				err);
++		return err;
++	}
++
++	button = &pdata->buttons[pdata->nbuttons++];
++	button->gpiod = desc;
++
++	if (device_child_property_read_u32(dev, child, "linux,code",
++					   &button->code)) {
++		dev_err(dev, "Button without keycode: %d\n",
++			pdata->nbuttons - 1);
++		return -EINVAL;
++	}
++
++	device_child_property_read_string(dev, child, "label", &button->desc);
++
++	if (device_child_property_read_u32(dev, child, "linux,input-type",
++					   &button->type))
++		button->type = EV_KEY;
++
++	button->wakeup = !device_get_child_property(dev, child,
++						    "gpio-key,wakeup", NULL);
++
++	if (device_child_property_read_u32(dev, child, "debounce-interval",
++					   &button->debounce_interval))
++		button->debounce_interval = 5;
++
++	return 0;
++}
++
+ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct device *dev)
+ {
+-	struct device_node *node, *pp;
+ 	struct gpio_keys_platform_data *pdata;
+ 	struct gpio_keys_button *button;
+ 	int error;
+ 	int nbuttons;
+-	int i;
 -
--#define XSIR0_IOWRITE(_priv, _reg, _val)				\
--	iowrite16((_val), (_priv)->sir0_regs + _reg)
+-	node = dev->of_node;
+-	if (!node)
+-		return NULL;
+ 
+-	nbuttons = of_get_child_count(node);
++	nbuttons = device_get_child_node_count(dev);
+ 	if (nbuttons == 0)
+ 		return NULL;
+ 
+@@ -126,54 +160,14 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct
+ 		return ERR_PTR(-ENOMEM);
+ 
+ 	pdata->buttons = (struct gpio_keys_button *)(pdata + 1);
+-	pdata->nbuttons = nbuttons;
+ 
+-	pdata->rep = !!of_get_property(node, "autorepeat", NULL);
+-	of_property_read_u32(node, "poll-interval", &pdata->poll_interval);
++	pdata->rep = !device_get_property(dev, "autorepeat", NULL);
++	device_property_read_u32(dev, "poll-interval", &pdata->poll_interval);
+ 
+-	i = 0;
+-	for_each_child_of_node(node, pp) {
+-		int gpio;
+-		enum of_gpio_flags flags;
 -
--#define XSIR0_IOWRITE_BITS(_priv, _reg, _field, _val)			\
--do {									\
--	u16 reg_val = XSIR0_IOREAD((_priv), _reg);			\
--	SET_BITS(reg_val,						\
--		 _reg##_##_field##_INDEX,				\
--		 _reg##_##_field##_WIDTH, (_val));			\
--	XSIR0_IOWRITE((_priv), _reg, reg_val);				\
--} while (0)
+-		if (!of_find_property(pp, "gpios", NULL)) {
+-			pdata->nbuttons--;
+-			dev_warn(dev, "Found button without gpios\n");
+-			continue;
+-		}
 -
--#define XSIR1_IOREAD(_priv, _reg)					\
--	ioread16((_priv)->sir1_regs + _reg)
+-		gpio = of_get_gpio_flags(pp, 0, &flags);
+-		if (gpio < 0) {
+-			error = gpio;
+-			if (error != -EPROBE_DEFER)
+-				dev_err(dev,
+-					"Failed to get gpio flags, error: %d\n",
+-					error);
+-			return ERR_PTR(error);
+-		}
 -
--#define XSIR1_IOREAD_BITS(_priv, _reg, _field)				\
--	GET_BITS(XSIR1_IOREAD((_priv), _reg),				\
--		 _reg##_##_field##_INDEX,				\
--		 _reg##_##_field##_WIDTH)
+-		button = &pdata->buttons[i++];
 -
--#define XSIR1_IOWRITE(_priv, _reg, _val)				\
--	iowrite16((_val), (_priv)->sir1_regs + _reg)
+-		button->gpio = gpio;
+-		button->active_low = flags & OF_GPIO_ACTIVE_LOW;
 -
--#define XSIR1_IOWRITE_BITS(_priv, _reg, _field, _val)			\
--do {									\
--	u16 reg_val = XSIR1_IOREAD((_priv), _reg);			\
--	SET_BITS(reg_val,						\
--		 _reg##_##_field##_INDEX,				\
--		 _reg##_##_field##_WIDTH, (_val));			\
--	XSIR1_IOWRITE((_priv), _reg, reg_val);				\
--} while (0)
+-		if (of_property_read_u32(pp, "linux,code", &button->code)) {
+-			dev_err(dev, "Button without keycode: 0x%x\n",
+-				button->gpio);
+-			return ERR_PTR(-EINVAL);
+-		}
 -
+-		button->desc = of_get_property(pp, "label", NULL);
 -
--/* Macros for reading or writing SerDes RxTx registers
-- *  The ioread macros will get bit fields or full values using the
-- *  register definitions formed using the input names
-- *
-- *  The iowrite macros will set bit fields or full values using the
-- *  register definitions formed using the input names
-- */
- #define XRXTX_IOREAD(_priv, _reg)					\
- 	ioread16((_priv)->rxtx_regs + _reg)
+-		if (of_property_read_u32(pp, "linux,input-type", &button->type))
+-			button->type = EV_KEY;
+-
+-		button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);
+-
+-		if (of_property_read_u32(pp, "debounce-interval",
+-					 &button->debounce_interval))
+-			button->debounce_interval = 5;
+-	}
++	error = device_for_each_child_node(dev, gpio_keys_polled_get_button,
++					   pdata);
++	if (error)
++		return ERR_PTR(error);
+ 
+ 	if (pdata->nbuttons == 0)
+ 		return ERR_PTR(-EINVAL);
+@@ -187,14 +181,11 @@ static const struct of_device_id gpio_keys_polled_of_match[] = {
+ };
+ MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match);
+ 
+-#else
+-
+-static inline struct gpio_keys_platform_data *
+-gpio_keys_polled_get_devtree_pdata(struct device *dev)
+-{
+-	return NULL;
+-}
+-#endif
++static const struct acpi_device_id gpio_keys_polled_acpi_match[] = {
++	{ "PRP0001" }, /* Device Tree shoehorned into ACPI */
++	{ },
++};
++MODULE_DEVICE_TABLE(acpi, gpio_keys_polled_acpi_match);
+ 
+ static int gpio_keys_polled_probe(struct platform_device *pdev)
+ {
+@@ -259,7 +250,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
+ 	for (i = 0; i < pdata->nbuttons; i++) {
+ 		struct gpio_keys_button *button = &pdata->buttons[i];
+ 		struct gpio_keys_button_data *bdata = &bdev->data[i];
+-		unsigned int gpio = button->gpio;
+ 		unsigned int type = button->type ?: EV_KEY;
+ 
+ 		if (button->wakeup) {
+@@ -267,15 +257,31 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
+ 			return -EINVAL;
+ 		}
+ 
+-		error = devm_gpio_request_one(&pdev->dev, gpio, GPIOF_IN,
+-					      button->desc ? : DRV_NAME);
+-		if (error) {
+-			dev_err(dev, "unable to claim gpio %u, err=%d\n",
+-				gpio, error);
+-			return error;
++		/*
++		 * Legacy GPIO number so request the GPIO here and
++		 * convert it to descriptor.
++		 */
++		if (!button->gpiod && gpio_is_valid(button->gpio)) {
++			unsigned flags = 0;
++
++			if (button->active_low)
++				flags |= GPIOF_ACTIVE_LOW;
++
++			error = devm_gpio_request_one(&pdev->dev, button->gpio,
++					flags, button->desc ? : DRV_NAME);
++			if (error) {
++				dev_err(dev, "unable to claim gpio %u, err=%d\n",
++					button->gpio, error);
++				return error;
++			}
++
++			button->gpiod = gpio_to_desc(button->gpio);
+ 		}
+ 
+-		bdata->can_sleep = gpio_cansleep(gpio);
++		if (IS_ERR(button->gpiod))
++			return PTR_ERR(button->gpiod);
++
++		bdata->can_sleep = gpiod_cansleep(button->gpiod);
+ 		bdata->last_state = -1;
+ 		bdata->threshold = DIV_ROUND_UP(button->debounce_interval,
+ 						pdata->poll_interval);
+@@ -308,7 +314,8 @@ static struct platform_driver gpio_keys_polled_driver = {
+ 	.driver	= {
+ 		.name	= DRV_NAME,
+ 		.owner	= THIS_MODULE,
+-		.of_match_table = of_match_ptr(gpio_keys_polled_of_match),
++		.of_match_table = gpio_keys_polled_of_match,
++		.acpi_match_table = gpio_keys_polled_acpi_match,
+ 	},
+ };
+ module_platform_driver(gpio_keys_polled_driver);
+diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
+index aa17ae8..d330dab 100644
+--- a/drivers/irqchip/irq-gic-v3.c
++++ b/drivers/irqchip/irq-gic-v3.c
+@@ -506,9 +506,19 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
+ 	isb();
+ }
+ 
++#ifdef CONFIG_ARM_PARKING_PROTOCOL
++static void gic_wakeup_parked_cpu(int cpu)
++{
++	gic_raise_softirq(cpumask_of(cpu), 0);
++}
++#endif
++
+ static void gic_smp_init(void)
+ {
+ 	set_smp_cross_call(gic_raise_softirq);
++#ifdef CONFIG_ARM_PARKING_PROTOCOL
++	set_smp_boot_wakeup_call(gic_wakeup_parked_cpu);
++#endif
+ 	register_cpu_notifier(&gic_cpu_notifier);
+ }
+ 
+diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
+index 38493ff..26e6773 100644
+--- a/drivers/irqchip/irq-gic.c
++++ b/drivers/irqchip/irq-gic.c
+@@ -33,12 +33,14 @@
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
++#include <linux/acpi.h>
+ #include <linux/irqdomain.h>
+ #include <linux/interrupt.h>
+ #include <linux/percpu.h>
+ #include <linux/slab.h>
+ #include <linux/irqchip/chained_irq.h>
+ #include <linux/irqchip/arm-gic.h>
++#include <linux/irqchip/arm-gic-acpi.h>
  
-@@ -283,6 +155,77 @@ do {									\
- 	XRXTX_IOWRITE((_priv), _reg, reg_val);				\
- } while (0)
+ #include <asm/cputype.h>
+ #include <asm/irq.h>
+@@ -641,6 +643,13 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
  
-+/* SerDes CMU register offsets */
-+#define CMU_REG15			0x003c
-+#define CMU_REG16			0x0040
+ 	raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
+ }
 +
-+/* SerDes CMU register entry bit positions and sizes */
-+#define CMU_REG16_TX_RATE_CHANGE_BASE	15
-+#define CMU_REG16_RX_RATE_CHANGE_BASE	14
-+#define CMU_REG16_RATE_CHANGE_DECR	2
++#ifdef CONFIG_ARM_PARKING_PROTOCOL
++static void gic_wakeup_parked_cpu(int cpu)
++{
++	gic_raise_softirq(cpumask_of(cpu), GIC_DIST_SOFTINT_NSATT);
++}
++#endif
+ #endif
+ 
+ #ifdef CONFIG_BL_SWITCHER
+@@ -996,6 +1005,9 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
+ #ifdef CONFIG_SMP
+ 		set_smp_cross_call(gic_raise_softirq);
+ 		register_cpu_notifier(&gic_cpu_notifier);
++#ifdef CONFIG_ARM_PARKING_PROTOCOL
++		set_smp_boot_wakeup_call(gic_wakeup_parked_cpu);
++#endif
+ #endif
+ 		set_handle_irq(gic_handle_irq);
+ 	}
+@@ -1048,3 +1060,107 @@ IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
+ IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
+ 
+ #endif
 +
++#ifdef CONFIG_ACPI
++static phys_addr_t dist_phy_base, cpu_phy_base;
++static int cpu_base_assigned;
 +
-+/* SerDes RxTx register offsets */
-+#define RXTX_REG2			0x0008
-+#define RXTX_REG3			0x000c
-+#define RXTX_REG5			0x0014
-+#define RXTX_REG6			0x0018
-+#define RXTX_REG20			0x0050
-+#define RXTX_REG53			0x00d4
-+#define RXTX_REG114			0x01c8
-+#define RXTX_REG115			0x01cc
-+#define RXTX_REG142			0x0238
++static int __init
++gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
++			const unsigned long end)
++{
++	struct acpi_madt_generic_interrupt *processor;
++	phys_addr_t gic_cpu_base;
 +
-+/* SerDes RxTx register entry bit positions and sizes */
-+#define RXTX_REG2_RESETB_INDEX			15
-+#define RXTX_REG2_RESETB_WIDTH			1
-+#define RXTX_REG3_TX_DATA_RATE_INDEX		14
-+#define RXTX_REG3_TX_DATA_RATE_WIDTH		2
-+#define RXTX_REG3_TX_WORD_MODE_INDEX		11
-+#define RXTX_REG3_TX_WORD_MODE_WIDTH		3
-+#define RXTX_REG5_TXAMP_CNTL_INDEX		7
-+#define RXTX_REG5_TXAMP_CNTL_WIDTH		4
-+#define RXTX_REG6_RX_DATA_RATE_INDEX		9
-+#define RXTX_REG6_RX_DATA_RATE_WIDTH		2
-+#define RXTX_REG6_RX_WORD_MODE_INDEX		11
-+#define RXTX_REG6_RX_WORD_MODE_WIDTH		3
-+#define RXTX_REG20_BLWC_ENA_INDEX		2
-+#define RXTX_REG20_BLWC_ENA_WIDTH		1
-+#define RXTX_REG53_RX_PLLSELECT_INDEX		15
-+#define RXTX_REG53_RX_PLLSELECT_WIDTH		1
-+#define RXTX_REG53_TX_PLLSELECT_INDEX		14
-+#define RXTX_REG53_TX_PLLSELECT_WIDTH		1
-+#define RXTX_REG53_PI_SPD_SEL_CDR_INDEX		10
-+#define RXTX_REG53_PI_SPD_SEL_CDR_WIDTH		4
-+#define RXTX_REG114_PQ_REG_INDEX		9
-+#define RXTX_REG114_PQ_REG_WIDTH		7
-+#define RXTX_REG115_FORCE_LAT_CAL_START_INDEX	2
-+#define RXTX_REG115_FORCE_LAT_CAL_START_WIDTH	1
-+#define RXTX_REG115_FORCE_SUM_CAL_START_INDEX	1
-+#define RXTX_REG115_FORCE_SUM_CAL_START_WIDTH	1
-+#define RXTX_REG142_SUM_CALIB_DONE_INDEX	15
-+#define RXTX_REG142_SUM_CALIB_DONE_WIDTH	1
-+#define RXTX_REG142_SUM_CALIB_ERR_INDEX		14
-+#define RXTX_REG142_SUM_CALIB_ERR_WIDTH		1
-+#define RXTX_REG142_LAT_CALIB_DONE_INDEX	11
-+#define RXTX_REG142_LAT_CALIB_DONE_WIDTH	1
++	processor = (struct acpi_madt_generic_interrupt *)header;
 +
-+#define RXTX_FULL_RATE				0x0
-+#define RXTX_HALF_RATE				0x1
-+#define RXTX_FIFTH_RATE				0x3
-+#define RXTX_66BIT_WORD				0x7
-+#define RXTX_10BIT_WORD				0x1
-+#define RXTX_10G_TX_AMP				0xa
-+#define RXTX_1G_TX_AMP				0xf
-+#define RXTX_10G_CDR				0x7
-+#define RXTX_1G_CDR				0x2
-+#define RXTX_10G_PLL				0x1
-+#define RXTX_1G_PLL				0x0
-+#define RXTX_10G_PQ				0x1e
-+#define RXTX_1G_PQ				0xa
++	if (BAD_MADT_ENTRY(processor, end))
++		return -EINVAL;
 +
++	/*
++	 * There is no support for non-banked GICv1/2 register in ACPI spec.
++	 * All CPU interface addresses have to be the same.
++	 */
++	gic_cpu_base = processor->base_address;
++	if (cpu_base_assigned && gic_cpu_base != cpu_phy_base)
++		return -EFAULT;
 +
-+DEFINE_SPINLOCK(cmu_lock);
- 
- enum amd_xgbe_phy_an {
- 	AMD_XGBE_AN_READY = 0,
-@@ -321,18 +264,18 @@ struct amd_xgbe_phy_priv {
- 
- 	/* SerDes related mmio resources */
- 	struct resource *rxtx_res;
--	struct resource *sir0_res;
--	struct resource *sir1_res;
-+	struct resource *cmu_res;
- 
- 	/* SerDes related mmio registers */
- 	void __iomem *rxtx_regs;	/* SerDes Rx/Tx CSRs */
--	void __iomem *sir0_regs;	/* SerDes integration registers (1/2) */
--	void __iomem *sir1_regs;	/* SerDes integration registers (2/2) */
-+	void __iomem *cmu_regs;		/* SerDes CMU CSRs */
++	cpu_phy_base = gic_cpu_base;
++	cpu_base_assigned = 1;
++	return 0;
++}
 +
-+	unsigned int serdes_channel;
-+	unsigned int speed_set;
- 
- 	/* Maintain link status for re-starting auto-negotiation */
- 	unsigned int link;
- 	enum amd_xgbe_phy_mode mode;
--	unsigned int speed_set;
++static int __init
++gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
++				const unsigned long end)
++{
++	struct acpi_madt_generic_distributor *dist;
++
++	dist = (struct acpi_madt_generic_distributor *)header;
++
++	if (BAD_MADT_ENTRY(dist, end))
++		return -EINVAL;
++
++	dist_phy_base = dist->base_address;
++	return 0;
++}
++
++int __init
++gic_v2_acpi_init(struct acpi_table_header *table)
++{
++	void __iomem *cpu_base, *dist_base;
++	int count;
++
++	/* Collect CPU base addresses */
++	count = acpi_parse_entries(sizeof(struct acpi_table_madt),
++				   gic_acpi_parse_madt_cpu, table,
++				   ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
++	if (count < 0) {
++		pr_err("Error during GICC entries parsing\n");
++		return -EFAULT;
++	} else if (!count) {
++		pr_err("No valid GICC entries exist\n");
++		return -EINVAL;
++	}
++
++	/*
++	 * Find distributor base address. We expect one distributor entry since
++	 * ACPI 5.1 spec neither support multi-GIC instances nor GIC cascade.
++	 */
++	count = acpi_parse_entries(sizeof(struct acpi_table_madt),
++				   gic_acpi_parse_madt_distributor, table,
++				   ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
++	if (count <= 0) {
++		pr_err("Error during GICD entries parsing\n");
++		return -EFAULT;
++	} else if (!count) {
++		pr_err("No valid GICD entries exist\n");
++		return -EINVAL;
++	} else if (count > 1) {
++		pr_err("More than one GICD entry detected\n");
++		return -EINVAL;
++	}
++
++	cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
++	if (!cpu_base) {
++		pr_err("Unable to map GICC registers\n");
++		return -ENOMEM;
++	}
++
++	dist_base = ioremap(dist_phy_base, ACPI_GICV2_DIST_MEM_SIZE);
++	if (!dist_base) {
++		pr_err("Unable to map GICD registers\n");
++		iounmap(cpu_base);
++		return -ENOMEM;
++	}
++
++	/*
++	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
++	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
++	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
++	 */
++	gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL);
++	irq_set_default_host(gic_data[0].domain);
++	return 0;
++}
++#endif
+diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c
+index 0fe2f71..9106c6d 100644
+--- a/drivers/irqchip/irqchip.c
++++ b/drivers/irqchip/irqchip.c
+@@ -11,6 +11,7 @@
+ #include <linux/init.h>
+ #include <linux/of_irq.h>
+ #include <linux/irqchip.h>
++#include <linux/irqchip/arm-gic-acpi.h>
  
- 	/* Auto-negotiation state machine support */
- 	struct mutex an_mutex;
-@@ -394,33 +337,51 @@ static int amd_xgbe_phy_pcs_power_cycle(struct phy_device *phydev)
- static void amd_xgbe_phy_serdes_start_ratechange(struct phy_device *phydev)
+ /*
+  * This special of_device_id is the sentinel at the end of the
+@@ -26,4 +27,6 @@ extern struct of_device_id __irqchip_of_table[];
+ void __init irqchip_init(void)
  {
- 	struct amd_xgbe_phy_priv *priv = phydev->priv;
-+	u16 val, mask;
+ 	of_irq_init(__irqchip_of_table);
 +
-+	/* Assert Rx and Tx ratechange in CMU_reg16 */
-+	val = XCMU_IOREAD(priv, CMU_REG16);
++	acpi_gic_init();
+ }
+diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
+index 57ff20f..681efd5 100644
+--- a/drivers/leds/leds-gpio.c
++++ b/drivers/leds/leds-gpio.c
+@@ -13,22 +13,20 @@
+ #include <linux/kernel.h>
+ #include <linux/platform_device.h>
+ #include <linux/gpio.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/leds.h>
+-#include <linux/of.h>
+-#include <linux/of_platform.h>
+-#include <linux/of_gpio.h>
+ #include <linux/slab.h>
+ #include <linux/workqueue.h>
+ #include <linux/module.h>
+ #include <linux/err.h>
++#include <linux/property.h>
+ 
+ struct gpio_led_data {
+ 	struct led_classdev cdev;
+-	unsigned gpio;
++	struct gpio_desc *gpiod;
+ 	struct work_struct work;
+ 	u8 new_level;
+ 	u8 can_sleep;
+-	u8 active_low;
+ 	u8 blinking;
+ 	int (*platform_gpio_blink_set)(unsigned gpio, int state,
+ 			unsigned long *delay_on, unsigned long *delay_off);
+@@ -40,12 +38,16 @@ static void gpio_led_work(struct work_struct *work)
+ 		container_of(work, struct gpio_led_data, work);
+ 
+ 	if (led_dat->blinking) {
+-		led_dat->platform_gpio_blink_set(led_dat->gpio,
+-						 led_dat->new_level,
+-						 NULL, NULL);
++		int gpio = desc_to_gpio(led_dat->gpiod);
++		int level = led_dat->new_level;
++
++		if (gpiod_is_active_low(led_dat->gpiod))
++			level = !level;
++
++		led_dat->platform_gpio_blink_set(gpio, level, NULL, NULL);
+ 		led_dat->blinking = 0;
+ 	} else
+-		gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level);
++		gpiod_set_value_cansleep(led_dat->gpiod, led_dat->new_level);
+ }
  
--	/* Assert Rx and Tx ratechange */
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, RATECHANGE, 1);
-+	mask = (1 << (CMU_REG16_TX_RATE_CHANGE_BASE -
-+		      (priv->serdes_channel * CMU_REG16_RATE_CHANGE_DECR))) |
-+	       (1 << (CMU_REG16_RX_RATE_CHANGE_BASE -
-+		      (priv->serdes_channel * CMU_REG16_RATE_CHANGE_DECR)));
-+	val |= mask;
-+
-+	XCMU_IOWRITE(priv, CMU_REG16, val);
+ static void gpio_led_set(struct led_classdev *led_cdev,
+@@ -60,9 +62,6 @@ static void gpio_led_set(struct led_classdev *led_cdev,
+ 	else
+ 		level = 1;
+ 
+-	if (led_dat->active_low)
+-		level = !level;
+-
+ 	/* Setting GPIOs with I2C/etc requires a task context, and we don't
+ 	 * seem to have a reliable way to know if we're already in one; so
+ 	 * let's just assume the worst.
+@@ -72,11 +71,16 @@ static void gpio_led_set(struct led_classdev *led_cdev,
+ 		schedule_work(&led_dat->work);
+ 	} else {
+ 		if (led_dat->blinking) {
+-			led_dat->platform_gpio_blink_set(led_dat->gpio, level,
+-							 NULL, NULL);
++			int gpio = desc_to_gpio(led_dat->gpiod);
++
++			if (gpiod_is_active_low(led_dat->gpiod))
++				level = !level;
++
++			led_dat->platform_gpio_blink_set(gpio, level, NULL,
++							 NULL);
+ 			led_dat->blinking = 0;
+ 		} else
+-			gpio_set_value(led_dat->gpio, level);
++			gpiod_set_value(led_dat->gpiod, level);
+ 	}
+ }
+ 
+@@ -85,9 +89,10 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
+ {
+ 	struct gpio_led_data *led_dat =
+ 		container_of(led_cdev, struct gpio_led_data, cdev);
++	int gpio = desc_to_gpio(led_dat->gpiod);
+ 
+ 	led_dat->blinking = 1;
+-	return led_dat->platform_gpio_blink_set(led_dat->gpio, GPIO_LED_BLINK,
++	return led_dat->platform_gpio_blink_set(gpio, GPIO_LED_BLINK,
+ 						delay_on, delay_off);
  }
  
- static void amd_xgbe_phy_serdes_complete_ratechange(struct phy_device *phydev)
+@@ -97,24 +102,33 @@ static int create_gpio_led(const struct gpio_led *template,
  {
- 	struct amd_xgbe_phy_priv *priv = phydev->priv;
-+	u16 val, mask;
- 	unsigned int wait;
--	u16 status;
+ 	int ret, state;
  
--	/* Release Rx and Tx ratechange */
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, RATECHANGE, 0);
-+	/* Release Rx and Tx ratechange for proper channel in CMU_reg16 */
-+	val = XCMU_IOREAD(priv, CMU_REG16);
-+
-+	mask = (1 << (CMU_REG16_TX_RATE_CHANGE_BASE -
-+		      (priv->serdes_channel * CMU_REG16_RATE_CHANGE_DECR))) |
-+	       (1 << (CMU_REG16_RX_RATE_CHANGE_BASE -
-+		      (priv->serdes_channel * CMU_REG16_RATE_CHANGE_DECR)));
-+	val &= ~mask;
+-	led_dat->gpio = -1;
++	if (!template->gpiod) {
++		unsigned long flags = 0;
  
--	/* Wait for Rx and Tx ready */
-+	XCMU_IOWRITE(priv, CMU_REG16, val);
+-	/* skip leds that aren't available */
+-	if (!gpio_is_valid(template->gpio)) {
+-		dev_info(parent, "Skipping unavailable LED gpio %d (%s)\n",
+-				template->gpio, template->name);
+-		return 0;
+-	}
++		/* skip leds that aren't available */
++		if (!gpio_is_valid(template->gpio)) {
++			dev_info(parent, "Skipping unavailable LED gpio %d (%s)\n",
++					template->gpio, template->name);
++			return 0;
++		}
+ 
+-	ret = devm_gpio_request(parent, template->gpio, template->name);
+-	if (ret < 0)
+-		return ret;
++		if (template->active_low)
++			flags |= GPIOF_ACTIVE_LOW;
 +
-+	/* Wait for Rx and Tx ready in CMU_reg15 */
-+	mask = (1 << priv->serdes_channel) |
-+	       (1 << (priv->serdes_channel + 8));
- 	wait = XGBE_PHY_RATECHANGE_COUNT;
- 	while (wait--) {
--		usleep_range(50, 75);
-+		udelay(50);
++		ret = devm_gpio_request_one(parent, template->gpio, flags,
++					    template->name);
++		if (ret < 0)
++			return ret;
++
++		led_dat->gpiod = gpio_to_desc(template->gpio);
++		if (IS_ERR(led_dat->gpiod))
++			return PTR_ERR(led_dat->gpiod);
++	}
  
--		status = XSIR0_IOREAD(priv, SIR0_STATUS);
--		if (XSIR_GET_BITS(status, SIR0_STATUS, RX_READY) &&
--		    XSIR_GET_BITS(status, SIR0_STATUS, TX_READY))
-+		val = XCMU_IOREAD(priv, CMU_REG15);
-+		if ((val & mask) == mask)
- 			return;
+ 	led_dat->cdev.name = template->name;
+ 	led_dat->cdev.default_trigger = template->default_trigger;
+-	led_dat->gpio = template->gpio;
+-	led_dat->can_sleep = gpio_cansleep(template->gpio);
+-	led_dat->active_low = template->active_low;
++	led_dat->gpiod = template->gpiod;
++	led_dat->can_sleep = gpiod_cansleep(template->gpiod);
+ 	led_dat->blinking = 0;
+ 	if (blink_set) {
+ 		led_dat->platform_gpio_blink_set = blink_set;
+@@ -122,30 +136,24 @@ static int create_gpio_led(const struct gpio_led *template,
  	}
+ 	led_dat->cdev.brightness_set = gpio_led_set;
+ 	if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP)
+-		state = !!gpio_get_value_cansleep(led_dat->gpio) ^ led_dat->active_low;
++		state = !!gpiod_get_value_cansleep(led_dat->gpiod);
+ 	else
+ 		state = (template->default_state == LEDS_GPIO_DEFSTATE_ON);
+ 	led_dat->cdev.brightness = state ? LED_FULL : LED_OFF;
+ 	if (!template->retain_state_suspended)
+ 		led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
  
- 	netdev_dbg(phydev->attached_dev, "SerDes rx/tx not ready (%#hx)\n",
--		   status);
-+		   val);
- }
- 
- static int amd_xgbe_phy_xgmii_mode(struct phy_device *phydev)
-@@ -428,8 +389,8 @@ static int amd_xgbe_phy_xgmii_mode(struct phy_device *phydev)
- 	struct amd_xgbe_phy_priv *priv = phydev->priv;
- 	int ret;
- 
--	/* Enable KR training */
--	ret = amd_xgbe_an_enable_kr_training(phydev);
-+	/* Disable KR training */
-+	ret = amd_xgbe_an_disable_kr_training(phydev);
+-	ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state);
++	ret = gpiod_direction_output(led_dat->gpiod, state);
  	if (ret < 0)
  		return ret;
  
-@@ -455,19 +416,30 @@ static int amd_xgbe_phy_xgmii_mode(struct phy_device *phydev)
- 		return ret;
+ 	INIT_WORK(&led_dat->work, gpio_led_work);
  
- 	/* Set SerDes to 10G speed */
-+	spin_lock(&cmu_lock);
-+
- 	amd_xgbe_phy_serdes_start_ratechange(phydev);
+-	ret = led_classdev_register(parent, &led_dat->cdev);
+-	if (ret < 0)
+-		return ret;
+-
+-	return 0;
++	return led_classdev_register(parent, &led_dat->cdev);
+ }
  
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, DATARATE, SPEED_10000_RATE);
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, WORDMODE, SPEED_10000_WORD);
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, TXAMP, SPEED_10000_TXAMP);
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, PLLSEL, SPEED_10000_PLL);
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, PI_SPD_SEL, SPEED_10000_CDR);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_DATA_RATE, RXTX_FULL_RATE);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_WORD_MODE, RXTX_66BIT_WORD);
-+
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG5, TXAMP_CNTL, RXTX_10G_TX_AMP);
-+
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_DATA_RATE, RXTX_FULL_RATE);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_WORD_MODE, RXTX_66BIT_WORD);
+ static void delete_gpio_led(struct gpio_led_data *led)
+ {
+-	if (!gpio_is_valid(led->gpio))
+-		return;
+ 	led_classdev_unregister(&led->cdev);
+ 	cancel_work_sync(&led->work);
+ }
+@@ -161,65 +169,59 @@ static inline int sizeof_gpio_leds_priv(int num_leds)
+ 		(sizeof(struct gpio_led_data) * num_leds);
+ }
  
--	XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA, RXTX_10000_BLWC);
--	XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG, RXTX_10000_PQ);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA, 0);
+-/* Code to create from OpenFirmware platform devices */
+-#ifdef CONFIG_OF_GPIO
+-static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
++static int gpio_leds_create_led(struct device *dev, void *child, void *data)
++{
++	struct gpio_leds_priv *priv = data;
++	struct gpio_led led = {};
++	const char *state = NULL;
++
++	led.gpiod = devm_get_named_gpiod_from_child(dev, child, "gpios", 0);
++	if (IS_ERR(led.gpiod))
++		return PTR_ERR(led.gpiod);
++
++	device_child_property_read_string(dev, child, "label", &led.name);
++	device_child_property_read_string(dev, child, "linux,default-trigger",
++					  &led.default_trigger);
++
++	device_child_property_read_string(dev, child, "linux,default_state",
++					  &state);
++	if (state) {
++		if (!strcmp(state, "keep"))
++			led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
++		else if (!strcmp(state, "on"))
++			led.default_state = LEDS_GPIO_DEFSTATE_ON;
++		else
++			led.default_state = LEDS_GPIO_DEFSTATE_OFF;
++	}
 +
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, RX_PLLSELECT, RXTX_10G_PLL);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, TX_PLLSELECT, RXTX_10G_PLL);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, PI_SPD_SEL_CDR, RXTX_10G_CDR);
++	if (!device_get_child_property(dev, child, "retain-state-suspended", NULL))
++		led.retain_state_suspended = 1;
 +
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG, RXTX_10G_PQ);
++	return create_gpio_led(&led, &priv->leds[priv->num_leds++], dev, NULL);
++}
++
++static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
+ {
+-	struct device_node *np = pdev->dev.of_node, *child;
+ 	struct gpio_leds_priv *priv;
+-	int count, ret;
++	int ret, count;
+ 
+-	/* count LEDs in this device, so we know how much to allocate */
+-	count = of_get_available_child_count(np);
++	count = device_get_child_node_count(&pdev->dev);
+ 	if (!count)
+ 		return ERR_PTR(-ENODEV);
+ 
+-	for_each_available_child_of_node(np, child)
+-		if (of_get_gpio(child, 0) == -EPROBE_DEFER)
+-			return ERR_PTR(-EPROBE_DEFER);
+-
+ 	priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count),
+ 			GFP_KERNEL);
+ 	if (!priv)
+ 		return ERR_PTR(-ENOMEM);
+ 
+-	for_each_available_child_of_node(np, child) {
+-		struct gpio_led led = {};
+-		enum of_gpio_flags flags;
+-		const char *state;
+-
+-		led.gpio = of_get_gpio_flags(child, 0, &flags);
+-		led.active_low = flags & OF_GPIO_ACTIVE_LOW;
+-		led.name = of_get_property(child, "label", NULL) ? : child->name;
+-		led.default_trigger =
+-			of_get_property(child, "linux,default-trigger", NULL);
+-		state = of_get_property(child, "default-state", NULL);
+-		if (state) {
+-			if (!strcmp(state, "keep"))
+-				led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
+-			else if (!strcmp(state, "on"))
+-				led.default_state = LEDS_GPIO_DEFSTATE_ON;
+-			else
+-				led.default_state = LEDS_GPIO_DEFSTATE_OFF;
+-		}
+-
+-		if (of_get_property(child, "retain-state-suspended", NULL))
+-			led.retain_state_suspended = 1;
+-
+-		ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
+-				      &pdev->dev, NULL);
+-		if (ret < 0) {
+-			of_node_put(child);
+-			goto err;
+-		}
++	ret = device_for_each_child_node(&pdev->dev, gpio_leds_create_led, priv);
++	if (ret) {
++		for (count = priv->num_leds - 2; count >= 0; count--)
++			delete_gpio_led(&priv->leds[count]);
++		return ERR_PTR(ret);
+ 	}
  
- 	amd_xgbe_phy_serdes_complete_ratechange(phydev);
+ 	return priv;
+-
+-err:
+-	for (count = priv->num_leds - 2; count >= 0; count--)
+-		delete_gpio_led(&priv->leds[count]);
+-	return ERR_PTR(-ENODEV);
+ }
  
-+	spin_unlock(&cmu_lock);
+ static const struct of_device_id of_gpio_leds_match[] = {
+@@ -228,13 +230,13 @@ static const struct of_device_id of_gpio_leds_match[] = {
+ };
+ 
+ MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
+-#else /* CONFIG_OF_GPIO */
+-static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
+-{
+-	return ERR_PTR(-ENODEV);
+-}
+-#endif /* CONFIG_OF_GPIO */
+ 
++static const struct acpi_device_id acpi_gpio_leds_match[] = {
++	{ "PRP0001" }, /* Device Tree shoehorned into ACPI */
++	{},
++};
 +
- 	priv->mode = AMD_XGBE_MODE_KR;
++MODULE_DEVICE_TABLE(acpi, acpi_gpio_leds_match);
+ 
+ static int gpio_led_probe(struct platform_device *pdev)
+ {
+@@ -263,7 +265,7 @@ static int gpio_led_probe(struct platform_device *pdev)
+ 			}
+ 		}
+ 	} else {
+-		priv = gpio_leds_create_of(pdev);
++		priv = gpio_leds_create(pdev);
+ 		if (IS_ERR(priv))
+ 			return PTR_ERR(priv);
+ 	}
+@@ -290,7 +292,8 @@ static struct platform_driver gpio_led_driver = {
+ 	.driver		= {
+ 		.name	= "leds-gpio",
+ 		.owner	= THIS_MODULE,
+-		.of_match_table = of_match_ptr(of_gpio_leds_match),
++		.of_match_table = of_gpio_leds_match,
++		.acpi_match_table = acpi_gpio_leds_match,
+ 	},
+ };
+ 
+diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
+index 634f729..1a760cd 100644
+--- a/drivers/misc/eeprom/at25.c
++++ b/drivers/misc/eeprom/at25.c
+@@ -18,7 +18,7 @@
+ 
+ #include <linux/spi/spi.h>
+ #include <linux/spi/eeprom.h>
+-#include <linux/of.h>
++#include <linux/property.h>
+ 
+ /*
+  * NOTE: this is an *EEPROM* driver.  The vagaries of product naming
+@@ -301,35 +301,33 @@ static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf,
+ 
+ /*-------------------------------------------------------------------------*/
  
+-static int at25_np_to_chip(struct device *dev,
+-			   struct device_node *np,
+-			   struct spi_eeprom *chip)
++static int at25_fw_to_chip(struct device *dev, struct spi_eeprom *chip)
+ {
+ 	u32 val;
+ 
+ 	memset(chip, 0, sizeof(*chip));
+-	strncpy(chip->name, np->name, sizeof(chip->name));
++	strncpy(chip->name, "at25", sizeof(chip->name));
+ 
+-	if (of_property_read_u32(np, "size", &val) == 0 ||
+-	    of_property_read_u32(np, "at25,byte-len", &val) == 0) {
++	if (device_property_read_u32(dev, "size", &val) == 0 ||
++	    device_property_read_u32(dev, "at25,byte-len", &val) == 0) {
+ 		chip->byte_len = val;
+ 	} else {
+ 		dev_err(dev, "Error: missing \"size\" property\n");
+ 		return -ENODEV;
+ 	}
+ 
+-	if (of_property_read_u32(np, "pagesize", &val) == 0 ||
+-	    of_property_read_u32(np, "at25,page-size", &val) == 0) {
++	if (device_property_read_u32(dev, "pagesize", &val) == 0 ||
++	    device_property_read_u32(dev, "at25,page-size", &val) == 0) {
+ 		chip->page_size = (u16)val;
+ 	} else {
+ 		dev_err(dev, "Error: missing \"pagesize\" property\n");
+ 		return -ENODEV;
+ 	}
+ 
+-	if (of_property_read_u32(np, "at25,addr-mode", &val) == 0) {
++	if (device_property_read_u32(dev, "at25,addr-mode", &val) == 0) {
+ 		chip->flags = (u16)val;
+ 	} else {
+-		if (of_property_read_u32(np, "address-width", &val)) {
++		if (device_property_read_u32(dev, "address-width", &val)) {
+ 			dev_err(dev,
+ 				"Error: missing \"address-width\" property\n");
+ 			return -ENODEV;
+@@ -350,7 +348,7 @@ static int at25_np_to_chip(struct device *dev,
+ 				val);
+ 			return -ENODEV;
+ 		}
+-		if (of_find_property(np, "read-only", NULL))
++		if (!device_get_property(dev, "read-only", NULL))
+ 			chip->flags |= EE_READONLY;
+ 	}
  	return 0;
-@@ -505,19 +477,30 @@ static int amd_xgbe_phy_gmii_2500_mode(struct phy_device *phydev)
- 		return ret;
+@@ -360,21 +358,15 @@ static int at25_probe(struct spi_device *spi)
+ {
+ 	struct at25_data	*at25 = NULL;
+ 	struct spi_eeprom	chip;
+-	struct device_node	*np = spi->dev.of_node;
+ 	int			err;
+ 	int			sr;
+ 	int			addrlen;
+ 
+ 	/* Chip description */
+ 	if (!spi->dev.platform_data) {
+-		if (np) {
+-			err = at25_np_to_chip(&spi->dev, np, &chip);
+-			if (err)
+-				return err;
+-		} else {
+-			dev_err(&spi->dev, "Error: no chip description\n");
+-			return -ENODEV;
+-		}
++		err = at25_fw_to_chip(&spi->dev, &chip);
++		if (err)
++			return err;
+ 	} else
+ 		chip = *(struct spi_eeprom *)spi->dev.platform_data;
  
- 	/* Set SerDes to 2.5G speed */
-+	spin_lock(&cmu_lock);
+@@ -467,11 +459,18 @@ static const struct of_device_id at25_of_match[] = {
+ };
+ MODULE_DEVICE_TABLE(of, at25_of_match);
+ 
++static const struct acpi_device_id at25_acpi_match[] = {
++	{ "PRP0001" },
++	{ }
++};
++MODULE_DEVICE_TABLE(acpi, at25_acpi_match);
++
+ static struct spi_driver at25_driver = {
+ 	.driver = {
+ 		.name		= "at25",
+ 		.owner		= THIS_MODULE,
+ 		.of_match_table = at25_of_match,
++		.acpi_match_table = at25_acpi_match,
+ 	},
+ 	.probe		= at25_probe,
+ 	.remove		= at25_remove,
+diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig
+index 8319c99..6feb6ef3 100644
+--- a/drivers/net/ethernet/amd/Kconfig
++++ b/drivers/net/ethernet/amd/Kconfig
+@@ -179,7 +179,7 @@ config SUNLANCE
+ 
+ config AMD_XGBE
+ 	tristate "AMD 10GbE Ethernet driver"
+-	depends on OF_NET
++	depends on OF_NET || ACPI
+ 	select PHYLIB
+ 	select AMD_XGBE_PHY
+ 	select BITREVERSE
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+index 9da3a03..a34cad2 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+@@ -130,7 +130,7 @@ static unsigned int xgbe_usec_to_riwt(struct xgbe_prv_data *pdata,
+ 
+ 	DBGPR("-->xgbe_usec_to_riwt\n");
+ 
+-	rate = clk_get_rate(pdata->sysclk);
++	rate = pdata->sysclk_rate;
+ 
+ 	/*
+ 	 * Convert the input usec value to the watchdog timer value. Each
+@@ -153,7 +153,7 @@ static unsigned int xgbe_riwt_to_usec(struct xgbe_prv_data *pdata,
+ 
+ 	DBGPR("-->xgbe_riwt_to_usec\n");
+ 
+-	rate = clk_get_rate(pdata->sysclk);
++	rate = pdata->sysclk_rate;
+ 
+ 	/*
+ 	 * Convert the input watchdog timer value to the usec value. Each
+@@ -695,6 +695,18 @@ static int xgbe_read_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
+ 	else
+ 		mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff);
+ 
++	if (XGBE_SEATTLE_A0) {
++		/* The PCS implementation has reversed the devices in
++		 * package registers so we need to change 05 to 06 and
++		 * 06 to 05 if being read (these registers are readonly
++		 * so no need to do this in the write function)
++		 */
++		if ((mmd_address & 0xffff) == 0x05)
++			mmd_address = (mmd_address & ~0xffff) | 0x06;
++		else if ((mmd_address & 0xffff) == 0x06)
++			mmd_address = (mmd_address & ~0xffff) | 0x05;
++	}
 +
- 	amd_xgbe_phy_serdes_start_ratechange(phydev);
+ 	/* The PCS registers are accessed using mmio. The underlying APB3
+ 	 * management interface uses indirect addressing to access the MMD
+ 	 * register sets. This requires accessing of the PCS register in two
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+index 2955499..423ae3d 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+@@ -425,6 +425,9 @@ void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata)
+ 	hw_feat->rx_ch_cnt++;
+ 	hw_feat->tx_ch_cnt++;
  
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, DATARATE, SPEED_2500_RATE);
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, WORDMODE, SPEED_2500_WORD);
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, TXAMP, SPEED_2500_TXAMP);
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, PLLSEL, SPEED_2500_PLL);
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, PI_SPD_SEL, SPEED_2500_CDR);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_DATA_RATE, RXTX_HALF_RATE);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_WORD_MODE, RXTX_10BIT_WORD);
++	/* A0 does not support NUMTC, hardcode it for now */
++	hw_feat->tc_cnt = XGBE_TC_CNT;
 +
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG5, TXAMP_CNTL, RXTX_1G_TX_AMP);
+ 	DBGPR("<--xgbe_get_all_hw_features\n");
+ }
  
--	XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA, RXTX_2500_BLWC);
--	XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG, RXTX_2500_PQ);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_DATA_RATE, RXTX_HALF_RATE);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_WORD_MODE, RXTX_10BIT_WORD);
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+index f5a8fa0..db29dec 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+@@ -124,6 +124,7 @@
+ #include <linux/of.h>
+ #include <linux/of_net.h>
+ #include <linux/clk.h>
++#include <linux/acpi.h>
+ 
+ #include "xgbe.h"
+ #include "xgbe-common.h"
+@@ -215,6 +216,210 @@ static void xgbe_init_all_fptrs(struct xgbe_prv_data *pdata)
+ 	xgbe_init_function_ptrs_desc(&pdata->desc_if);
+ }
+ 
++static int xgbe_map_resources(struct xgbe_prv_data *pdata)
++{
++	struct platform_device *pdev = pdata->pdev;
++	struct device *dev = pdata->dev;
++	struct resource *res;
++
++	/* Obtain the mmio areas for the device */
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	pdata->xgmac_regs = devm_ioremap_resource(dev, res);
++	if (IS_ERR(pdata->xgmac_regs)) {
++		dev_err(dev, "xgmac ioremap failed\n");
++		return PTR_ERR(pdata->xgmac_regs);
++	}
++	DBGPR("  xgmac_regs = %p\n", pdata->xgmac_regs);
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++	pdata->xpcs_regs = devm_ioremap_resource(dev, res);
++	if (IS_ERR(pdata->xpcs_regs)) {
++		dev_err(dev, "xpcs ioremap failed\n");
++		return PTR_ERR(pdata->xpcs_regs);
++	}
++	DBGPR("  xpcs_regs  = %p\n", pdata->xpcs_regs);
++
++	return 0;
++}
++
++#ifdef CONFIG_ACPI
++static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
++{
++	struct acpi_device *adev = pdata->adev;
++	struct device *dev = pdata->dev;
++	const union acpi_object *property;
++	acpi_status status;
++	u64 cca;
++	unsigned int i;
++	int ret;
++
++	/* Map the memory resources */
++	ret = xgbe_map_resources(pdata);
++	if (ret)
++		return ret;
++
++	/* Obtain the system clock setting */
++	ret = acpi_dev_get_property(adev, XGBE_ACPI_DMA_FREQ, ACPI_TYPE_INTEGER,
++				    &property);
++	if (ret) {
++		dev_err(dev, "unable to obtain %s acpi property\n",
++			XGBE_ACPI_DMA_FREQ);
++		return ret;
++	}
++	pdata->sysclk_rate = property->integer.value;
++
++	/* Obtain the PTP clock setting */
++	ret = acpi_dev_get_property(adev, XGBE_ACPI_PTP_FREQ, ACPI_TYPE_INTEGER,
++				    &property);
++	if (ret) {
++		dev_err(dev, "unable to obtain %s acpi property\n",
++			XGBE_ACPI_PTP_FREQ);
++		return ret;
++	}
++	pdata->ptpclk_rate = property->integer.value;
++
++	/* Retrieve the MAC address */
++	ret = acpi_dev_get_property_array(adev, XGBE_ACPI_MAC_ADDR,
++					  ACPI_TYPE_INTEGER, &property);
++	if (ret) {
++		dev_err(dev, "unable to obtain %s acpi property\n",
++			XGBE_ACPI_MAC_ADDR);
++		return ret;
++	}
++	if (property->package.count != 6) {
++		dev_err(dev, "invalid %s acpi property\n",
++			XGBE_ACPI_MAC_ADDR);
++		return -EINVAL;
++	}
++	for (i = 0; i < property->package.count; i++) {
++		union acpi_object *obj = &property->package.elements[i];
++
++		pdata->mac_addr[i] = (u8)obj->integer.value;
++	}
++	if (!is_valid_ether_addr(pdata->mac_addr)) {
++		dev_err(dev, "invalid %s acpi property\n",
++			XGBE_ACPI_MAC_ADDR);
++#if 0
++		return -EINVAL;
++#else
++		dev_err(dev, "invalid MAC address, using random address\n");
++		eth_random_addr(pdata->mac_addr);
++#endif
++	}
++
++	/* Retrieve the PHY mode - it must be "xgmii" */
++	ret = acpi_dev_get_property(adev, XGBE_ACPI_PHY_MODE, ACPI_TYPE_STRING,
++				    &property);
++	if (ret) {
++		dev_err(dev, "unable to obtain %s acpi property\n",
++			XGBE_ACPI_PHY_MODE);
++		return ret;
++	}
++	if (strcmp(property->string.pointer,
++		   phy_modes(PHY_INTERFACE_MODE_XGMII))) {
++		dev_err(dev, "invalid %s acpi property\n",
++			XGBE_ACPI_PHY_MODE);
++		return -EINVAL;
++	}
++	pdata->phy_mode = PHY_INTERFACE_MODE_XGMII;
++
++#ifndef METHOD_NAME__CCA
++#define METHOD_NAME__CCA "_CCA"
++#endif
++	/* Set the device cache coherency values */
++	if (acpi_has_method(adev->handle, METHOD_NAME__CCA)) {
++		status = acpi_evaluate_integer(adev->handle, METHOD_NAME__CCA,
++					       NULL, &cca);
++		if (ACPI_FAILURE(status)) {
++			dev_err(dev, "error obtaining acpi _CCA method\n");
++			return -EINVAL;
++		}
++	} else {
++		cca = 0;
++	}
++
++	if (cca) {
++		pdata->axdomain = XGBE_DMA_OS_AXDOMAIN;
++		pdata->arcache = XGBE_DMA_OS_ARCACHE;
++		pdata->awcache = XGBE_DMA_OS_AWCACHE;
++	} else {
++		pdata->axdomain = XGBE_DMA_SYS_AXDOMAIN;
++		pdata->arcache = XGBE_DMA_SYS_ARCACHE;
++		pdata->awcache = XGBE_DMA_SYS_AWCACHE;
++	}
++
++	return 0;
++}
++#else   /* CONFIG_ACPI */
++static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
++{
++	return -EINVAL;
++}
++#endif  /* CONFIG_ACPI */
 +
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA, 1);
++#ifdef CONFIG_OF
++static int xgbe_of_support(struct xgbe_prv_data *pdata)
++{
++	struct device *dev = pdata->dev;
++	const u8 *mac_addr;
++	int ret;
 +
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, RX_PLLSELECT, RXTX_1G_PLL);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, TX_PLLSELECT, RXTX_1G_PLL);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, PI_SPD_SEL_CDR, RXTX_1G_CDR);
++	/* Map the memory resources */
++	ret = xgbe_map_resources(pdata);
++	if (ret)
++		return ret;
 +
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG, RXTX_1G_PQ);
- 
- 	amd_xgbe_phy_serdes_complete_ratechange(phydev);
- 
-+	spin_unlock(&cmu_lock);
++	/* Obtain the system clock setting */
++	pdata->sysclk = devm_clk_get(dev, XGBE_DMA_CLOCK);
++	if (IS_ERR(pdata->sysclk)) {
++		dev_err(dev, "dma devm_clk_get failed\n");
++		return PTR_ERR(pdata->sysclk);
++	}
++	pdata->sysclk_rate = clk_get_rate(pdata->sysclk);
 +
- 	priv->mode = AMD_XGBE_MODE_KX;
- 
- 	return 0;
-@@ -555,19 +538,30 @@ static int amd_xgbe_phy_gmii_mode(struct phy_device *phydev)
- 		return ret;
- 
- 	/* Set SerDes to 1G speed */
-+	spin_lock(&cmu_lock);
++	/* Obtain the PTP clock setting */
++	pdata->ptpclk = devm_clk_get(dev, XGBE_PTP_CLOCK);
++	if (IS_ERR(pdata->ptpclk)) {
++		dev_err(dev, "ptp devm_clk_get failed\n");
++		return PTR_ERR(pdata->ptpclk);
++	}
++	pdata->ptpclk_rate = clk_get_rate(pdata->ptpclk);
 +
- 	amd_xgbe_phy_serdes_start_ratechange(phydev);
- 
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, DATARATE, SPEED_1000_RATE);
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, WORDMODE, SPEED_1000_WORD);
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, TXAMP, SPEED_1000_TXAMP);
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, PLLSEL, SPEED_1000_PLL);
--	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, PI_SPD_SEL, SPEED_1000_CDR);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_DATA_RATE, RXTX_FIFTH_RATE);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_WORD_MODE, RXTX_10BIT_WORD);
++	/* Retrieve the MAC address */
++	mac_addr = of_get_mac_address(dev->of_node);
++	if (!mac_addr) {
++		dev_err(dev, "invalid mac address for this device\n");
++		return -EINVAL;
++	}
++	memcpy(pdata->mac_addr, mac_addr, ETH_ALEN);
 +
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG5, TXAMP_CNTL, RXTX_1G_TX_AMP);
- 
--	XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA, RXTX_1000_BLWC);
--	XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG, RXTX_1000_PQ);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_DATA_RATE, RXTX_FIFTH_RATE);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_WORD_MODE, RXTX_10BIT_WORD);
++	/* Retrieve the PHY mode - it must be "xgmii" */
++	pdata->phy_mode = of_get_phy_mode(dev->of_node);
++	if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII) {
++		dev_err(dev, "invalid phy-mode specified for this device\n");
++		return -EINVAL;
++	}
 +
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA, 1);
++	/* Set the device cache coherency values */
++	if (of_property_read_bool(dev->of_node, "dma-coherent")) {
++		pdata->axdomain = XGBE_DMA_OS_AXDOMAIN;
++		pdata->arcache = XGBE_DMA_OS_ARCACHE;
++		pdata->awcache = XGBE_DMA_OS_AWCACHE;
++	} else {
++		pdata->axdomain = XGBE_DMA_SYS_AXDOMAIN;
++		pdata->arcache = XGBE_DMA_SYS_ARCACHE;
++		pdata->awcache = XGBE_DMA_SYS_AWCACHE;
++	}
 +
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, RX_PLLSELECT, RXTX_1G_PLL);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, TX_PLLSELECT, RXTX_1G_PLL);
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, PI_SPD_SEL_CDR, RXTX_1G_CDR);
++	return 0;
++}
++#else   /* CONFIG_OF */
++static int xgbe_of_support(struct xgbe_prv_data *pdata)
++{
++	return -EINVAL;
++}
++#endif  /*CONFIG_OF */
 +
-+	XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG, RXTX_1G_PQ);
+ static int xgbe_probe(struct platform_device *pdev)
+ {
+ 	struct xgbe_prv_data *pdata;
+@@ -222,8 +427,6 @@ static int xgbe_probe(struct platform_device *pdev)
+ 	struct xgbe_desc_if *desc_if;
+ 	struct net_device *netdev;
+ 	struct device *dev = &pdev->dev;
+-	struct resource *res;
+-	const u8 *mac_addr;
+ 	int ret;
  
- 	amd_xgbe_phy_serdes_complete_ratechange(phydev);
+ 	DBGPR("--> xgbe_probe\n");
+@@ -239,6 +442,7 @@ static int xgbe_probe(struct platform_device *pdev)
+ 	pdata = netdev_priv(netdev);
+ 	pdata->netdev = netdev;
+ 	pdata->pdev = pdev;
++	pdata->adev = ACPI_COMPANION(dev);
+ 	pdata->dev = dev;
+ 	platform_set_drvdata(pdev, netdev);
+ 
+@@ -264,40 +468,13 @@ static int xgbe_probe(struct platform_device *pdev)
+ 		goto err_io;
+ 	}
  
-+	spin_unlock(&cmu_lock);
-+
- 	priv->mode = AMD_XGBE_MODE_KX;
+-	/* Obtain the system clock setting */
+-	pdata->sysclk = devm_clk_get(dev, XGBE_DMA_CLOCK);
+-	if (IS_ERR(pdata->sysclk)) {
+-		dev_err(dev, "dma devm_clk_get failed\n");
+-		ret = PTR_ERR(pdata->sysclk);
+-		goto err_io;
+-	}
+-
+-	/* Obtain the PTP clock setting */
+-	pdata->ptpclk = devm_clk_get(dev, XGBE_PTP_CLOCK);
+-	if (IS_ERR(pdata->ptpclk)) {
+-		dev_err(dev, "ptp devm_clk_get failed\n");
+-		ret = PTR_ERR(pdata->ptpclk);
+-		goto err_io;
+-	}
+-
+-	/* Obtain the mmio areas for the device */
+-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-	pdata->xgmac_regs = devm_ioremap_resource(dev, res);
+-	if (IS_ERR(pdata->xgmac_regs)) {
+-		dev_err(dev, "xgmac ioremap failed\n");
+-		ret = PTR_ERR(pdata->xgmac_regs);
+-		goto err_io;
+-	}
+-	DBGPR("  xgmac_regs = %p\n", pdata->xgmac_regs);
+-
+-	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+-	pdata->xpcs_regs = devm_ioremap_resource(dev, res);
+-	if (IS_ERR(pdata->xpcs_regs)) {
+-		dev_err(dev, "xpcs ioremap failed\n");
+-		ret = PTR_ERR(pdata->xpcs_regs);
++	/* Obtain device settings */
++	if (pdata->adev && !acpi_disabled)
++		ret = xgbe_acpi_support(pdata);
++	else
++		ret = xgbe_of_support(pdata);
++	if (ret)
+ 		goto err_io;
+-	}
+-	DBGPR("  xpcs_regs  = %p\n", pdata->xpcs_regs);
  
- 	return 0;
-@@ -639,13 +633,9 @@ static enum amd_xgbe_phy_an amd_xgbe_an_tx_training(struct phy_device *phydev,
- 	if (ret < 0)
- 		return AMD_XGBE_AN_ERROR;
+ 	/* Set the DMA mask */
+ 	if (!dev->dma_mask)
+@@ -308,23 +485,16 @@ static int xgbe_probe(struct platform_device *pdev)
+ 		goto err_io;
+ 	}
  
--	XSIR0_IOWRITE_BITS(priv, SIR0_KR_RT_1, RESET, 1);
+-	if (of_property_read_bool(dev->of_node, "dma-coherent")) {
+-		pdata->axdomain = XGBE_DMA_OS_AXDOMAIN;
+-		pdata->arcache = XGBE_DMA_OS_ARCACHE;
+-		pdata->awcache = XGBE_DMA_OS_AWCACHE;
+-	} else {
+-		pdata->axdomain = XGBE_DMA_SYS_AXDOMAIN;
+-		pdata->arcache = XGBE_DMA_SYS_ARCACHE;
+-		pdata->awcache = XGBE_DMA_SYS_AWCACHE;
+-	}
 -
- 	ret |= 0x01;
- 	phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, ret);
- 
--	XSIR0_IOWRITE_BITS(priv, SIR0_KR_RT_1, RESET, 0);
++	/* Get the device interrupt */
+ 	ret = platform_get_irq(pdev, 0);
+ 	if (ret < 0) {
+ 		dev_err(dev, "platform_get_irq failed\n");
+ 		goto err_io;
+ 	}
++
+ 	netdev->irq = ret;
+ 	netdev->base_addr = (unsigned long)pdata->xgmac_regs;
++	memcpy(netdev->dev_addr, pdata->mac_addr, netdev->addr_len);
+ 
+ 	/* Set all the function pointers */
+ 	xgbe_init_all_fptrs(pdata);
+@@ -337,23 +507,6 @@ static int xgbe_probe(struct platform_device *pdev)
+ 	/* Populate the hardware features */
+ 	xgbe_get_all_hw_features(pdata);
+ 
+-	/* Retrieve the MAC address */
+-	mac_addr = of_get_mac_address(dev->of_node);
+-	if (!mac_addr) {
+-		dev_err(dev, "invalid mac address for this device\n");
+-		ret = -EINVAL;
+-		goto err_io;
+-	}
+-	memcpy(netdev->dev_addr, mac_addr, netdev->addr_len);
 -
- 	return AMD_XGBE_AN_EVENT;
+-	/* Retrieve the PHY mode - it must be "xgmii" */
+-	pdata->phy_mode = of_get_phy_mode(dev->of_node);
+-	if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII) {
+-		dev_err(dev, "invalid phy-mode specified for this device\n");
+-		ret = -EINVAL;
+-		goto err_io;
+-	}
+-
+ 	/* Set default configuration data */
+ 	xgbe_default_config(pdata);
+ 
+@@ -531,10 +684,22 @@ static int xgbe_resume(struct device *dev)
  }
+ #endif /* CONFIG_PM */
  
-@@ -1291,21 +1281,33 @@ static int amd_xgbe_phy_probe(struct phy_device *phydev)
- 		goto err_priv;
- 	}
++#ifdef CONFIG_ACPI
++static const struct acpi_device_id xgbe_acpi_match[] = {
++	{ "AMDI8000", 0 },
++	{},
++};
++
++MODULE_DEVICE_TABLE(acpi, xgbe_acpi_match);
++#endif
++
++#ifdef CONFIG_OF
+ static const struct of_device_id xgbe_of_match[] = {
++	{ .compatible = "amd,xgbe-seattle-v0a", },
+ 	{ .compatible = "amd,xgbe-seattle-v1a", },
+ 	{},
+ };
++#endif
  
--	priv->sir0_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
--	priv->sir0_regs = devm_ioremap_resource(dev, priv->sir0_res);
--	if (IS_ERR(priv->sir0_regs)) {
--		dev_err(dev, "sir0 ioremap failed\n");
--		ret = PTR_ERR(priv->sir0_regs);
-+	/* All xgbe phy devices share the CMU registers so retrieve
-+	 * the resource and do the ioremap directly rather than
-+	 * the devm_ioremap_resource call
-+	 */
-+	priv->cmu_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-+	if (!priv->cmu_res) {
-+		dev_err(dev, "cmu invalid resource\n");
-+		ret = -EINVAL;
-+		goto err_rxtx;
-+	}
-+	priv->cmu_regs = devm_ioremap_nocache(dev, priv->cmu_res->start,
-+					      resource_size(priv->cmu_res));
-+	if (!priv->cmu_regs) {
-+		dev_err(dev, "cmu ioremap failed\n");
-+		ret = -ENOMEM;
- 		goto err_rxtx;
- 	}
+ MODULE_DEVICE_TABLE(of, xgbe_of_match);
+ static SIMPLE_DEV_PM_OPS(xgbe_pm_ops, xgbe_suspend, xgbe_resume);
+@@ -542,7 +707,12 @@ static SIMPLE_DEV_PM_OPS(xgbe_pm_ops, xgbe_suspend, xgbe_resume);
+ static struct platform_driver xgbe_driver = {
+ 	.driver = {
+ 		.name = "amd-xgbe",
++#ifdef CONFIG_ACPI
++		.acpi_match_table = xgbe_acpi_match,
++#endif
++#ifdef CONFIG_OF
+ 		.of_match_table = xgbe_of_match,
++#endif
+ 		.pm = &xgbe_pm_ops,
+ 	},
+ 	.probe = xgbe_probe,
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+index 363b210..5d2c89b 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+@@ -119,6 +119,7 @@
+ #include <linux/mdio.h>
+ #include <linux/phy.h>
+ #include <linux/of.h>
++#include <linux/acpi.h>
  
--	priv->sir1_res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
--	priv->sir1_regs = devm_ioremap_resource(dev, priv->sir1_res);
--	if (IS_ERR(priv->sir1_regs)) {
--		dev_err(dev, "sir1 ioremap failed\n");
--		ret = PTR_ERR(priv->sir1_regs);
--		goto err_sir0;
-+	/* Get the device serdes channel property */
-+	property = of_get_property(dev->of_node, XGBE_PHY_CHANNEL_PROPERTY,
-+				   NULL);
-+	if (!property) {
-+		dev_err(dev, "unable to obtain serdes_channel property\n");
-+		ret = -EINVAL;
-+		goto err_cmu;
- 	}
-+	priv->serdes_channel = be32_to_cpu(*property);
+ #include "xgbe.h"
+ #include "xgbe-common.h"
+@@ -205,25 +206,16 @@ void xgbe_dump_phy_registers(struct xgbe_prv_data *pdata)
  
- 	/* Get the device speed set property */
- 	speed_set = 0;
-@@ -1324,14 +1326,14 @@ static int amd_xgbe_phy_probe(struct phy_device *phydev)
- 	default:
- 		dev_err(dev, "invalid amd,speed-set property\n");
- 		ret = -EINVAL;
--		goto err_sir1;
-+		goto err_cmu;
+ int xgbe_mdio_register(struct xgbe_prv_data *pdata)
+ {
+-	struct device_node *phy_node;
+ 	struct mii_bus *mii;
+ 	struct phy_device *phydev;
+ 	int ret = 0;
+ 
+ 	DBGPR("-->xgbe_mdio_register\n");
+ 
+-	/* Retrieve the phy-handle */
+-	phy_node = of_parse_phandle(pdata->dev->of_node, "phy-handle", 0);
+-	if (!phy_node) {
+-		dev_err(pdata->dev, "unable to parse phy-handle\n");
+-		return -EINVAL;
+-	}
+-
+ 	mii = mdiobus_alloc();
+ 	if (mii == NULL) {
+ 		dev_err(pdata->dev, "mdiobus_alloc failed\n");
+-		ret = -ENOMEM;
+-		goto err_node_get;
++		return -ENOMEM;
  	}
  
- 	priv->link = 1;
+ 	/* Register on the MDIO bus (don't probe any PHYs) */
+@@ -252,12 +244,9 @@ int xgbe_mdio_register(struct xgbe_prv_data *pdata)
+ 	request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT,
+ 		       MDIO_ID_ARGS(phydev->c45_ids.device_ids[MDIO_MMD_PCS]));
  
- 	ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2);
- 	if (ret < 0)
--		goto err_sir1;
-+		goto err_cmu;
- 	if ((ret & MDIO_PCS_CTRL2_TYPE) == MDIO_PCS_CTRL2_10GBR)
- 		priv->mode = AMD_XGBE_MODE_KR;
- 	else
-@@ -1342,7 +1344,7 @@ static int amd_xgbe_phy_probe(struct phy_device *phydev)
- 	priv->an_workqueue = create_singlethread_workqueue(wq_name);
- 	if (!priv->an_workqueue) {
- 		ret = -ENOMEM;
--		goto err_sir1;
-+		goto err_cmu;
+-	of_node_get(phy_node);
+-	phydev->dev.of_node = phy_node;
+ 	ret = phy_device_register(phydev);
+ 	if (ret) {
+ 		dev_err(pdata->dev, "phy_device_register failed\n");
+-		of_node_put(phy_node);
+ 		goto err_phy_device;
  	}
  
- 	phydev->priv = priv;
-@@ -1352,15 +1354,8 @@ static int amd_xgbe_phy_probe(struct phy_device *phydev)
+@@ -283,8 +272,6 @@ int xgbe_mdio_register(struct xgbe_prv_data *pdata)
  
- 	return 0;
+ 	pdata->phydev = phydev;
  
--err_sir1:
--	devm_iounmap(dev, priv->sir1_regs);
--	devm_release_mem_region(dev, priv->sir1_res->start,
--				resource_size(priv->sir1_res));
+-	of_node_put(phy_node);
 -
--err_sir0:
--	devm_iounmap(dev, priv->sir0_regs);
--	devm_release_mem_region(dev, priv->sir0_res->start,
--				resource_size(priv->sir0_res));
-+err_cmu:
-+	devm_iounmap(dev, priv->cmu_regs);
+ 	DBGPHY_REGS(pdata);
  
- err_rxtx:
- 	devm_iounmap(dev, priv->rxtx_regs);
-@@ -1392,14 +1387,7 @@ static void amd_xgbe_phy_remove(struct phy_device *phydev)
- 	flush_workqueue(priv->an_workqueue);
- 	destroy_workqueue(priv->an_workqueue);
+ 	DBGPR("<--xgbe_mdio_register\n");
+@@ -300,9 +287,6 @@ err_mdiobus_register:
+ err_mdiobus_alloc:
+ 	mdiobus_free(mii);
  
--	/* Release resources */
--	devm_iounmap(dev, priv->sir1_regs);
--	devm_release_mem_region(dev, priv->sir1_res->start,
--				resource_size(priv->sir1_res));
+-err_node_get:
+-	of_node_put(phy_node);
 -
--	devm_iounmap(dev, priv->sir0_regs);
--	devm_release_mem_region(dev, priv->sir0_res->start,
--				resource_size(priv->sir0_res));
-+	devm_iounmap(dev, priv->cmu_regs);
+ 	return ret;
+ }
  
- 	devm_iounmap(dev, priv->rxtx_regs);
- 	devm_release_mem_region(dev, priv->rxtx_res->start,
-diff --git a/drivers/of/address.c b/drivers/of/address.c
-index e371825..afdb782 100644
---- a/drivers/of/address.c
-+++ b/drivers/of/address.c
-@@ -5,6 +5,8 @@
- #include <linux/module.h>
- #include <linux/of_address.h>
- #include <linux/pci_regs.h>
-+#include <linux/sizes.h>
-+#include <linux/slab.h>
- #include <linux/string.h>
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
+index a1bf9d1c..fa67203 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
+@@ -239,7 +239,7 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata)
+ 	snprintf(info->name, sizeof(info->name), "%s",
+ 		 netdev_name(pdata->netdev));
+ 	info->owner = THIS_MODULE;
+-	info->max_adj = clk_get_rate(pdata->ptpclk);
++	info->max_adj = pdata->ptpclk_rate;
+ 	info->adjfreq = xgbe_adjfreq;
+ 	info->adjtime = xgbe_adjtime;
+ 	info->gettime = xgbe_gettime;
+@@ -260,7 +260,7 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata)
+ 	 */
+ 	dividend = 50000000;
+ 	dividend <<= 32;
+-	pdata->tstamp_addend = div_u64(dividend, clk_get_rate(pdata->ptpclk));
++	pdata->tstamp_addend = div_u64(dividend, pdata->ptpclk_rate);
  
- /* Max address size we deal with */
-@@ -293,6 +295,51 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
- }
- EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
+ 	/* Setup the timecounter */
+ 	cc->read = xgbe_cc_read;
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
+index 789957d..59498eb 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
++++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
+@@ -172,6 +172,12 @@
+ #define XGBE_DMA_CLOCK		"dma_clk"
+ #define XGBE_PTP_CLOCK		"ptp_clk"
+ 
++/* ACPI property names */
++#define XGBE_ACPI_MAC_ADDR	"mac-address"
++#define XGBE_ACPI_PHY_MODE	"phy-mode"
++#define XGBE_ACPI_DMA_FREQ	"amd,dma-freq"
++#define XGBE_ACPI_PTP_FREQ	"amd,ptp-freq"
++
+ /* Timestamp support - values based on 50MHz PTP clock
+  *   50MHz => 20 nsec
+  */
+@@ -186,8 +192,11 @@
+ #define XGBE_FIFO_SIZE_B(x)	(x)
+ #define XGBE_FIFO_SIZE_KB(x)	(x * 1024)
  
-+/*
-+ * of_pci_range_to_resource - Create a resource from an of_pci_range
-+ * @range:	the PCI range that describes the resource
-+ * @np:		device node where the range belongs to
-+ * @res:	pointer to a valid resource that will be updated to
-+ *              reflect the values contained in the range.
-+ *
-+ * Returns EINVAL if the range cannot be converted to resource.
-+ *
-+ * Note that if the range is an IO range, the resource will be converted
-+ * using pci_address_to_pio() which can fail if it is called too early or
-+ * if the range cannot be matched to any host bridge IO space (our case here).
-+ * To guard against that we try to register the IO range first.
-+ * If that fails we know that pci_address_to_pio() will do too.
-+ */
-+int of_pci_range_to_resource(struct of_pci_range *range,
-+			     struct device_node *np, struct resource *res)
-+{
-+	int err;
-+	res->flags = range->flags;
-+	res->parent = res->child = res->sibling = NULL;
-+	res->name = np->full_name;
++#define XGBE_TC_CNT		2
+ #define XGBE_TC_MIN_QUANTUM	10
+ 
++#define XGBE_SEATTLE_A0		((read_cpuid_id() & 0x00f0000f) == 0)
 +
-+	if (res->flags & IORESOURCE_IO) {
-+		unsigned long port;
-+		err = pci_register_io_range(range->cpu_addr, range->size);
-+		if (err)
-+			goto invalid_range;
-+		port = pci_address_to_pio(range->cpu_addr);
-+		if (port == (unsigned long)-1) {
-+			err = -EINVAL;
-+			goto invalid_range;
-+		}
-+		res->start = port;
-+	} else {
-+		res->start = range->cpu_addr;
+ /* Helper macro for descriptor handling
+  *  Always use XGBE_GET_DESC_DATA to access the descriptor data
+  *  since the index is free-running and needs to be and-ed
+@@ -569,6 +578,7 @@ struct xgbe_hw_features {
+ struct xgbe_prv_data {
+ 	struct net_device *netdev;
+ 	struct platform_device *pdev;
++	struct acpi_device *adev;
+ 	struct device *dev;
+ 
+ 	/* XGMAC/XPCS related mmio registers */
+@@ -649,6 +659,7 @@ struct xgbe_prv_data {
+ 	unsigned int phy_rx_pause;
+ 
+ 	/* Netdev related settings */
++	unsigned char mac_addr[MAX_ADDR_LEN];
+ 	netdev_features_t netdev_features;
+ 	struct napi_struct napi;
+ 	struct xgbe_mmc_stats mmc_stats;
+@@ -658,7 +669,9 @@ struct xgbe_prv_data {
+ 
+ 	/* Device clocks */
+ 	struct clk *sysclk;
++	unsigned long sysclk_rate;
+ 	struct clk *ptpclk;
++	unsigned long ptpclk_rate;
+ 
+ 	/* Timestamp support */
+ 	spinlock_t tstamp_lock;
+diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+index 63ea194..bb059b4 100644
+--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+@@ -579,9 +579,11 @@ static void xgene_enet_reset(struct xgene_enet_pdata *pdata)
+ {
+ 	u32 val;
+ 
+-	clk_prepare_enable(pdata->clk);
+-	clk_disable_unprepare(pdata->clk);
+-	clk_prepare_enable(pdata->clk);
++	if (pdata->clk) {
++		clk_prepare_enable(pdata->clk);
++		clk_disable_unprepare(pdata->clk);
++		clk_prepare_enable(pdata->clk);
 +	}
-+	res->end = res->start + range->size - 1;
-+	return 0;
+ 	xgene_enet_ecc_init(pdata);
+ 	xgene_enet_config_ring_if_assoc(pdata);
+ 
+@@ -647,15 +649,20 @@ static int xgene_enet_phy_connect(struct net_device *ndev)
+ 	struct phy_device *phy_dev;
+ 	struct device *dev = &pdata->pdev->dev;
+ 
+-	phy_np = of_parse_phandle(dev->of_node, "phy-handle", 0);
+-	if (!phy_np) {
+-		netdev_dbg(ndev, "No phy-handle found\n");
+-		return -ENODEV;
++	if (dev->of_node) {
++		phy_np = of_parse_phandle(dev->of_node, "phy-handle", 0);
++		if (!phy_np) {
++			netdev_dbg(ndev, "No phy-handle found in DT\n");
++			return -ENODEV;
++		}
++		pdata->phy_dev = of_phy_find_device(phy_np);
+ 	}
+ 
+-	phy_dev = of_phy_connect(ndev, phy_np, &xgene_enet_adjust_link,
+-				 0, pdata->phy_mode);
+-	if (!phy_dev) {
++	phy_dev = pdata->phy_dev;
 +
-+invalid_range:
-+	res->start = (resource_size_t)OF_BAD_ADDR;
-+	res->end = (resource_size_t)OF_BAD_ADDR;
-+	return err;
-+}
- #endif /* CONFIG_PCI */
++	if (phy_dev == NULL ||
++	    phy_connect_direct(ndev, phy_dev, &xgene_enet_adjust_link,
++			       pdata->phy_mode)) {
+ 		netdev_err(ndev, "Could not connect to PHY\n");
+ 		return  -ENODEV;
+ 	}
+@@ -665,11 +672,52 @@ static int xgene_enet_phy_connect(struct net_device *ndev)
+ 			      ~SUPPORTED_100baseT_Half &
+ 			      ~SUPPORTED_1000baseT_Half;
+ 	phy_dev->advertising = phy_dev->supported;
+-	pdata->phy_dev = phy_dev;
  
- /*
-@@ -601,12 +648,119 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
+ 	return 0;
  }
- EXPORT_SYMBOL(of_get_address);
  
-+#ifdef PCI_IOBASE
-+struct io_range {
-+	struct list_head list;
-+	phys_addr_t start;
-+	resource_size_t size;
-+};
-+
-+static LIST_HEAD(io_range_list);
-+static DEFINE_SPINLOCK(io_range_lock);
-+#endif
-+
-+/*
-+ * Record the PCI IO range (expressed as CPU physical address + size).
-+ * Return a negative value if an error has occured, zero otherwise
-+ */
-+int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size)
++#ifdef CONFIG_ACPI
++static int xgene_acpi_mdiobus_register(struct xgene_enet_pdata *pdata,
++	struct mii_bus *mdio)
 +{
-+	int err = 0;
++	struct device *dev = &pdata->pdev->dev;
++	struct phy_device *phy;
++	int i, ret;
++	u32 phy_id;
 +
-+#ifdef PCI_IOBASE
-+	struct io_range *range;
-+	resource_size_t allocated_size = 0;
++	/* Mask out all PHYs from auto probing. */
++	mdio->phy_mask = ~0;
 +
-+	/* check if the range hasn't been previously recorded */
-+	spin_lock(&io_range_lock);
-+	list_for_each_entry(range, &io_range_list, list) {
-+		if (addr >= range->start && addr + size <= range->start + size) {
-+			/* range already registered, bail out */
-+			goto end_register;
-+		}
-+		allocated_size += range->size;
-+	}
++	/* Clear all the IRQ properties */
++	if (mdio->irq)
++		for (i = 0; i < PHY_MAX_ADDR; i++)
++			mdio->irq[i] = PHY_POLL;
 +
-+	/* range not registed yet, check for available space */
-+	if (allocated_size + size - 1 > IO_SPACE_LIMIT) {
-+		/* if it's too big check if 64K space can be reserved */
-+		if (allocated_size + SZ_64K - 1 > IO_SPACE_LIMIT) {
-+			err = -E2BIG;
-+			goto end_register;
-+		}
++	/* Register the MDIO bus */
++	ret = mdiobus_register(mdio);
++	if (ret)
++		return ret;
 +
-+		size = SZ_64K;
-+		pr_warn("Requested IO range too big, new size set to 64K\n");
-+	}
++	ret = device_property_read_u32(dev, "phy-channel", &phy_id);
++	if (ret)
++		return -EINVAL;
 +
-+	/* add the range to the list */
-+	range = kzalloc(sizeof(*range), GFP_KERNEL);
-+	if (!range) {
-+		err = -ENOMEM;
-+		goto end_register;
-+	}
++	phy = get_phy_device(mdio, phy_id, true);
++	if (!phy || IS_ERR(phy))
++		return -EIO;
++
++	ret = phy_device_register(phy);
++	if (ret)
++		phy_device_free(phy);
++	else
++		pdata->phy_dev = phy;
 +
-+	range->start = addr;
-+	range->size = size;
++	return ret;
++}
++#else
++#define xgene_acpi_mdiobus_register(a, b) -1
++#endif
 +
-+	list_add_tail(&range->list, &io_range_list);
+ int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata)
+ {
+ 	struct net_device *ndev = pdata->ndev;
+@@ -686,7 +734,7 @@ int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata)
+ 		}
+ 	}
+ 
+-	if (!mdio_np) {
++	if (dev->of_node && !mdio_np) {
+ 		netdev_dbg(ndev, "No mdio node in the dts\n");
+ 		return -ENXIO;
+ 	}
+@@ -704,7 +752,10 @@ int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata)
+ 	mdio_bus->priv = pdata;
+ 	mdio_bus->parent = &ndev->dev;
+ 
+-	ret = of_mdiobus_register(mdio_bus, mdio_np);
++	if (dev->of_node)
++		ret = of_mdiobus_register(mdio_bus, mdio_np);
++	else
++		ret = xgene_acpi_mdiobus_register(pdata, mdio_bus);
+ 	if (ret) {
+ 		netdev_err(ndev, "Failed to register MDIO bus\n");
+ 		mdiobus_free(mdio_bus);
+diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+index 3c208cc..6370ff4 100644
+--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+@@ -746,6 +746,42 @@ static const struct net_device_ops xgene_ndev_ops = {
+ 	.ndo_set_mac_address = xgene_enet_set_mac_address,
+ };
+ 
++#ifdef CONFIG_ACPI
++static int acpi_get_mac_address(struct device *dev,
++				unsigned char *addr)
++{
++	int ret;
 +
-+end_register:
-+	spin_unlock(&io_range_lock);
-+#endif
++	ret = device_property_read_u8_array(dev, "mac-address", addr, 6);
++	if (ret)
++		return 0;
 +
-+	return err;
++	return 6;
 +}
 +
-+phys_addr_t pci_pio_to_address(unsigned long pio)
++static int acpi_get_phy_mode(struct device *dev)
 +{
-+	phys_addr_t address = (phys_addr_t)OF_BAD_ADDR;
++	int i, ret, phy_mode;
++	char *modestr;
 +
-+#ifdef PCI_IOBASE
-+	struct io_range *range;
-+	resource_size_t allocated_size = 0;
-+
-+	if (pio > IO_SPACE_LIMIT)
-+		return address;
++	ret = device_property_read_string(dev, "phy-mode", &modestr);
++	if (ret)
++		return -1;
 +
-+	spin_lock(&io_range_lock);
-+	list_for_each_entry(range, &io_range_list, list) {
-+		if (pio >= allocated_size && pio < allocated_size + range->size) {
-+			address = range->start + pio - allocated_size;
++	phy_mode = -1;
++	for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) {
++		if (!strcasecmp(modestr, phy_modes(i))) {
++			phy_mode = i;
 +			break;
 +		}
-+		allocated_size += range->size;
 +	}
-+	spin_unlock(&io_range_lock);
-+#endif
-+
-+	return address;
++	return phy_mode;
 +}
++#else
++#define acpi_get_mac_address(a, b, c) 0
++#define acpi_get_phy_mode(a) -1
++#endif
 +
- unsigned long __weak pci_address_to_pio(phys_addr_t address)
+ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
  {
-+#ifdef PCI_IOBASE
-+	struct io_range *res;
-+	resource_size_t offset = 0;
-+	unsigned long addr = -1;
-+
-+	spin_lock(&io_range_lock);
-+	list_for_each_entry(res, &io_range_list, list) {
-+		if (address >= res->start && address < res->start + res->size) {
-+			addr = res->start - address + offset;
-+			break;
-+		}
-+		offset += res->size;
-+	}
-+	spin_unlock(&io_range_lock);
-+
-+	return addr;
-+#else
- 	if (address > IO_SPACE_LIMIT)
- 		return (unsigned long)-1;
+ 	struct platform_device *pdev;
+@@ -761,6 +797,8 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
+ 	ndev = pdata->ndev;
+ 
+ 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "enet_csr");
++	if (!res)
++		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ 	if (!res) {
+ 		dev_err(dev, "Resource enet_csr not defined\n");
+ 		return -ENODEV;
+@@ -772,6 +810,8 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
+ 	}
  
- 	return (unsigned long) address;
-+#endif
+ 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ring_csr");
++	if (!res)
++		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ 	if (!res) {
+ 		dev_err(dev, "Resource ring_csr not defined\n");
+ 		return -ENODEV;
+@@ -783,6 +823,8 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
+ 	}
+ 
+ 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ring_cmd");
++	if (!res)
++		res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ 	if (!res) {
+ 		dev_err(dev, "Resource ring_cmd not defined\n");
+ 		return -ENODEV;
+@@ -804,11 +846,13 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
+ 	mac = of_get_mac_address(dev->of_node);
+ 	if (mac)
+ 		memcpy(ndev->dev_addr, mac, ndev->addr_len);
+-	else
++	else if (!acpi_get_mac_address(dev, ndev->dev_addr))
+ 		eth_hw_addr_random(ndev);
+ 	memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
+ 
+ 	pdata->phy_mode = of_get_phy_mode(pdev->dev.of_node);
++	if (pdata->phy_mode < 0)
++		pdata->phy_mode = acpi_get_phy_mode(dev);
+ 	if (pdata->phy_mode < 0) {
+ 		dev_err(dev, "Unable to get phy-connection-type\n");
+ 		return pdata->phy_mode;
+@@ -821,11 +865,12 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
+ 	}
+ 
+ 	pdata->clk = devm_clk_get(&pdev->dev, NULL);
+-	ret = IS_ERR(pdata->clk);
+ 	if (IS_ERR(pdata->clk)) {
+-		dev_err(&pdev->dev, "can't get clock\n");
+-		ret = PTR_ERR(pdata->clk);
+-		return ret;
++		/*
++		 * Not necessarily an error. Firmware may have
++		 * set up the clock already.
++		 */
++		pdata->clk = NULL;
+ 	}
+ 
+ 	base_addr = pdata->base_addr;
+@@ -873,7 +918,7 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
+ 	pdata->port_ops->cle_bypass(pdata, dst_ring_num, buf_pool->id);
+ 	pdata->mac_ops->init(pdata);
+ 
+-	return ret;
++	return 0;
  }
  
- static int __of_address_to_resource(struct device_node *dev,
-diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
-index 8481996..8882b46 100644
---- a/drivers/of/of_pci.c
-+++ b/drivers/of/of_pci.c
-@@ -1,7 +1,9 @@
- #include <linux/kernel.h>
- #include <linux/export.h>
+ static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
+@@ -934,7 +979,7 @@ static int xgene_enet_probe(struct platform_device *pdev)
+ 		goto err;
+ 	}
+ 
+-	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
++	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64));
+ 	if (ret) {
+ 		netdev_err(ndev, "No usable DMA configuration\n");
+ 		goto err;
+@@ -981,6 +1026,14 @@ static int xgene_enet_remove(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_ACPI
++static const struct acpi_device_id xgene_enet_acpi_match[] = {
++	{ "APMC0D05", },
++	{ }
++};
++MODULE_DEVICE_TABLE(acpi, xgene_enet_acpi_match);
++#endif
++
+ static struct of_device_id xgene_enet_match[] = {
+ 	{.compatible = "apm,xgene-enet",},
+ 	{},
+@@ -992,6 +1045,7 @@ static struct platform_driver xgene_enet_driver = {
+ 	.driver = {
+ 		   .name = "xgene-enet",
+ 		   .of_match_table = xgene_enet_match,
++		   .acpi_match_table = ACPI_PTR(xgene_enet_acpi_match),
+ 	},
+ 	.probe = xgene_enet_probe,
+ 	.remove = xgene_enet_remove,
+diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+index 874e5a0..8b7e2cf 100644
+--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+@@ -31,6 +31,7 @@
+ #include <linux/prefetch.h>
+ #include <linux/if_vlan.h>
+ #include <linux/phy.h>
++#include <linux/acpi.h>
+ #include "xgene_enet_hw.h"
+ 
+ #define XGENE_DRV_VERSION	"v1.0"
+diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
+index 5e94d00..a6131a9 100644
+--- a/drivers/net/ethernet/smsc/smc91x.c
++++ b/drivers/net/ethernet/smsc/smc91x.c
+@@ -81,6 +81,7 @@ static const char version[] =
+ #include <linux/workqueue.h>
  #include <linux/of.h>
-+#include <linux/of_address.h>
- #include <linux/of_pci.h>
-+#include <linux/slab.h>
+ #include <linux/of_device.h>
++#include <linux/acpi.h>
+ 
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+@@ -2405,6 +2406,14 @@ static struct dev_pm_ops smc_drv_pm_ops = {
+ 	.resume		= smc_drv_resume,
+ };
+ 
++#ifdef CONFIG_ACPI
++static const struct acpi_device_id smc91x_acpi_match[] = {
++	{ "LNRO0003", },
++	{ }
++};
++MODULE_DEVICE_TABLE(acpi, smc91x_acpi_match);
++#endif
++
+ static struct platform_driver smc_driver = {
+ 	.probe		= smc_drv_probe,
+ 	.remove		= smc_drv_remove,
+@@ -2413,6 +2422,7 @@ static struct platform_driver smc_driver = {
+ 		.owner	= THIS_MODULE,
+ 		.pm	= &smc_drv_pm_ops,
+ 		.of_match_table = of_match_ptr(smc91x_match),
++		.acpi_match_table = ACPI_PTR(smc91x_acpi_match),
+ 	},
+ };
+ 
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+index 75472cf7..bacafe2 100644
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -26,7 +26,7 @@ config AMD_PHY
+ 
+ config AMD_XGBE_PHY
+ 	tristate "Driver for the AMD 10GbE (amd-xgbe) PHYs"
+-	depends on OF
++	depends on OF || ACPI
+ 	---help---
+ 	  Currently supports the AMD 10GbE PHY
+ 
+diff --git a/drivers/net/phy/amd-xgbe-phy.c b/drivers/net/phy/amd-xgbe-phy.c
+index c456559..d852c6e 100644
+--- a/drivers/net/phy/amd-xgbe-phy.c
++++ b/drivers/net/phy/amd-xgbe-phy.c
+@@ -74,15 +74,19 @@
+ #include <linux/of_platform.h>
+ #include <linux/of_device.h>
+ #include <linux/uaccess.h>
++#include <linux/acpi.h>
++
+ 
+ MODULE_AUTHOR("Tom Lendacky <thomas.lendacky at amd.com>");
+ MODULE_LICENSE("Dual BSD/GPL");
+-MODULE_VERSION("1.0.0-a");
++MODULE_VERSION("0.0.0-a");
+ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
+ 
+-#define XGBE_PHY_ID	0x000162d0
++#define XGBE_PHY_ID	0x7996ced0
+ #define XGBE_PHY_MASK	0xfffffff0
+ 
++#define XGBE_PHY_SERDES_RETRY		32
++#define XGBE_PHY_CHANNEL_PROPERTY	"amd,serdes-channel"
+ #define XGBE_PHY_SPEEDSET_PROPERTY	"amd,speed-set"
+ 
+ #define XGBE_AN_INT_CMPLT		0x01
+@@ -99,11 +103,9 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
+ #ifndef MDIO_PMA_10GBR_PMD_CTRL
+ #define MDIO_PMA_10GBR_PMD_CTRL		0x0096
+ #endif
+-
+ #ifndef MDIO_PMA_10GBR_FEC_CTRL
+ #define MDIO_PMA_10GBR_FEC_CTRL		0x00ab
+ #endif
+-
+ #ifndef MDIO_AN_XNP
+ #define MDIO_AN_XNP			0x0016
+ #endif
+@@ -111,93 +113,14 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
+ #ifndef MDIO_AN_INTMASK
+ #define MDIO_AN_INTMASK			0x8001
+ #endif
+-
+ #ifndef MDIO_AN_INT
+ #define MDIO_AN_INT			0x8002
+ #endif
+ 
+-#ifndef MDIO_AN_KR_CTRL
+-#define MDIO_AN_KR_CTRL			0x8003
+-#endif
+-
+ #ifndef MDIO_CTRL1_SPEED1G
+ #define MDIO_CTRL1_SPEED1G		(MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100)
+ #endif
+ 
+-#ifndef MDIO_KR_CTRL_PDETECT
+-#define MDIO_KR_CTRL_PDETECT		0x01
+-#endif
+-
+-/* SerDes integration register offsets */
+-#define SIR0_KR_RT_1			0x002c
+-#define SIR0_STATUS			0x0040
+-#define SIR1_SPEED			0x0000
+-
+-/* SerDes integration register entry bit positions and sizes */
+-#define SIR0_KR_RT_1_RESET_INDEX	11
+-#define SIR0_KR_RT_1_RESET_WIDTH	1
+-#define SIR0_STATUS_RX_READY_INDEX	0
+-#define SIR0_STATUS_RX_READY_WIDTH	1
+-#define SIR0_STATUS_TX_READY_INDEX	8
+-#define SIR0_STATUS_TX_READY_WIDTH	1
+-#define SIR1_SPEED_DATARATE_INDEX	4
+-#define SIR1_SPEED_DATARATE_WIDTH	2
+-#define SIR1_SPEED_PI_SPD_SEL_INDEX	12
+-#define SIR1_SPEED_PI_SPD_SEL_WIDTH	4
+-#define SIR1_SPEED_PLLSEL_INDEX		3
+-#define SIR1_SPEED_PLLSEL_WIDTH		1
+-#define SIR1_SPEED_RATECHANGE_INDEX	6
+-#define SIR1_SPEED_RATECHANGE_WIDTH	1
+-#define SIR1_SPEED_TXAMP_INDEX		8
+-#define SIR1_SPEED_TXAMP_WIDTH		4
+-#define SIR1_SPEED_WORDMODE_INDEX	0
+-#define SIR1_SPEED_WORDMODE_WIDTH	3
+-
+-#define SPEED_10000_CDR			0x7
+-#define SPEED_10000_PLL			0x1
+-#define SPEED_10000_RATE		0x0
+-#define SPEED_10000_TXAMP		0xa
+-#define SPEED_10000_WORD		0x7
+-
+-#define SPEED_2500_CDR			0x2
+-#define SPEED_2500_PLL			0x0
+-#define SPEED_2500_RATE			0x1
+-#define SPEED_2500_TXAMP		0xf
+-#define SPEED_2500_WORD			0x1
+-
+-#define SPEED_1000_CDR			0x2
+-#define SPEED_1000_PLL			0x0
+-#define SPEED_1000_RATE			0x3
+-#define SPEED_1000_TXAMP		0xf
+-#define SPEED_1000_WORD			0x1
+-
+-/* SerDes RxTx register offsets */
+-#define RXTX_REG20			0x0050
+-#define RXTX_REG114			0x01c8
+-
+-/* SerDes RxTx register entry bit positions and sizes */
+-#define RXTX_REG20_BLWC_ENA_INDEX	2
+-#define RXTX_REG20_BLWC_ENA_WIDTH	1
+-#define RXTX_REG114_PQ_REG_INDEX	9
+-#define RXTX_REG114_PQ_REG_WIDTH	7
+-
+-#define RXTX_10000_BLWC			0
+-#define RXTX_10000_PQ			0x1e
+-
+-#define RXTX_2500_BLWC			1
+-#define RXTX_2500_PQ			0xa
+-
+-#define RXTX_1000_BLWC			1
+-#define RXTX_1000_PQ			0xa
+-
+-/* Bit setting and getting macros
+- *  The get macro will extract the current bit field value from within
+- *  the variable
+- *
+- *  The set macro will clear the current bit field value within the
+- *  variable and then set the bit field of the variable to the
+- *  specified value
+- */
+ #define GET_BITS(_var, _index, _width)					\
+ 	(((_var) >> (_index)) & ((0x1 << (_width)) - 1))
+ 
+@@ -207,70 +130,12 @@ do {									\
+ 	(_var) |= (((_val) & ((0x1 << (_width)) - 1)) << (_index));	\
+ } while (0)
+ 
+-#define XSIR_GET_BITS(_var, _prefix, _field)				\
+-	GET_BITS((_var),						\
+-		 _prefix##_##_field##_INDEX,				\
+-		 _prefix##_##_field##_WIDTH)
+-
+-#define XSIR_SET_BITS(_var, _prefix, _field, _val)			\
+-	SET_BITS((_var),						\
+-		 _prefix##_##_field##_INDEX,				\
+-		 _prefix##_##_field##_WIDTH, (_val))
+-
+-/* Macros for reading or writing SerDes integration registers
+- *  The ioread macros will get bit fields or full values using the
+- *  register definitions formed using the input names
+- *
+- *  The iowrite macros will set bit fields or full values using the
+- *  register definitions formed using the input names
+- */
+-#define XSIR0_IOREAD(_priv, _reg)					\
+-	ioread16((_priv)->sir0_regs + _reg)
+-
+-#define XSIR0_IOREAD_BITS(_priv, _reg, _field)				\
+-	GET_BITS(XSIR0_IOREAD((_priv), _reg),				\
+-		 _reg##_##_field##_INDEX,				\
+-		 _reg##_##_field##_WIDTH)
+-
+-#define XSIR0_IOWRITE(_priv, _reg, _val)				\
+-	iowrite16((_val), (_priv)->sir0_regs + _reg)
+-
+-#define XSIR0_IOWRITE_BITS(_priv, _reg, _field, _val)			\
+-do {									\
+-	u16 reg_val = XSIR0_IOREAD((_priv), _reg);			\
+-	SET_BITS(reg_val,						\
+-		 _reg##_##_field##_INDEX,				\
+-		 _reg##_##_field##_WIDTH, (_val));			\
+-	XSIR0_IOWRITE((_priv), _reg, reg_val);				\
+-} while (0)
+-
+-#define XSIR1_IOREAD(_priv, _reg)					\
+-	ioread16((_priv)->sir1_regs + _reg)
+-
+-#define XSIR1_IOREAD_BITS(_priv, _reg, _field)				\
+-	GET_BITS(XSIR1_IOREAD((_priv), _reg),				\
+-		 _reg##_##_field##_INDEX,				\
+-		 _reg##_##_field##_WIDTH)
++#define XCMU_IOREAD(_priv, _reg)					\
++	ioread16((_priv)->cmu_regs + _reg)
+ 
+-#define XSIR1_IOWRITE(_priv, _reg, _val)				\
+-	iowrite16((_val), (_priv)->sir1_regs + _reg)
++#define XCMU_IOWRITE(_priv, _reg, _val)					\
++	iowrite16((_val), (_priv)->cmu_regs + _reg)
+ 
+-#define XSIR1_IOWRITE_BITS(_priv, _reg, _field, _val)			\
+-do {									\
+-	u16 reg_val = XSIR1_IOREAD((_priv), _reg);			\
+-	SET_BITS(reg_val,						\
+-		 _reg##_##_field##_INDEX,				\
+-		 _reg##_##_field##_WIDTH, (_val));			\
+-	XSIR1_IOWRITE((_priv), _reg, reg_val);				\
+-} while (0)
+-
+-/* Macros for reading or writing SerDes RxTx registers
+- *  The ioread macros will get bit fields or full values using the
+- *  register definitions formed using the input names
+- *
+- *  The iowrite macros will set bit fields or full values using the
+- *  register definitions formed using the input names
+- */
+ #define XRXTX_IOREAD(_priv, _reg)					\
+ 	ioread16((_priv)->rxtx_regs + _reg)
  
- static inline int __of_pci_pci_compare(struct device_node *node,
- 				       unsigned int data)
-@@ -89,6 +91,146 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
- }
- EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
+@@ -291,6 +156,78 @@ do {									\
+ 	XRXTX_IOWRITE((_priv), _reg, reg_val);				\
+ } while (0)
  
-+/**
-+ * This function will try to obtain the host bridge domain number by
-+ * finding a property called "linux,pci-domain" of the given device node.
-+ *
-+ * @node: device tree node with the domain information
-+ *
-+ * Returns the associated domain number from DT in the range [0-0xffff], or
-+ * a negative value if the required property is not found.
-+ */
-+int of_get_pci_domain_nr(struct device_node *node)
-+{
-+	const __be32 *value;
-+	int len;
-+	u16 domain;
-+
-+	value = of_get_property(node, "linux,pci-domain", &len);
-+	if (!value || len < sizeof(*value))
-+		return -EINVAL;
-+
-+	domain = (u16)be32_to_cpup(value);
-+
-+	return domain;
-+}
-+EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
-+
-+#if defined(CONFIG_OF_ADDRESS)
-+/**
-+ * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
-+ * @dev: device node of the host bridge having the range property
-+ * @busno: bus number associated with the bridge root bus
-+ * @bus_max: maximum number of buses for this bridge
-+ * @resources: list where the range of resources will be added after DT parsing
-+ * @io_base: pointer to a variable that will contain on return the physical
-+ * address for the start of the I/O range. Can be NULL if the caller doesn't
-+ * expect IO ranges to be present in the device tree.
-+ *
-+ * It is the caller's job to free the @resources list.
-+ *
-+ * This function will parse the "ranges" property of a PCI host bridge device
-+ * node and setup the resource mapping based on its content. It is expected
-+ * that the property conforms with the Power ePAPR document.
-+ *
-+ * It returns zero if the range parsing has been successful or a standard error
-+ * value if it failed.
-+ */
-+int of_pci_get_host_bridge_resources(struct device_node *dev,
-+			unsigned char busno, unsigned char bus_max,
-+			struct list_head *resources, resource_size_t *io_base)
-+{
-+	struct resource *res;
-+	struct resource *bus_range;
-+	struct of_pci_range range;
-+	struct of_pci_range_parser parser;
-+	char range_type[4];
-+	int err;
-+
-+	if (io_base)
-+		*io_base = (resource_size_t)OF_BAD_ADDR;
-+
-+	bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
-+	if (!bus_range)
-+		return -ENOMEM;
-+
-+	pr_info("PCI host bridge %s ranges:\n", dev->full_name);
-+
-+	err = of_pci_parse_bus_range(dev, bus_range);
-+	if (err) {
-+		bus_range->start = busno;
-+		bus_range->end = bus_max;
-+		bus_range->flags = IORESOURCE_BUS;
-+		pr_info("  No bus range found for %s, using %pR\n",
-+			dev->full_name, bus_range);
-+	} else {
-+		if (bus_range->end > bus_range->start + bus_max)
-+			bus_range->end = bus_range->start + bus_max;
-+	}
-+	pci_add_resource(resources, bus_range);
++/* SerDes CMU register offsets */
++#define CMU_REG15			0x003c
++#define CMU_REG16			0x0040
 +
-+	/* Check for ranges property */
-+	err = of_pci_range_parser_init(&parser, dev);
-+	if (err)
-+		goto parse_failed;
-+
-+	pr_debug("Parsing ranges property...\n");
-+	for_each_of_pci_range(&parser, &range) {
-+		/* Read next ranges element */
-+		if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
-+			snprintf(range_type, 4, " IO");
-+		else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
-+			snprintf(range_type, 4, "MEM");
-+		else
-+			snprintf(range_type, 4, "err");
-+		pr_info("  %s %#010llx..%#010llx -> %#010llx\n", range_type,
-+			range.cpu_addr, range.cpu_addr + range.size - 1,
-+			range.pci_addr);
++/* SerDes CMU register entry bit positions and sizes */
++#define CMU_REG16_TX_RATE_CHANGE_BASE	15
++#define CMU_REG16_RX_RATE_CHANGE_BASE	14
++#define CMU_REG16_RATE_CHANGE_DECR	2
 +
-+		/*
-+		 * If we failed translation or got a zero-sized region
-+		 * then skip this range
-+		 */
-+		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
-+			continue;
 +
-+		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
-+		if (!res) {
-+			err = -ENOMEM;
-+			goto parse_failed;
-+		}
++/* SerDes RxTx register offsets */
++#define RXTX_REG2			0x0008
++#define RXTX_REG3			0x000c
++#define RXTX_REG5			0x0014
++#define RXTX_REG6			0x0018
++#define RXTX_REG20			0x0050
++#define RXTX_REG53			0x00d4
++#define RXTX_REG114			0x01c8
++#define RXTX_REG115			0x01cc
++#define RXTX_REG142			0x0238
 +
-+		err = of_pci_range_to_resource(&range, dev, res);
-+		if (err)
-+			goto conversion_failed;
-+
-+		if (resource_type(res) == IORESOURCE_IO) {
-+			if (!io_base) {
-+				pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n",
-+					dev->full_name);
-+				err = -EINVAL;
-+				goto conversion_failed;
-+			}
-+			if (*io_base != (resource_size_t)OF_BAD_ADDR)
-+				pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n",
-+					dev->full_name);
-+			*io_base = range.cpu_addr;
-+		}
++/* SerDes RxTx register entry bit positions and sizes */
++#define RXTX_REG2_RESETB_INDEX			15
++#define RXTX_REG2_RESETB_WIDTH			1
++#define RXTX_REG3_TX_DATA_RATE_INDEX		14
++#define RXTX_REG3_TX_DATA_RATE_WIDTH		2
++#define RXTX_REG3_TX_WORD_MODE_INDEX		11
++#define RXTX_REG3_TX_WORD_MODE_WIDTH		3
++#define RXTX_REG5_TXAMP_CNTL_INDEX		7
++#define RXTX_REG5_TXAMP_CNTL_WIDTH		4
++#define RXTX_REG6_RX_DATA_RATE_INDEX		9
++#define RXTX_REG6_RX_DATA_RATE_WIDTH		2
++#define RXTX_REG6_RX_WORD_MODE_INDEX		11
++#define RXTX_REG6_RX_WORD_MODE_WIDTH		3
++#define RXTX_REG20_BLWC_ENA_INDEX		2
++#define RXTX_REG20_BLWC_ENA_WIDTH		1
++#define RXTX_REG53_RX_PLLSELECT_INDEX		15
++#define RXTX_REG53_RX_PLLSELECT_WIDTH		1
++#define RXTX_REG53_TX_PLLSELECT_INDEX		14
++#define RXTX_REG53_TX_PLLSELECT_WIDTH		1
++#define RXTX_REG53_PI_SPD_SEL_CDR_INDEX		10
++#define RXTX_REG53_PI_SPD_SEL_CDR_WIDTH		4
++#define RXTX_REG114_PQ_REG_INDEX		9
++#define RXTX_REG114_PQ_REG_WIDTH		7
++#define RXTX_REG115_FORCE_LAT_CAL_START_INDEX	2
++#define RXTX_REG115_FORCE_LAT_CAL_START_WIDTH	1
++#define RXTX_REG115_FORCE_SUM_CAL_START_INDEX	1
++#define RXTX_REG115_FORCE_SUM_CAL_START_WIDTH	1
++#define RXTX_REG142_SUM_CALIB_DONE_INDEX	15
++#define RXTX_REG142_SUM_CALIB_DONE_WIDTH	1
++#define RXTX_REG142_SUM_CALIB_ERR_INDEX		14
++#define RXTX_REG142_SUM_CALIB_ERR_WIDTH		1
++#define RXTX_REG142_LAT_CALIB_DONE_INDEX	11
++#define RXTX_REG142_LAT_CALIB_DONE_WIDTH	1
 +
-+		pci_add_resource_offset(resources, res,	res->start - range.pci_addr);
-+	}
++#define RXTX_FULL_RATE				0x0
++#define RXTX_HALF_RATE				0x1
++#define RXTX_FIFTH_RATE				0x3
++#define RXTX_66BIT_WORD				0x7
++#define RXTX_10BIT_WORD				0x1
++#define RXTX_10G_TX_AMP				0xa
++#define RXTX_1G_TX_AMP				0xf
++#define RXTX_10G_CDR				0x7
++#define RXTX_1G_CDR				0x2
++#define RXTX_10G_PLL				0x1
++#define RXTX_1G_PLL				0x0
++#define RXTX_10G_PQ				0x1e
++#define RXTX_1G_PQ				0xa
 +
-+	return 0;
 +
-+conversion_failed:
-+	kfree(res);
-+parse_failed:
-+	pci_free_resource_list(resources);
-+	return err;
-+}
-+EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
-+#endif /* CONFIG_OF_ADDRESS */
++DEFINE_SPINLOCK(cmu_lock);
 +
- #ifdef CONFIG_PCI_MSI
+ enum amd_xgbe_phy_an {
+ 	AMD_XGBE_AN_READY = 0,
+ 	AMD_XGBE_AN_START,
+@@ -316,29 +253,31 @@ enum amd_xgbe_phy_mode {
+ };
  
- static LIST_HEAD(of_pci_msi_chip_list);
-diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
-index 90f5cca..382fd3d 100644
---- a/drivers/pci/host/Kconfig
-+++ b/drivers/pci/host/Kconfig
-@@ -63,4 +63,14 @@ config PCIE_SPEAR13XX
- 	help
- 	  Say Y here if you want PCIe support on SPEAr13XX SoCs.
+ enum amd_xgbe_phy_speedset {
+-	AMD_XGBE_PHY_SPEEDSET_1000_10000,
++	AMD_XGBE_PHY_SPEEDSET_1000_10000 = 0,
+ 	AMD_XGBE_PHY_SPEEDSET_2500_10000,
+ };
  
-+config PCI_XGENE
-+	bool "X-Gene PCIe controller"
-+	depends on ARCH_XGENE
-+	depends on OF
-+	select PCIEPORTBUS
-+	help
-+	  Say Y here if you want internal PCI support on APM X-Gene SoC.
-+	  There are 5 internal PCIe ports available. Each port is GEN3 capable
-+	  and have varied lanes from x1 to x8.
-+
- endmenu
-diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
-index d0e88f1..845611f 100644
---- a/drivers/pci/host/Makefile
-+++ b/drivers/pci/host/Makefile
-@@ -8,3 +8,4 @@ obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
- obj-$(CONFIG_PCI_RCAR_GEN2_PCIE) += pcie-rcar.o
- obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
- obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
-+obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
-diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
-index 0fb0fdb..946935d 100644
---- a/drivers/pci/host/pci-tegra.c
-+++ b/drivers/pci/host/pci-tegra.c
-@@ -626,13 +626,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
- static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
- {
- 	struct tegra_pcie *pcie = sys_to_pcie(sys);
-+	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
+ struct amd_xgbe_phy_priv {
+ 	struct platform_device *pdev;
++	struct acpi_device *adev;
+ 	struct device *dev;
+ 
+ 	struct phy_device *phydev;
  
- 	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
- 	pci_add_resource_offset(&sys->resources, &pcie->prefetch,
- 				sys->mem_offset);
- 	pci_add_resource(&sys->resources, &pcie->busn);
+ 	/* SerDes related mmio resources */
+ 	struct resource *rxtx_res;
+-	struct resource *sir0_res;
+-	struct resource *sir1_res;
++	struct resource *cmu_res;
  
--	pci_ioremap_io(nr * SZ_64K, pcie->io.start);
-+	pci_ioremap_io(nr * SZ_64K, io_start);
+ 	/* SerDes related mmio registers */
+ 	void __iomem *rxtx_regs;	/* SerDes Rx/Tx CSRs */
+-	void __iomem *sir0_regs;	/* SerDes integration registers (1/2) */
+-	void __iomem *sir1_regs;	/* SerDes integration registers (2/2) */
++	void __iomem *cmu_regs;		/* SerDes CMU CSRs */
++
++	unsigned int serdes_channel;
++	unsigned int speed_set;
  
- 	return 1;
- }
-@@ -737,6 +738,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
- static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
- {
- 	u32 fpci_bar, size, axi_address;
-+	phys_addr_t io_start = pci_pio_to_address(pcie->io.start);
- 
- 	/* Bar 0: type 1 extended configuration space */
- 	fpci_bar = 0xfe100000;
-@@ -749,7 +751,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
- 	/* Bar 1: downstream IO bar */
- 	fpci_bar = 0xfdfc0000;
- 	size = resource_size(&pcie->io);
--	axi_address = pcie->io.start;
-+	axi_address = io_start;
- 	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
- 	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
- 	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
-@@ -1520,7 +1522,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
- 	}
+ 	/* Maintain link status for re-starting auto-negotiation */
+ 	unsigned int link;
+-	unsigned int speed_set;
++	enum amd_xgbe_phy_mode mode;
  
- 	for_each_of_pci_range(&parser, &range) {
--		of_pci_range_to_resource(&range, np, &res);
-+		err = of_pci_range_to_resource(&range, np, &res);
-+		if (err < 0)
-+			return err;
+ 	/* Auto-negotiation state machine support */
+ 	struct mutex an_mutex;
+@@ -348,7 +287,6 @@ struct amd_xgbe_phy_priv {
+ 	enum amd_xgbe_phy_rx kx_state;
+ 	struct work_struct an_work;
+ 	struct workqueue_struct *an_workqueue;
+-	unsigned int parallel_detect;
+ };
  
- 		switch (res.flags & IORESOURCE_TYPE_BITS) {
- 		case IORESOURCE_IO:
-diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
-new file mode 100644
-index 0000000..41c76b8
---- /dev/null
-+++ b/drivers/pci/host/pci-xgene.c
-@@ -0,0 +1,659 @@
-+/**
-+ * APM X-Gene PCIe Driver
-+ *
-+ * Copyright (c) 2014 Applied Micro Circuits Corporation.
-+ *
-+ * Author: Tanmay Inamdar <tinamdar at apm.com>.
-+ *
-+ * This program is free software; you can redistribute  it and/or modify it
-+ * under  the terms of  the GNU General  Public License as published by the
-+ * Free Software Foundation;  either version 2 of the  License, or (at your
-+ * option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+#include <linux/clk-private.h>
-+#include <linux/delay.h>
-+#include <linux/io.h>
-+#include <linux/jiffies.h>
-+#include <linux/memblock.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_pci.h>
-+#include <linux/pci.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+
-+#define PCIECORE_CTLANDSTATUS		0x50
-+#define PIM1_1L				0x80
-+#define IBAR2				0x98
-+#define IR2MSK				0x9c
-+#define PIM2_1L				0xa0
-+#define IBAR3L				0xb4
-+#define IR3MSKL				0xbc
-+#define PIM3_1L				0xc4
-+#define OMR1BARL			0x100
-+#define OMR2BARL			0x118
-+#define OMR3BARL			0x130
-+#define CFGBARL				0x154
-+#define CFGBARH				0x158
-+#define CFGCTL				0x15c
-+#define RTDID				0x160
-+#define BRIDGE_CFG_0			0x2000
-+#define BRIDGE_CFG_4			0x2010
-+#define BRIDGE_STATUS_0			0x2600
-+
-+#define LINK_UP_MASK			0x00000100
-+#define AXI_EP_CFG_ACCESS		0x10000
-+#define EN_COHERENCY			0xF0000000
-+#define EN_REG				0x00000001
-+#define OB_LO_IO			0x00000002
-+#define XGENE_PCIE_VENDORID		0x10E8
-+#define XGENE_PCIE_DEVICEID		0xE004
-+#define SZ_1T				(SZ_1G*1024ULL)
-+#define PIPE_PHY_RATE_RD(src)		((0xc000 & (u32)(src)) >> 0xe)
-+
-+struct xgene_pcie_port {
-+	struct device_node	*node;
-+	struct device		*dev;
-+	struct clk		*clk;
-+	void __iomem		*csr_base;
-+	void __iomem		*cfg_base;
-+	unsigned long		cfg_addr;
-+	bool			link_up;
-+};
-+
-+static inline u32 pcie_bar_low_val(u32 addr, u32 flags)
-+{
-+	return (addr & PCI_BASE_ADDRESS_MEM_MASK) | flags;
-+}
-+
-+/* PCIE Configuration Out/In */
-+static inline void xgene_pcie_cfg_out32(void __iomem *addr, int offset, u32 val)
-+{
-+	writel(val, addr + offset);
-+}
-+
-+static inline void xgene_pcie_cfg_out16(void __iomem *addr, int offset, u16 val)
-+{
-+	u32 val32 = readl(addr + (offset & ~0x3));
-+
-+	switch (offset & 0x3) {
-+	case 2:
-+		val32 &= ~0xFFFF0000;
-+		val32 |= (u32)val << 16;
-+		break;
-+	case 0:
-+	default:
-+		val32 &= ~0xFFFF;
-+		val32 |= val;
-+		break;
-+	}
-+	writel(val32, addr + (offset & ~0x3));
-+}
-+
-+static inline void xgene_pcie_cfg_out8(void __iomem *addr, int offset, u8 val)
-+{
-+	u32 val32 = readl(addr + (offset & ~0x3));
-+
-+	switch (offset & 0x3) {
-+	case 0:
-+		val32 &= ~0xFF;
-+		val32 |= val;
-+		break;
-+	case 1:
-+		val32 &= ~0xFF00;
-+		val32 |= (u32)val << 8;
-+		break;
-+	case 2:
-+		val32 &= ~0xFF0000;
-+		val32 |= (u32)val << 16;
-+		break;
-+	case 3:
-+	default:
-+		val32 &= ~0xFF000000;
-+		val32 |= (u32)val << 24;
-+		break;
-+	}
-+	writel(val32, addr + (offset & ~0x3));
-+}
-+
-+static inline void xgene_pcie_cfg_in32(void __iomem *addr, int offset, u32 *val)
-+{
-+	*val = readl(addr + offset);
-+}
-+
-+static inline void xgene_pcie_cfg_in16(void __iomem *addr, int offset, u32 *val)
-+{
-+	*val = readl(addr + (offset & ~0x3));
-+
-+	switch (offset & 0x3) {
-+	case 2:
-+		*val >>= 16;
-+		break;
-+	}
-+
-+	*val &= 0xFFFF;
-+}
-+
-+static inline void xgene_pcie_cfg_in8(void __iomem *addr, int offset, u32 *val)
-+{
-+	*val = readl(addr + (offset & ~0x3));
-+
-+	switch (offset & 0x3) {
-+	case 3:
-+		*val = *val >> 24;
-+		break;
-+	case 2:
-+		*val = *val >> 16;
-+		break;
-+	case 1:
-+		*val = *val >> 8;
-+		break;
-+	}
-+	*val &= 0xFF;
-+}
-+
-+/*
-+ * When the address bit [17:16] is 2'b01, the Configuration access will be
-+ * treated as Type 1 and it will be forwarded to external PCIe device.
-+ */
-+static void __iomem *xgene_pcie_get_cfg_base(struct pci_bus *bus)
-+{
-+	struct xgene_pcie_port *port = bus->sysdata;
-+
-+	if (bus->number >= (bus->primary + 1))
-+		return port->cfg_base + AXI_EP_CFG_ACCESS;
-+
-+	return port->cfg_base;
-+}
-+
-+/*
-+ * For Configuration request, RTDID register is used as Bus Number,
-+ * Device Number and Function number of the header fields.
-+ */
-+static void xgene_pcie_set_rtdid_reg(struct pci_bus *bus, uint devfn)
-+{
-+	struct xgene_pcie_port *port = bus->sysdata;
-+	unsigned int b, d, f;
-+	u32 rtdid_val = 0;
-+
-+	b = bus->number;
-+	d = PCI_SLOT(devfn);
-+	f = PCI_FUNC(devfn);
-+
-+	if (!pci_is_root_bus(bus))
-+		rtdid_val = (b << 8) | (d << 3) | f;
-+
-+	writel(rtdid_val, port->csr_base + RTDID);
-+	/* read the register back to ensure flush */
-+	readl(port->csr_base + RTDID);
-+}
-+
-+/*
-+ * X-Gene PCIe port uses BAR0-BAR1 of RC's configuration space as
-+ * the translation between PCI bus to native BUS. Entire DDR region
-+ * is mapped on to PCIe space using these registers, so that it is
-+ * accessible for EP devices for DMA. The BAR0/1 of bridge should be
-+ * hidden during enumeration to avoid the sizing and resource allocation
-+ * by PCIe core.
-+ */
-+static bool xgene_pcie_hide_rc_bars(struct pci_bus *bus, int offset)
-+{
-+	if (pci_is_root_bus(bus) && ((offset == PCI_BASE_ADDRESS_0) ||
-+				     (offset == PCI_BASE_ADDRESS_1)))
-+		return true;
-+
-+	return false;
-+}
+ static int amd_xgbe_an_enable_kr_training(struct phy_device *phydev)
+@@ -401,33 +339,51 @@ static int amd_xgbe_phy_pcs_power_cycle(struct phy_device *phydev)
+ static void amd_xgbe_phy_serdes_start_ratechange(struct phy_device *phydev)
+ {
+ 	struct amd_xgbe_phy_priv *priv = phydev->priv;
++	u16 val, mask;
 +
-+static int xgene_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
-+				  int offset, int len, u32 *val)
-+{
-+	struct xgene_pcie_port *port = bus->sysdata;
-+	void __iomem *addr;
++	/* Assert Rx and Tx ratechange in CMU_reg16 */
++	val = XCMU_IOREAD(priv, CMU_REG16);
+ 
+-	/* Assert Rx and Tx ratechange */
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, RATECHANGE, 1);
++	mask = (1 << (CMU_REG16_TX_RATE_CHANGE_BASE -
++		      (priv->serdes_channel * CMU_REG16_RATE_CHANGE_DECR))) |
++	       (1 << (CMU_REG16_RX_RATE_CHANGE_BASE -
++		      (priv->serdes_channel * CMU_REG16_RATE_CHANGE_DECR)));
++	val |= mask;
 +
-+	if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up)
-+		return PCIBIOS_DEVICE_NOT_FOUND;
++	XCMU_IOWRITE(priv, CMU_REG16, val);
+ }
+ 
+ static void amd_xgbe_phy_serdes_complete_ratechange(struct phy_device *phydev)
+ {
+ 	struct amd_xgbe_phy_priv *priv = phydev->priv;
++	u16 val, mask;
+ 	unsigned int wait;
+-	u16 status;
+ 
+-	/* Release Rx and Tx ratechange */
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, RATECHANGE, 0);
++	/* Release Rx and Tx ratechange for proper channel in CMU_reg16 */
++	val = XCMU_IOREAD(priv, CMU_REG16);
 +
-+	if (xgene_pcie_hide_rc_bars(bus, offset)) {
-+		*val = 0;
-+		return PCIBIOS_SUCCESSFUL;
-+	}
++	mask = (1 << (CMU_REG16_TX_RATE_CHANGE_BASE -
++		      (priv->serdes_channel * CMU_REG16_RATE_CHANGE_DECR))) |
++	       (1 << (CMU_REG16_RX_RATE_CHANGE_BASE -
++		      (priv->serdes_channel * CMU_REG16_RATE_CHANGE_DECR)));
++	val &= ~mask;
+ 
+-	/* Wait for Rx and Tx ready */
++	XCMU_IOWRITE(priv, CMU_REG16, val);
 +
-+	xgene_pcie_set_rtdid_reg(bus, devfn);
-+	addr = xgene_pcie_get_cfg_base(bus);
-+	switch (len) {
-+	case 1:
-+		xgene_pcie_cfg_in8(addr, offset, val);
-+		break;
-+	case 2:
-+		xgene_pcie_cfg_in16(addr, offset, val);
-+		break;
-+	default:
-+		xgene_pcie_cfg_in32(addr, offset, val);
-+		break;
-+	}
++	/* Wait for Rx and Tx ready in CMU_reg15 */
++	mask = (1 << priv->serdes_channel) |
++	       (1 << (priv->serdes_channel + 8));
+ 	wait = XGBE_PHY_RATECHANGE_COUNT;
+ 	while (wait--) {
+-		usleep_range(50, 75);
++		udelay(50);
+ 
+-		status = XSIR0_IOREAD(priv, SIR0_STATUS);
+-		if (XSIR_GET_BITS(status, SIR0_STATUS, RX_READY) &&
+-		    XSIR_GET_BITS(status, SIR0_STATUS, TX_READY))
++		val = XCMU_IOREAD(priv, CMU_REG15);
++		if ((val & mask) == mask)
+ 			return;
+ 	}
+ 
+ 	netdev_dbg(phydev->attached_dev, "SerDes rx/tx not ready (%#hx)\n",
+-		   status);
++		   val);
+ }
+ 
+ static int amd_xgbe_phy_xgmii_mode(struct phy_device *phydev)
+@@ -435,8 +391,8 @@ static int amd_xgbe_phy_xgmii_mode(struct phy_device *phydev)
+ 	struct amd_xgbe_phy_priv *priv = phydev->priv;
+ 	int ret;
+ 
+-	/* Enable KR training */
+-	ret = amd_xgbe_an_enable_kr_training(phydev);
++	/* Disable KR training */
++	ret = amd_xgbe_an_disable_kr_training(phydev);
+ 	if (ret < 0)
+ 		return ret;
+ 
+@@ -462,19 +418,32 @@ static int amd_xgbe_phy_xgmii_mode(struct phy_device *phydev)
+ 		return ret;
+ 
+ 	/* Set SerDes to 10G speed */
++	spin_lock(&cmu_lock);
 +
-+	return PCIBIOS_SUCCESSFUL;
-+}
+ 	amd_xgbe_phy_serdes_start_ratechange(phydev);
+ 
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, DATARATE, SPEED_10000_RATE);
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, WORDMODE, SPEED_10000_WORD);
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, TXAMP, SPEED_10000_TXAMP);
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, PLLSEL, SPEED_10000_PLL);
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, PI_SPD_SEL, SPEED_10000_CDR);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_DATA_RATE, RXTX_FULL_RATE);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_WORD_MODE, RXTX_66BIT_WORD);
+ 
+-	XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA, RXTX_10000_BLWC);
+-	XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG, RXTX_10000_PQ);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG5, TXAMP_CNTL, RXTX_10G_TX_AMP);
 +
-+static int xgene_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
-+				   int offset, int len, u32 val)
-+{
-+	struct xgene_pcie_port *port = bus->sysdata;
-+	void __iomem *addr;
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_DATA_RATE, RXTX_FULL_RATE);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_WORD_MODE, RXTX_66BIT_WORD);
 +
-+	if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up)
-+		return PCIBIOS_DEVICE_NOT_FOUND;
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA, 0);
 +
-+	if (xgene_pcie_hide_rc_bars(bus, offset))
-+		return PCIBIOS_SUCCESSFUL;
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, RX_PLLSELECT, RXTX_10G_PLL);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, TX_PLLSELECT, RXTX_10G_PLL);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, PI_SPD_SEL_CDR, RXTX_10G_CDR);
 +
-+	xgene_pcie_set_rtdid_reg(bus, devfn);
-+	addr = xgene_pcie_get_cfg_base(bus);
-+	switch (len) {
-+	case 1:
-+		xgene_pcie_cfg_out8(addr, offset, (u8)val);
-+		break;
-+	case 2:
-+		xgene_pcie_cfg_out16(addr, offset, (u16)val);
-+		break;
-+	default:
-+		xgene_pcie_cfg_out32(addr, offset, val);
-+		break;
-+	}
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG, RXTX_10G_PQ);
+ 
+ 	amd_xgbe_phy_serdes_complete_ratechange(phydev);
+ 
++	spin_unlock(&cmu_lock);
 +
-+	return PCIBIOS_SUCCESSFUL;
-+}
++	priv->mode = AMD_XGBE_MODE_KR;
 +
-+static struct pci_ops xgene_pcie_ops = {
-+	.read = xgene_pcie_read_config,
-+	.write = xgene_pcie_write_config
-+};
+ 	return 0;
+ }
+ 
+@@ -510,19 +479,32 @@ static int amd_xgbe_phy_gmii_2500_mode(struct phy_device *phydev)
+ 		return ret;
+ 
+ 	/* Set SerDes to 2.5G speed */
++	spin_lock(&cmu_lock);
 +
-+static u64 xgene_pcie_set_ib_mask(void __iomem *csr_base, u32 addr,
-+				  u32 flags, u64 size)
-+{
-+	u64 mask = (~(size - 1) & PCI_BASE_ADDRESS_MEM_MASK) | flags;
-+	u32 val32 = 0;
-+	u32 val;
+ 	amd_xgbe_phy_serdes_start_ratechange(phydev);
+ 
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, DATARATE, SPEED_2500_RATE);
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, WORDMODE, SPEED_2500_WORD);
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, TXAMP, SPEED_2500_TXAMP);
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, PLLSEL, SPEED_2500_PLL);
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, PI_SPD_SEL, SPEED_2500_CDR);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_DATA_RATE, RXTX_HALF_RATE);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_WORD_MODE, RXTX_10BIT_WORD);
 +
-+	val32 = readl(csr_base + addr);
-+	val = (val32 & 0x0000ffff) | (lower_32_bits(mask) << 16);
-+	writel(val, csr_base + addr);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG5, TXAMP_CNTL, RXTX_1G_TX_AMP);
 +
-+	val32 = readl(csr_base + addr + 0x04);
-+	val = (val32 & 0xffff0000) | (lower_32_bits(mask) >> 16);
-+	writel(val, csr_base + addr + 0x04);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_DATA_RATE, RXTX_HALF_RATE);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_WORD_MODE, RXTX_10BIT_WORD);
+ 
+-	XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA, RXTX_2500_BLWC);
+-	XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG, RXTX_2500_PQ);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA, 1);
 +
-+	val32 = readl(csr_base + addr + 0x04);
-+	val = (val32 & 0x0000ffff) | (upper_32_bits(mask) << 16);
-+	writel(val, csr_base + addr + 0x04);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, RX_PLLSELECT, RXTX_1G_PLL);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, TX_PLLSELECT, RXTX_1G_PLL);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, PI_SPD_SEL_CDR, RXTX_1G_CDR);
 +
-+	val32 = readl(csr_base + addr + 0x08);
-+	val = (val32 & 0xffff0000) | (upper_32_bits(mask) >> 16);
-+	writel(val, csr_base + addr + 0x08);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG, RXTX_1G_PQ);
+ 
+ 	amd_xgbe_phy_serdes_complete_ratechange(phydev);
+ 
++	spin_unlock(&cmu_lock);
 +
-+	return mask;
-+}
++	priv->mode = AMD_XGBE_MODE_KX;
 +
-+static void xgene_pcie_linkup(struct xgene_pcie_port *port,
-+				   u32 *lanes, u32 *speed)
-+{
-+	void __iomem *csr_base = port->csr_base;
-+	u32 val32;
+ 	return 0;
+ }
+ 
+@@ -558,47 +540,33 @@ static int amd_xgbe_phy_gmii_mode(struct phy_device *phydev)
+ 		return ret;
+ 
+ 	/* Set SerDes to 1G speed */
++	spin_lock(&cmu_lock);
 +
-+	port->link_up = false;
-+	val32 = readl(csr_base + PCIECORE_CTLANDSTATUS);
-+	if (val32 & LINK_UP_MASK) {
-+		port->link_up = true;
-+		*speed = PIPE_PHY_RATE_RD(val32);
-+		val32 = readl(csr_base + BRIDGE_STATUS_0);
-+		*lanes = val32 >> 26;
-+	}
-+}
+ 	amd_xgbe_phy_serdes_start_ratechange(phydev);
+ 
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, DATARATE, SPEED_1000_RATE);
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, WORDMODE, SPEED_1000_WORD);
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, TXAMP, SPEED_1000_TXAMP);
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, PLLSEL, SPEED_1000_PLL);
+-	XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, PI_SPD_SEL, SPEED_1000_CDR);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_DATA_RATE, RXTX_FIFTH_RATE);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG3, TX_WORD_MODE, RXTX_10BIT_WORD);
+ 
+-	XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA, RXTX_1000_BLWC);
+-	XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG, RXTX_1000_PQ);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG5, TXAMP_CNTL, RXTX_1G_TX_AMP);
+ 
+-	amd_xgbe_phy_serdes_complete_ratechange(phydev);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_DATA_RATE, RXTX_FIFTH_RATE);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG6, RX_WORD_MODE, RXTX_10BIT_WORD);
+ 
+-	return 0;
+-}
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA, 1);
+ 
+-static int amd_xgbe_phy_cur_mode(struct phy_device *phydev,
+-				 enum amd_xgbe_phy_mode *mode)
+-{
+-	int ret;
+-
+-	ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2);
+-	if (ret < 0)
+-		return ret;
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, RX_PLLSELECT, RXTX_1G_PLL);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, TX_PLLSELECT, RXTX_1G_PLL);
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG53, PI_SPD_SEL_CDR, RXTX_1G_CDR);
+ 
+-	if ((ret & MDIO_PCS_CTRL2_TYPE) == MDIO_PCS_CTRL2_10GBR)
+-		*mode = AMD_XGBE_MODE_KR;
+-	else
+-		*mode = AMD_XGBE_MODE_KX;
++	XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG, RXTX_1G_PQ);
+ 
+-	return 0;
+-}
++	amd_xgbe_phy_serdes_complete_ratechange(phydev);
+ 
+-static bool amd_xgbe_phy_in_kr_mode(struct phy_device *phydev)
+-{
+-	enum amd_xgbe_phy_mode mode;
++	spin_unlock(&cmu_lock);
+ 
+-	if (amd_xgbe_phy_cur_mode(phydev, &mode))
+-		return false;
++	priv->mode = AMD_XGBE_MODE_KX;
+ 
+-	return (mode == AMD_XGBE_MODE_KR);
++	return 0;
+ }
+ 
+ static int amd_xgbe_phy_switch_mode(struct phy_device *phydev)
+@@ -607,7 +575,7 @@ static int amd_xgbe_phy_switch_mode(struct phy_device *phydev)
+ 	int ret;
+ 
+ 	/* If we are in KR switch to KX, and vice-versa */
+-	if (amd_xgbe_phy_in_kr_mode(phydev)) {
++	if (priv->mode == AMD_XGBE_MODE_KR) {
+ 		if (priv->speed_set == AMD_XGBE_PHY_SPEEDSET_1000_10000)
+ 			ret = amd_xgbe_phy_gmii_mode(phydev);
+ 		else
+@@ -619,20 +587,15 @@ static int amd_xgbe_phy_switch_mode(struct phy_device *phydev)
+ 	return ret;
+ }
+ 
+-static int amd_xgbe_phy_set_mode(struct phy_device *phydev,
+-				 enum amd_xgbe_phy_mode mode)
++static enum amd_xgbe_phy_an amd_xgbe_an_switch_mode(struct phy_device *phydev)
+ {
+-	enum amd_xgbe_phy_mode cur_mode;
+ 	int ret;
+ 
+-	ret = amd_xgbe_phy_cur_mode(phydev, &cur_mode);
+-	if (ret)
+-		return ret;
+-
+-	if (mode != cur_mode)
+-		ret = amd_xgbe_phy_switch_mode(phydev);
++	ret = amd_xgbe_phy_switch_mode(phydev);
++	if (ret < 0)
++		return AMD_XGBE_AN_ERROR;
+ 
+-	return ret;
++	return AMD_XGBE_AN_START;
+ }
+ 
+ static enum amd_xgbe_phy_an amd_xgbe_an_tx_training(struct phy_device *phydev,
+@@ -643,8 +606,8 @@ static enum amd_xgbe_phy_an amd_xgbe_an_tx_training(struct phy_device *phydev,
+ 
+ 	*state = AMD_XGBE_RX_COMPLETE;
+ 
+-	/* If we're not in KR mode then we're done */
+-	if (!amd_xgbe_phy_in_kr_mode(phydev))
++	/* If we're in KX mode then we're done */
++	if (priv->mode == AMD_XGBE_MODE_KX)
+ 		return AMD_XGBE_AN_EVENT;
+ 
+ 	/* Enable/Disable FEC */
+@@ -672,13 +635,9 @@ static enum amd_xgbe_phy_an amd_xgbe_an_tx_training(struct phy_device *phydev,
+ 	if (ret < 0)
+ 		return AMD_XGBE_AN_ERROR;
+ 
+-	XSIR0_IOWRITE_BITS(priv, SIR0_KR_RT_1, RESET, 1);
+-
+ 	ret |= 0x01;
+ 	phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, ret);
+ 
+-	XSIR0_IOWRITE_BITS(priv, SIR0_KR_RT_1, RESET, 0);
+-
+ 	return AMD_XGBE_AN_EVENT;
+ }
+ 
+@@ -702,6 +661,7 @@ static enum amd_xgbe_phy_an amd_xgbe_an_tx_xnp(struct phy_device *phydev,
+ static enum amd_xgbe_phy_an amd_xgbe_an_rx_bpa(struct phy_device *phydev,
+ 					       enum amd_xgbe_phy_rx *state)
+ {
++	struct amd_xgbe_phy_priv *priv = phydev->priv;
+ 	unsigned int link_support;
+ 	int ret, ad_reg, lp_reg;
+ 
+@@ -711,9 +671,9 @@ static enum amd_xgbe_phy_an amd_xgbe_an_rx_bpa(struct phy_device *phydev,
+ 		return AMD_XGBE_AN_ERROR;
+ 
+ 	/* Check for a supported mode, otherwise restart in a different one */
+-	link_support = amd_xgbe_phy_in_kr_mode(phydev) ? 0x80 : 0x20;
++	link_support = (priv->mode == AMD_XGBE_MODE_KR) ? 0x80 : 0x20;
+ 	if (!(ret & link_support))
+-		return AMD_XGBE_AN_INCOMPAT_LINK;
++		return amd_xgbe_an_switch_mode(phydev);
+ 
+ 	/* Check Extended Next Page support */
+ 	ad_reg = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
+@@ -754,7 +714,7 @@ static enum amd_xgbe_phy_an amd_xgbe_an_start(struct phy_device *phydev)
+ 	int ret;
+ 
+ 	/* Be sure we aren't looping trying to negotiate */
+-	if (amd_xgbe_phy_in_kr_mode(phydev)) {
++	if (priv->mode == AMD_XGBE_MODE_KR) {
+ 		if (priv->kr_state != AMD_XGBE_RX_READY)
+ 			return AMD_XGBE_AN_NO_LINK;
+ 		priv->kr_state = AMD_XGBE_RX_BPA;
+@@ -817,13 +777,6 @@ static enum amd_xgbe_phy_an amd_xgbe_an_start(struct phy_device *phydev)
+ 	/* Enable and start auto-negotiation */
+ 	phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_INT, 0);
+ 
+-	ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_KR_CTRL);
+-	if (ret < 0)
+-		return AMD_XGBE_AN_ERROR;
+-
+-	ret |= MDIO_KR_CTRL_PDETECT;
+-	phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_KR_CTRL, ret);
+-
+ 	ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
+ 	if (ret < 0)
+ 		return AMD_XGBE_AN_ERROR;
+@@ -864,8 +817,8 @@ static enum amd_xgbe_phy_an amd_xgbe_an_page_received(struct phy_device *phydev)
+ 	enum amd_xgbe_phy_rx *state;
+ 	int ret;
+ 
+-	state = amd_xgbe_phy_in_kr_mode(phydev) ? &priv->kr_state
+-						: &priv->kx_state;
++	state = (priv->mode == AMD_XGBE_MODE_KR) ? &priv->kr_state
++						 : &priv->kx_state;
+ 
+ 	switch (*state) {
+ 	case AMD_XGBE_RX_BPA:
+@@ -885,13 +838,7 @@ static enum amd_xgbe_phy_an amd_xgbe_an_page_received(struct phy_device *phydev)
+ 
+ static enum amd_xgbe_phy_an amd_xgbe_an_incompat_link(struct phy_device *phydev)
+ {
+-	int ret;
+-
+-	ret = amd_xgbe_phy_switch_mode(phydev);
+-	if (ret)
+-		return AMD_XGBE_AN_ERROR;
+-
+-	return AMD_XGBE_AN_START;
++	return amd_xgbe_an_switch_mode(phydev);
+ }
+ 
+ static void amd_xgbe_an_state_machine(struct work_struct *work)
+@@ -904,10 +851,6 @@ static void amd_xgbe_an_state_machine(struct work_struct *work)
+ 	int sleep;
+ 	unsigned int an_supported = 0;
+ 
+-	/* Start in KX mode */
+-	if (amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KX))
+-		priv->an_state = AMD_XGBE_AN_ERROR;
+-
+ 	while (1) {
+ 		mutex_lock(&priv->an_mutex);
+ 
+@@ -915,9 +858,8 @@ static void amd_xgbe_an_state_machine(struct work_struct *work)
+ 
+ 		switch (priv->an_state) {
+ 		case AMD_XGBE_AN_START:
+-			an_supported = 0;
+-			priv->parallel_detect = 0;
+ 			priv->an_state = amd_xgbe_an_start(phydev);
++			an_supported = 0;
+ 			break;
+ 
+ 		case AMD_XGBE_AN_EVENT:
+@@ -934,7 +876,6 @@ static void amd_xgbe_an_state_machine(struct work_struct *work)
+ 			break;
+ 
+ 		case AMD_XGBE_AN_COMPLETE:
+-			priv->parallel_detect = an_supported ? 0 : 1;
+ 			netdev_info(phydev->attached_dev, "%s successful\n",
+ 				    an_supported ? "Auto negotiation"
+ 						 : "Parallel detection");
+@@ -1069,6 +1010,7 @@ static int amd_xgbe_phy_config_aneg(struct phy_device *phydev)
+ {
+ 	struct amd_xgbe_phy_priv *priv = phydev->priv;
+ 	u32 mmd_mask = phydev->c45_ids.devices_in_package;
++	int ret;
+ 
+ 	if (phydev->autoneg != AUTONEG_ENABLE)
+ 		return amd_xgbe_phy_setup_forced(phydev);
+@@ -1077,6 +1019,11 @@ static int amd_xgbe_phy_config_aneg(struct phy_device *phydev)
+ 	if (!(mmd_mask & MDIO_DEVS_AN))
+ 		return -EINVAL;
+ 
++	/* Get the current speed mode */
++	ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2);
++	if (ret < 0)
++		return ret;
 +
-+static int xgene_pcie_init_port(struct xgene_pcie_port *port)
+ 	/* Start/Restart the auto-negotiation state machine */
+ 	mutex_lock(&priv->an_mutex);
+ 	priv->an_result = AMD_XGBE_AN_READY;
+@@ -1166,14 +1113,18 @@ static int amd_xgbe_phy_read_status(struct phy_device *phydev)
+ {
+ 	struct amd_xgbe_phy_priv *priv = phydev->priv;
+ 	u32 mmd_mask = phydev->c45_ids.devices_in_package;
+-	int ret, ad_ret, lp_ret;
++	int ret, mode, ad_ret, lp_ret;
+ 
+ 	ret = amd_xgbe_phy_update_link(phydev);
+ 	if (ret)
+ 		return ret;
+ 
+-	if ((phydev->autoneg == AUTONEG_ENABLE) &&
+-	    !priv->parallel_detect) {
++	mode = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2);
++	if (mode < 0)
++		return mode;
++	mode &= MDIO_PCS_CTRL2_TYPE;
++
++	if (phydev->autoneg == AUTONEG_ENABLE) {
+ 		if (!(mmd_mask & MDIO_DEVS_AN))
+ 			return -EINVAL;
+ 
+@@ -1204,39 +1155,40 @@ static int amd_xgbe_phy_read_status(struct phy_device *phydev)
+ 		ad_ret &= lp_ret;
+ 		if (ad_ret & 0x80) {
+ 			phydev->speed = SPEED_10000;
+-			ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KR);
+-			if (ret)
+-				return ret;
++			if (mode != MDIO_PCS_CTRL2_10GBR) {
++				ret = amd_xgbe_phy_xgmii_mode(phydev);
++				if (ret < 0)
++					return ret;
++			}
+ 		} else {
+-			switch (priv->speed_set) {
+-			case AMD_XGBE_PHY_SPEEDSET_1000_10000:
+-				phydev->speed = SPEED_1000;
+-				break;
++			int (*mode_fcn)(struct phy_device *);
+ 
+-			case AMD_XGBE_PHY_SPEEDSET_2500_10000:
++			if (priv->speed_set ==
++			    AMD_XGBE_PHY_SPEEDSET_1000_10000) {
++				phydev->speed = SPEED_1000;
++				mode_fcn = amd_xgbe_phy_gmii_mode;
++			} else {
+ 				phydev->speed = SPEED_2500;
+-				break;
++				mode_fcn = amd_xgbe_phy_gmii_2500_mode;
+ 			}
+ 
+-			ret = amd_xgbe_phy_set_mode(phydev, AMD_XGBE_MODE_KX);
+-			if (ret)
+-				return ret;
++			if (mode == MDIO_PCS_CTRL2_10GBR) {
++				ret = mode_fcn(phydev);
++				if (ret < 0)
++					return ret;
++			}
+ 		}
+ 
+ 		phydev->duplex = DUPLEX_FULL;
+ 	} else {
+-		if (amd_xgbe_phy_in_kr_mode(phydev)) {
++		if (mode == MDIO_PCS_CTRL2_10GBR) {
+ 			phydev->speed = SPEED_10000;
+ 		} else {
+-			switch (priv->speed_set) {
+-			case AMD_XGBE_PHY_SPEEDSET_1000_10000:
++			if (priv->speed_set ==
++			    AMD_XGBE_PHY_SPEEDSET_1000_10000)
+ 				phydev->speed = SPEED_1000;
+-				break;
+-
+-			case AMD_XGBE_PHY_SPEEDSET_2500_10000:
++			else
+ 				phydev->speed = SPEED_2500;
+-				break;
+-			}
+ 		}
+ 		phydev->duplex = DUPLEX_FULL;
+ 		phydev->pause = 0;
+@@ -1288,29 +1240,188 @@ unlock:
+ 	return ret;
+ }
+ 
++static int amd_xgbe_phy_map_resources(struct amd_xgbe_phy_priv *priv,
++				      struct platform_device *phy_pdev,
++				      unsigned int phy_resnum)
 +{
-+	int rc;
++	struct device *dev = priv->dev;
++	int ret;
 +
-+	port->clk = clk_get(port->dev, NULL);
-+	if (IS_ERR(port->clk)) {
-+		dev_err(port->dev, "clock not available\n");
-+		return -ENODEV;
++	/* Get the device mmio areas */
++	priv->rxtx_res = platform_get_resource(phy_pdev, IORESOURCE_MEM,
++					       phy_resnum++);
++	priv->rxtx_regs = devm_ioremap_resource(dev, priv->rxtx_res);
++	if (IS_ERR(priv->rxtx_regs)) {
++		dev_err(dev, "rxtx ioremap failed\n");
++		return PTR_ERR(priv->rxtx_regs);
 +	}
 +
-+	rc = clk_prepare_enable(port->clk);
-+	if (rc) {
-+		dev_err(port->dev, "clock enable failed\n");
-+		return rc;
++	/* All xgbe phy devices share the CMU registers so retrieve
++	 * the resource and do the ioremap directly rather than
++	 * the devm_ioremap_resource call
++	 */
++	priv->cmu_res = platform_get_resource(phy_pdev, IORESOURCE_MEM,
++					      phy_resnum++);
++	if (!priv->cmu_res) {
++		dev_err(dev, "cmu invalid resource\n");
++		ret = -EINVAL;
++		goto err_rxtx;
++	}
++	priv->cmu_regs = devm_ioremap_nocache(dev, priv->cmu_res->start,
++					      resource_size(priv->cmu_res));
++	if (!priv->cmu_regs) {
++		dev_err(dev, "cmu ioremap failed\n");
++		ret = -ENOMEM;
++		goto err_rxtx;
 +	}
 +
 +	return 0;
-+}
-+
-+static int xgene_pcie_map_reg(struct xgene_pcie_port *port,
-+			      struct platform_device *pdev)
-+{
-+	struct resource *res;
-+
-+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr");
-+	port->csr_base = devm_ioremap_resource(port->dev, res);
-+	if (IS_ERR(port->csr_base))
-+		return PTR_ERR(port->csr_base);
 +
-+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
-+	port->cfg_base = devm_ioremap_resource(port->dev, res);
-+	if (IS_ERR(port->cfg_base))
-+		return PTR_ERR(port->cfg_base);
-+	port->cfg_addr = res->start;
++err_rxtx:
++	devm_iounmap(dev, priv->rxtx_regs);
++	devm_release_mem_region(dev, priv->rxtx_res->start,
++				resource_size(priv->rxtx_res));
 +
-+	return 0;
++	return ret;
 +}
 +
-+static void xgene_pcie_setup_ob_reg(struct xgene_pcie_port *port,
-+				    struct resource *res, u32 offset,
-+				    u64 cpu_addr, u64 pci_addr)
++static void amd_xgbe_phy_unmap_resources(struct amd_xgbe_phy_priv *priv)
 +{
-+	void __iomem *base = port->csr_base + offset;
-+	resource_size_t size = resource_size(res);
-+	u64 restype = resource_type(res);
-+	u64 mask = 0;
-+	u32 min_size;
-+	u32 flag = EN_REG;
-+
-+	if (restype == IORESOURCE_MEM) {
-+		min_size = SZ_128M;
-+	} else {
-+		min_size = 128;
-+		flag |= OB_LO_IO;
-+	}
-+
-+	if (size >= min_size)
-+		mask = ~(size - 1) | flag;
-+	else
-+		dev_warn(port->dev, "res size 0x%llx less than minimum 0x%x\n",
-+			 (u64)size, min_size);
++	struct device *dev = priv->dev;
 +
-+	writel(lower_32_bits(cpu_addr), base);
-+	writel(upper_32_bits(cpu_addr), base + 0x04);
-+	writel(lower_32_bits(mask), base + 0x08);
-+	writel(upper_32_bits(mask), base + 0x0c);
-+	writel(lower_32_bits(pci_addr), base + 0x10);
-+	writel(upper_32_bits(pci_addr), base + 0x14);
-+}
++	devm_iounmap(dev, priv->cmu_regs);
 +
-+static void xgene_pcie_setup_cfg_reg(void __iomem *csr_base, u64 addr)
-+{
-+	writel(lower_32_bits(addr), csr_base + CFGBARL);
-+	writel(upper_32_bits(addr), csr_base + CFGBARH);
-+	writel(EN_REG, csr_base + CFGCTL);
++	devm_iounmap(dev, priv->rxtx_regs);
++	devm_release_mem_region(dev, priv->rxtx_res->start,
++				resource_size(priv->rxtx_res));
 +}
 +
-+static int xgene_pcie_map_ranges(struct xgene_pcie_port *port,
-+				 struct list_head *res,
-+				 resource_size_t io_base)
++#ifdef CONFIG_ACPI
++static int amd_xgbe_phy_acpi_support(struct amd_xgbe_phy_priv *priv)
 +{
-+	struct pci_host_bridge_window *window;
-+	struct device *dev = port->dev;
++	struct platform_device *phy_pdev = priv->pdev;
++	struct acpi_device *adev = priv->adev;
++	struct device *dev = priv->dev;
++	const union acpi_object *property;
 +	int ret;
 +
-+	list_for_each_entry(window, res, list) {
-+		struct resource *res = window->res;
-+		u64 restype = resource_type(res);
++	/* Map the memory resources */
++	ret = amd_xgbe_phy_map_resources(priv, phy_pdev, 2);
++	if (ret)
++		return ret;
 +
-+		dev_dbg(port->dev, "%pR\n", res);
++	/* Get the device serdes channel property */
++	ret = acpi_dev_get_property(adev, XGBE_PHY_CHANNEL_PROPERTY,
++				    ACPI_TYPE_INTEGER, &property);
++	if (ret) {
++		dev_err(dev, "unable to obtain %s acpi property\n",
++			XGBE_PHY_CHANNEL_PROPERTY);
++		goto err_resources;
++	}
++	priv->serdes_channel = property->integer.value;
 +
-+		switch (restype) {
-+		case IORESOURCE_IO:
-+			xgene_pcie_setup_ob_reg(port, res, OMR3BARL, io_base,
-+						res->start - window->offset);
-+			ret = pci_remap_iospace(res, io_base);
-+			if (ret < 0)
-+				return ret;
-+			break;
-+		case IORESOURCE_MEM:
-+			xgene_pcie_setup_ob_reg(port, res, OMR1BARL, res->start,
-+						res->start - window->offset);
-+			break;
-+		case IORESOURCE_BUS:
-+			break;
-+		default:
-+			dev_err(dev, "invalid io resource - %pR\n", res);
-+			return -EINVAL;
-+		}
++	/* Get the device speed set property */
++	ret = acpi_dev_get_property(adev, XGBE_PHY_SPEEDSET_PROPERTY,
++				    ACPI_TYPE_INTEGER, &property);
++	if (ret) {
++		dev_err(dev, "unable to obtain %s acpi property\n",
++			XGBE_PHY_SPEEDSET_PROPERTY);
++		goto err_resources;
 +	}
-+	xgene_pcie_setup_cfg_reg(port->csr_base, port->cfg_addr);
++	priv->speed_set = property->integer.value;
 +
 +	return 0;
-+}
 +
-+static void xgene_pcie_setup_pims(void *addr, u64 pim, u64 size)
++err_resources:
++	amd_xgbe_phy_unmap_resources(priv);
++
++	return ret;
++}
++#else	/* CONFIG_ACPI */
++static int amd_xgbe_phy_acpi_support(struct amd_xgbe_phy_priv *priv)
 +{
-+	writel(lower_32_bits(pim), addr);
-+	writel(upper_32_bits(pim) | EN_COHERENCY, addr + 0x04);
-+	writel(lower_32_bits(size), addr + 0x10);
-+	writel(upper_32_bits(size), addr + 0x14);
++	return -EINVAL;
 +}
++#endif	/* CONFIG_ACPI */
 +
-+/*
-+ * X-Gene PCIe support maximum 3 inbound memory regions
-+ * This function helps to select a region based on size of region
-+ */
-+static int xgene_pcie_select_ib_reg(u8 *ib_reg_mask, u64 size)
++#ifdef CONFIG_OF
++static int amd_xgbe_phy_of_support(struct amd_xgbe_phy_priv *priv)
 +{
-+	if ((size > 4) && (size < SZ_16M) && !(*ib_reg_mask & (1 << 1))) {
-+		*ib_reg_mask |= (1 << 1);
-+		return 1;
-+	}
++	struct platform_device *phy_pdev;
++	struct device_node *bus_node;
++	struct device_node *phy_node;
++	struct device *dev = priv->dev;
++	const __be32 *property;
++	int ret;
 +
-+	if ((size > SZ_1K) && (size < SZ_1T) && !(*ib_reg_mask & (1 << 0))) {
-+		*ib_reg_mask |= (1 << 0);
-+		return 0;
++	bus_node = priv->dev->of_node;
++	phy_node = of_parse_phandle(bus_node, "phy-handle", 0);
++	if (!phy_node) {
++		dev_err(dev, "unable to parse phy-handle\n");
++		return -EINVAL;
 +	}
 +
-+	if ((size > SZ_1M) && (size < SZ_1T) && !(*ib_reg_mask & (1 << 2))) {
-+		*ib_reg_mask |= (1 << 2);
-+		return 2;
++	phy_pdev = of_find_device_by_node(phy_node);
++	if (!phy_pdev) {
++		dev_err(dev, "unable to obtain phy device\n");
++		ret = -EINVAL;
++		goto err_put;
 +	}
 +
-+	return -EINVAL;
-+}
++	/* Map the memory resources */
++	ret = amd_xgbe_phy_map_resources(priv, phy_pdev, 0);
++	if (ret)
++		goto err_put;
 +
-+static void xgene_pcie_setup_ib_reg(struct xgene_pcie_port *port,
-+				    struct of_pci_range *range, u8 *ib_reg_mask)
-+{
-+	void __iomem *csr_base = port->csr_base;
-+	void __iomem *cfg_base = port->cfg_base;
-+	void *bar_addr;
-+	void *pim_addr;
-+	u64 cpu_addr = range->cpu_addr;
-+	u64 pci_addr = range->pci_addr;
-+	u64 size = range->size;
-+	u64 mask = ~(size - 1) | EN_REG;
-+	u32 flags = PCI_BASE_ADDRESS_MEM_TYPE_64;
-+	u32 bar_low;
-+	int region;
-+
-+	region = xgene_pcie_select_ib_reg(ib_reg_mask, range->size);
-+	if (region < 0) {
-+		dev_warn(port->dev, "invalid pcie dma-range config\n");
-+		return;
++	/* Get the device serdes channel property */
++	property = of_get_property(phy_node, XGBE_PHY_CHANNEL_PROPERTY, NULL);
++	if (!property) {
++		dev_err(dev, "unable to obtain %s property\n",
++			XGBE_PHY_CHANNEL_PROPERTY);
++		ret = -EINVAL;
++		goto err_resources;
 +	}
++	priv->serdes_channel = be32_to_cpu(*property);
 +
-+	if (range->flags & IORESOURCE_PREFETCH)
-+		flags |= PCI_BASE_ADDRESS_MEM_PREFETCH;
-+
-+	bar_low = pcie_bar_low_val((u32)cpu_addr, flags);
-+	switch (region) {
-+	case 0:
-+		xgene_pcie_set_ib_mask(csr_base, BRIDGE_CFG_4, flags, size);
-+		bar_addr = cfg_base + PCI_BASE_ADDRESS_0;
-+		writel(bar_low, bar_addr);
-+		writel(upper_32_bits(cpu_addr), bar_addr + 0x4);
-+		pim_addr = csr_base + PIM1_1L;
-+		break;
-+	case 1:
-+		bar_addr = csr_base + IBAR2;
-+		writel(bar_low, bar_addr);
-+		writel(lower_32_bits(mask), csr_base + IR2MSK);
-+		pim_addr = csr_base + PIM2_1L;
-+		break;
-+	case 2:
-+		bar_addr = csr_base + IBAR3L;
-+		writel(bar_low, bar_addr);
-+		writel(upper_32_bits(cpu_addr), bar_addr + 0x4);
-+		writel(lower_32_bits(mask), csr_base + IR3MSKL);
-+		writel(upper_32_bits(mask), csr_base + IR3MSKL + 0x4);
-+		pim_addr = csr_base + PIM3_1L;
-+		break;
-+	}
++	/* Get the device speed set property */
++	property = of_get_property(phy_node, XGBE_PHY_SPEEDSET_PROPERTY, NULL);
++	if (property)
++		priv->speed_set = be32_to_cpu(*property);
 +
-+	xgene_pcie_setup_pims(pim_addr, pci_addr, ~(size - 1));
-+}
++	of_node_put(phy_node);
 +
-+static int pci_dma_range_parser_init(struct of_pci_range_parser *parser,
-+				     struct device_node *node)
-+{
-+	const int na = 3, ns = 2;
-+	int rlen;
++	return 0;
 +
-+	parser->node = node;
-+	parser->pna = of_n_addr_cells(node);
-+	parser->np = parser->pna + na + ns;
++err_resources:
++	amd_xgbe_phy_unmap_resources(priv);
 +
-+	parser->range = of_get_property(node, "dma-ranges", &rlen);
-+	if (!parser->range)
-+		return -ENOENT;
-+	parser->end = parser->range + rlen / sizeof(__be32);
++err_put:
++	of_node_put(phy_node);
 +
-+	return 0;
++	return ret;
 +}
-+
-+static int xgene_pcie_parse_map_dma_ranges(struct xgene_pcie_port *port)
++#else	/* CONFIG_OF */
++static int amd_xgbe_phy_of_support(struct amd_xgbe_phy_priv *priv)
 +{
-+	struct device_node *np = port->node;
-+	struct of_pci_range range;
-+	struct of_pci_range_parser parser;
-+	struct device *dev = port->dev;
-+	u8 ib_reg_mask = 0;
++	return -EINVAL;
++}
++#endif	/* CONFIG_OF */
 +
-+	if (pci_dma_range_parser_init(&parser, np)) {
-+		dev_err(dev, "missing dma-ranges property\n");
-+		return -EINVAL;
-+	}
+ static int amd_xgbe_phy_probe(struct phy_device *phydev)
+ {
+ 	struct amd_xgbe_phy_priv *priv;
+-	struct platform_device *pdev;
+ 	struct device *dev;
+ 	char *wq_name;
+-	const __be32 *property;
+-	unsigned int speed_set;
+ 	int ret;
+ 
+-	if (!phydev->dev.of_node)
++	if (!phydev->bus || !phydev->bus->parent)
+ 		return -EINVAL;
+ 
+-	pdev = of_find_device_by_node(phydev->dev.of_node);
+-	if (!pdev)
+-		return -EINVAL;
+-	dev = &pdev->dev;
++	dev = phydev->bus->parent;
+ 
+ 	wq_name = kasprintf(GFP_KERNEL, "%s-amd-xgbe-phy", phydev->bus->name);
+-	if (!wq_name) {
+-		ret = -ENOMEM;
+-		goto err_pdev;
+-	}
++	if (!wq_name)
++		return -ENOMEM;
+ 
+ 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ 	if (!priv) {
+@@ -1318,86 +1429,54 @@ static int amd_xgbe_phy_probe(struct phy_device *phydev)
+ 		goto err_name;
+ 	}
+ 
+-	priv->pdev = pdev;
++	priv->pdev = to_platform_device(dev);
++	priv->adev = ACPI_COMPANION(dev);
+ 	priv->dev = dev;
+ 	priv->phydev = phydev;
+ 
+-	/* Get the device mmio areas */
+-	priv->rxtx_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-	priv->rxtx_regs = devm_ioremap_resource(dev, priv->rxtx_res);
+-	if (IS_ERR(priv->rxtx_regs)) {
+-		dev_err(dev, "rxtx ioremap failed\n");
+-		ret = PTR_ERR(priv->rxtx_regs);
++	if (priv->adev && !acpi_disabled)
++		ret = amd_xgbe_phy_acpi_support(priv);
++	else
++		ret = amd_xgbe_phy_of_support(priv);
++	if (ret)
+ 		goto err_priv;
+-	}
+-
+-	priv->sir0_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+-	priv->sir0_regs = devm_ioremap_resource(dev, priv->sir0_res);
+-	if (IS_ERR(priv->sir0_regs)) {
+-		dev_err(dev, "sir0 ioremap failed\n");
+-		ret = PTR_ERR(priv->sir0_regs);
+-		goto err_rxtx;
+-	}
+-
+-	priv->sir1_res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+-	priv->sir1_regs = devm_ioremap_resource(dev, priv->sir1_res);
+-	if (IS_ERR(priv->sir1_regs)) {
+-		dev_err(dev, "sir1 ioremap failed\n");
+-		ret = PTR_ERR(priv->sir1_regs);
+-		goto err_sir0;
+-	}
+ 
+-	/* Get the device speed set property */
+-	speed_set = 0;
+-	property = of_get_property(dev->of_node, XGBE_PHY_SPEEDSET_PROPERTY,
+-				   NULL);
+-	if (property)
+-		speed_set = be32_to_cpu(*property);
+-
+-	switch (speed_set) {
+-	case 0:
+-		priv->speed_set = AMD_XGBE_PHY_SPEEDSET_1000_10000;
+-		break;
+-	case 1:
+-		priv->speed_set = AMD_XGBE_PHY_SPEEDSET_2500_10000;
++	switch (priv->speed_set) {
++	case AMD_XGBE_PHY_SPEEDSET_1000_10000:
++	case AMD_XGBE_PHY_SPEEDSET_2500_10000:
+ 		break;
+ 	default:
+ 		dev_err(dev, "invalid amd,speed-set property\n");
+ 		ret = -EINVAL;
+-		goto err_sir1;
++		goto err_resources;
+ 	}
+ 
+ 	priv->link = 1;
+ 
++	ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2);
++	if (ret < 0)
++		goto err_resources;
++	if ((ret & MDIO_PCS_CTRL2_TYPE) == MDIO_PCS_CTRL2_10GBR)
++		priv->mode = AMD_XGBE_MODE_KR;
++	else
++		priv->mode = AMD_XGBE_MODE_KX;
++
+ 	mutex_init(&priv->an_mutex);
+ 	INIT_WORK(&priv->an_work, amd_xgbe_an_state_machine);
+ 	priv->an_workqueue = create_singlethread_workqueue(wq_name);
+ 	if (!priv->an_workqueue) {
+ 		ret = -ENOMEM;
+-		goto err_sir1;
++		goto err_resources;
+ 	}
+ 
+ 	phydev->priv = priv;
+ 
+ 	kfree(wq_name);
+-	of_dev_put(pdev);
+ 
+ 	return 0;
+ 
+-err_sir1:
+-	devm_iounmap(dev, priv->sir1_regs);
+-	devm_release_mem_region(dev, priv->sir1_res->start,
+-				resource_size(priv->sir1_res));
+-
+-err_sir0:
+-	devm_iounmap(dev, priv->sir0_regs);
+-	devm_release_mem_region(dev, priv->sir0_res->start,
+-				resource_size(priv->sir0_res));
+-
+-err_rxtx:
+-	devm_iounmap(dev, priv->rxtx_regs);
+-	devm_release_mem_region(dev, priv->rxtx_res->start,
+-				resource_size(priv->rxtx_res));
++err_resources:
++	amd_xgbe_phy_unmap_resources(priv);
+ 
+ err_priv:
+ 	devm_kfree(dev, priv);
+@@ -1405,9 +1484,6 @@ err_priv:
+ err_name:
+ 	kfree(wq_name);
+ 
+-err_pdev:
+-	of_dev_put(pdev);
+-
+ 	return ret;
+ }
+ 
+@@ -1424,18 +1500,7 @@ static void amd_xgbe_phy_remove(struct phy_device *phydev)
+ 	flush_workqueue(priv->an_workqueue);
+ 	destroy_workqueue(priv->an_workqueue);
+ 
+-	/* Release resources */
+-	devm_iounmap(dev, priv->sir1_regs);
+-	devm_release_mem_region(dev, priv->sir1_res->start,
+-				resource_size(priv->sir1_res));
+-
+-	devm_iounmap(dev, priv->sir0_regs);
+-	devm_release_mem_region(dev, priv->sir0_res->start,
+-				resource_size(priv->sir0_res));
+-
+-	devm_iounmap(dev, priv->rxtx_regs);
+-	devm_release_mem_region(dev, priv->rxtx_res->start,
+-				resource_size(priv->rxtx_res));
++	amd_xgbe_phy_unmap_resources(priv);
+ 
+ 	devm_kfree(dev, priv);
+ }
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index 2305dc0..43999a8 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -1250,6 +1250,39 @@ int of_property_read_u64(const struct device_node *np, const char *propname,
+ EXPORT_SYMBOL_GPL(of_property_read_u64);
+ 
+ /**
++ * of_property_read_u64_array - Find and read an array of 64 bit integers
++ * from a property.
++ *
++ * @np:		device node from which the property value is to be read.
++ * @propname:	name of the property to be searched.
++ * @out_values:	pointer to return value, modified only if return value is 0.
++ * @sz:		number of array elements to read
++ *
++ * Search for a property in a device node and read 64-bit value(s) from
++ * it. Returns 0 on success, -EINVAL if the property does not exist,
++ * -ENODATA if property does not have a value, and -EOVERFLOW if the
++ * property data isn't large enough.
++ *
++ * The out_values is modified only if a valid u64 value can be decoded.
++ */
++int of_property_read_u64_array(const struct device_node *np,
++			       const char *propname, u64 *out_values,
++			       size_t sz)
++{
++	const __be32 *val = of_find_property_value_of_size(np, propname,
++						(sz * sizeof(*out_values)));
 +
-+	/* Get the dma-ranges from DT */
-+	for_each_of_pci_range(&parser, &range) {
-+		u64 end = range.cpu_addr + range.size - 1;
++	if (IS_ERR(val))
++		return PTR_ERR(val);
 +
-+		dev_dbg(port->dev, "0x%08x 0x%016llx..0x%016llx -> 0x%016llx\n",
-+			range.flags, range.cpu_addr, end, range.pci_addr);
-+		xgene_pcie_setup_ib_reg(port, &range, &ib_reg_mask);
++	while (sz--) {
++		*out_values++ = of_read_number(val, 2);
++		val += 2;
 +	}
 +	return 0;
 +}
 +
-+/* clear bar configuration which was done by firmware */
-+static void xgene_pcie_clear_config(struct xgene_pcie_port *port)
-+{
-+	int i;
-+
-+	for (i = PIM1_1L; i <= CFGCTL; i += 4)
-+		writel(0x0, port->csr_base + i);
-+}
-+
-+static int xgene_pcie_setup(struct xgene_pcie_port *port,
-+			    struct list_head *res,
-+			    resource_size_t io_base)
++/**
+  * of_property_read_string - Find and read a string from a property
+  * @np:		device node from which the property value is to be read.
+  * @propname:	name of the property to be searched.
+@@ -1397,6 +1430,49 @@ int of_property_count_strings(struct device_node *np, const char *propname)
+ }
+ EXPORT_SYMBOL_GPL(of_property_count_strings);
+ 
++/**
++ * of_property_read_string_array - Find and read an array of strings
++ * from a multiple strings property.
++ * @np:		device node from which the property value is to be read.
++ * @propname:	name of the property to be searched.
++ * @out_string:	pointer to null terminated return string, modified only if
++ *		return value is 0.
++ * @sz:		number of array elements to read
++ *
++ * Search for a property in a device tree node and retrieve a list of
++ * terminated string value (pointer to data, not a copy) in that property.
++ * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
++ * property does not have a value, and -EOVERFLOW if the string is not
++ * null-terminated within the length of the property data.
++ *
++ * The out_string pointer is modified only if a valid string can be decoded.
++ */
++int of_property_read_string_array(struct device_node *np, const char *propname,
++				  char **output, size_t sz)
 +{
-+	u32 val, lanes = 0, speed = 0;
-+	int ret;
++	struct property *prop = of_find_property(np, propname, NULL);
++	int i = 0;
++	size_t l = 0, total = 0;
++	char *p;
 +
-+	xgene_pcie_clear_config(port);
++	if (!prop)
++		return -EINVAL;
 +
-+	/* setup the vendor and device IDs correctly */
-+	val = (XGENE_PCIE_DEVICEID << 16) | XGENE_PCIE_VENDORID;
-+	writel(val, port->csr_base + BRIDGE_CFG_0);
++	if (!prop->value)
++		return -ENODATA;
 +
-+	ret = xgene_pcie_map_ranges(port, res, io_base);
-+	if (ret)
-+		return ret;
++	if (strnlen(prop->value, prop->length) >= prop->length)
++		return -EOVERFLOW;
 +
-+	ret = xgene_pcie_parse_map_dma_ranges(port);
-+	if (ret)
-+		return ret;
++	p = prop->value;
 +
-+	xgene_pcie_linkup(port, &lanes, &speed);
-+	if (!port->link_up)
-+		dev_info(port->dev, "(rc) link down\n");
-+	else
-+		dev_info(port->dev, "(rc) x%d gen-%d link up\n",
-+				lanes, speed + 1);
++	for (i = 0; total < prop->length; total += l, p += l) {
++		output[i++] = p;
++		l = strlen(p) + 1;
++	}
 +	return 0;
 +}
 +
-+static int xgene_pcie_probe_bridge(struct platform_device *pdev)
-+{
-+	struct device_node *dn = pdev->dev.of_node;
-+	struct xgene_pcie_port *port;
-+	resource_size_t iobase = 0;
-+	struct pci_bus *bus;
-+	int ret;
-+	LIST_HEAD(res);
+ void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
+ {
+ 	int i;
+@@ -2186,3 +2262,113 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
+ 	return of_get_next_parent(np);
+ }
+ EXPORT_SYMBOL(of_graph_get_remote_port);
 +
-+	port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
-+	if (!port)
-+		return -ENOMEM;
-+	port->node = of_node_get(pdev->dev.of_node);
-+	port->dev = &pdev->dev;
++int of_dev_prop_get(struct device_node *dn, const char *propname, void **valptr)
++{
++	struct property *pp = of_find_property(dn, propname, NULL);
 +
-+	ret = xgene_pcie_map_reg(port, pdev);
-+	if (ret)
-+		return ret;
++	if (!pp)
++		return -ENODATA;
 +
-+	ret = xgene_pcie_init_port(port);
-+	if (ret)
-+		return ret;
++	if (valptr)
++		*valptr = pp->value;
++	return 0;
++}
 +
-+	ret = of_pci_get_host_bridge_resources(dn, 0, 0xff, &res, &iobase);
-+	if (ret)
-+		return ret;
++int of_dev_prop_read(struct device_node *dn, const char *propname,
++		     enum dev_prop_type proptype, void *val)
++{
++	void *value;
++	int ret = of_dev_prop_get(dn, propname, &value);
 +
-+	ret = xgene_pcie_setup(port, &res, iobase);
 +	if (ret)
 +		return ret;
 +
-+	bus = pci_scan_root_bus(&pdev->dev, 0, &xgene_pcie_ops, port, &res);
-+	if (!bus)
-+		return -ENOMEM;
++	if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
++		switch (proptype) {
++		case DEV_PROP_U8: {
++			*(u8 *)val = *(u8 *)value;
++			break;
++		}
++		case DEV_PROP_U16:
++			*(u16 *)val = *(u16 *)value;
++			break;
++		case DEV_PROP_U32:
++			*(u32 *)val = *(u32 *)value;
++			break;
++		default:
++			*(u64 *)val = *(u64 *)value;
++			break;
++		}
++	} else if (proptype == DEV_PROP_STRING) {
++		*(char **)val = value;
++	}
++	return ret;
 +
-+	platform_set_drvdata(pdev, port);
-+	return 0;
 +}
 +
-+static const struct of_device_id xgene_pcie_match_table[] = {
-+	{.compatible = "apm,xgene-pcie",},
-+	{},
-+};
-+
-+static struct platform_driver xgene_pcie_driver = {
-+	.driver = {
-+		   .name = "xgene-pcie",
-+		   .owner = THIS_MODULE,
-+		   .of_match_table = of_match_ptr(xgene_pcie_match_table),
-+	},
-+	.probe = xgene_pcie_probe_bridge,
-+};
-+module_platform_driver(xgene_pcie_driver);
-+
-+MODULE_AUTHOR("Tanmay Inamdar <tinamdar at apm.com>");
-+MODULE_DESCRIPTION("APM X-Gene PCIe driver");
-+MODULE_LICENSE("GPL v2");
-diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
-index 4884ee5..61158e0 100644
---- a/drivers/pci/host/pcie-rcar.c
-+++ b/drivers/pci/host/pcie-rcar.c
-@@ -323,6 +323,7 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
- 
- 	/* Setup PCIe address space mappings for each resource */
- 	resource_size_t size;
-+	resource_size_t res_start;
- 	u32 mask;
- 
- 	rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
-@@ -335,8 +336,13 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
- 	mask = (roundup_pow_of_two(size) / SZ_128) - 1;
- 	rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
- 
--	rcar_pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win));
--	rcar_pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win));
-+	if (res->flags & IORESOURCE_IO)
-+		res_start = pci_pio_to_address(res->start);
-+	else
-+		res_start = res->start;
-+
-+	rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPARH(win));
-+	rcar_pci_write_reg(pcie, lower_32_bits(res_start), PCIEPARL(win));
- 
- 	/* First resource is for IO */
- 	mask = PAR_ENABLE;
-@@ -363,9 +369,10 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
- 
- 		rcar_pcie_setup_window(i, pcie);
- 
--		if (res->flags & IORESOURCE_IO)
--			pci_ioremap_io(nr * SZ_64K, res->start);
--		else
-+		if (res->flags & IORESOURCE_IO) {
-+			phys_addr_t io_start = pci_pio_to_address(res->start);
-+			pci_ioremap_io(nr * SZ_64K, io_start);
-+		} else
- 			pci_add_resource(&sys->resources, res);
- 	}
- 	pci_add_resource(&sys->resources, &pcie->busn);
-@@ -935,8 +942,10 @@ static int rcar_pcie_probe(struct platform_device *pdev)
- 	}
- 
- 	for_each_of_pci_range(&parser, &range) {
--		of_pci_range_to_resource(&range, pdev->dev.of_node,
-+		err = of_pci_range_to_resource(&range, pdev->dev.of_node,
- 						&pcie->res[win++]);
-+		if (err < 0)
-+			return err;
- 
- 		if (win > RCAR_PCI_MAX_RESOURCES)
- 			break;
-diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
-index 2c9ac70..6e994fc 100644
---- a/drivers/pci/pci.c
-+++ b/drivers/pci/pci.c
-@@ -2704,6 +2704,37 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name)
- }
- EXPORT_SYMBOL(pci_request_regions_exclusive);
- 
-+/**
-+ *	pci_remap_iospace - Remap the memory mapped I/O space
-+ *	@res: Resource describing the I/O space
-+ *	@phys_addr: physical address of range to be mapped
-+ *
-+ *	Remap the memory mapped I/O space described by the @res
-+ *	and the CPU physical address @phys_addr into virtual address space.
-+ *	Only architectures that have memory mapped IO functions defined
-+ *	(and the PCI_IOBASE value defined) should call this function.
-+ */
-+int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr)
++int of_dev_prop_read_array(struct device_node *dn, const char *propname,
++			   enum dev_prop_type proptype, void *val, size_t nval)
 +{
-+#if defined(PCI_IOBASE) && defined(CONFIG_MMU)
-+	unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start;
-+
-+	if (!(res->flags & IORESOURCE_IO))
-+		return -EINVAL;
-+
-+	if (res->end > IO_SPACE_LIMIT)
-+		return -EINVAL;
-+
-+	return ioremap_page_range(vaddr, vaddr + resource_size(res), phys_addr,
-+				  pgprot_device(PAGE_KERNEL));
-+#else
-+	/* this architecture does not have memory mapped I/O space,
-+	   so this function should never be called */
-+	WARN_ONCE(1, "This architecture does not support memory mapped I/O\n");
-+	return -ENODEV;
-+#endif
-+}
++	int ret, elem_size;
 +
- static void __pci_set_master(struct pci_dev *dev, bool enable)
- {
- 	u16 old_cmd, cmd;
-@@ -4406,6 +4437,15 @@ static void pci_no_domains(void)
- #endif
- }
- 
-+#ifdef CONFIG_PCI_DOMAINS
-+static atomic_t __domain_nr = ATOMIC_INIT(-1);
++	if (!val) {
++		switch (proptype) {
++		case DEV_PROP_U8:
++			elem_size = sizeof(u8);
++			break;
++		case DEV_PROP_U16:
++			elem_size = sizeof(u16);
++			break;
++		case DEV_PROP_U32:
++			elem_size = sizeof(u32);
++			break;
++		case DEV_PROP_U64:
++			elem_size = sizeof(u64);
++			break;
++		case DEV_PROP_STRING:
++			return of_property_count_strings(dn, propname);
++		default:
++			return -EINVAL;
++		}
++		return of_property_count_elems_of_size(dn, propname, elem_size);
++	}
 +
-+int pci_get_new_domain_nr(void)
-+{
-+	return atomic_inc_return(&__domain_nr);
++	switch (proptype) {
++	case DEV_PROP_U8:
++		ret = of_property_read_u8_array(dn, propname, (u8 *)val, nval);
++		break;
++	case DEV_PROP_U16:
++		ret = of_property_read_u16_array(dn, propname, (u16 *)val, nval);
++		break;
++	case DEV_PROP_U32:
++		ret = of_property_read_u32_array(dn, propname, (u32 *)val, nval);
++		break;
++	case DEV_PROP_U64:
++		ret = of_property_read_u64_array(dn, propname, (u64 *)val, nval);
++		break;
++	case DEV_PROP_STRING:
++		ret = of_property_read_string_array(dn, propname,
++						    (char **)val, nval);
++		break;
++	default:
++		ret = -EINVAL;
++		break;
++	}
++	return ret;
 +}
-+#endif
-+
- /**
-  * pci_ext_cfg_avail - can we access extended PCI config space?
-  *
-diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
-index 4170113..c3cec34 100644
---- a/drivers/pci/probe.c
-+++ b/drivers/pci/probe.c
-@@ -485,7 +485,7 @@ void pci_read_bridge_bases(struct pci_bus *child)
- 	}
- }
- 
--static struct pci_bus *pci_alloc_bus(void)
-+static struct pci_bus *pci_alloc_bus(struct pci_bus *parent)
- {
- 	struct pci_bus *b;
- 
-@@ -500,6 +500,10 @@ static struct pci_bus *pci_alloc_bus(void)
- 	INIT_LIST_HEAD(&b->resources);
- 	b->max_bus_speed = PCI_SPEED_UNKNOWN;
- 	b->cur_bus_speed = PCI_SPEED_UNKNOWN;
-+#ifdef CONFIG_PCI_DOMAINS_GENERIC
-+	if (parent)
-+		b->domain_nr = parent->domain_nr;
-+#endif
- 	return b;
- }
- 
-@@ -515,7 +519,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
- 	kfree(bridge);
- }
- 
--static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
-+static struct pci_host_bridge *pci_alloc_host_bridge(void)
- {
- 	struct pci_host_bridge *bridge;
- 
-@@ -524,7 +528,8 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
- 		return NULL;
- 
- 	INIT_LIST_HEAD(&bridge->windows);
--	bridge->bus = b;
-+	bridge->dev.release = pci_release_host_bridge_dev;
 +
- 	return bridge;
- }
- 
-@@ -671,7 +676,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
- 	/*
- 	 * Allocate a new bus, and inherit stuff from the parent..
- 	 */
--	child = pci_alloc_bus();
-+	child = pci_alloc_bus(parent);
- 	if (!child)
- 		return NULL;
- 
-@@ -1751,37 +1756,37 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
- 	char bus_addr[64];
- 	char *fmt;
- 
--	b = pci_alloc_bus();
--	if (!b)
-+	bridge = pci_alloc_host_bridge();
-+	if (!bridge)
- 		return NULL;
- 
-+	bridge->dev.parent = parent;
-+
-+	b = pci_alloc_bus(NULL);
-+	if (!b)
-+		goto err_out;
-+
- 	b->sysdata = sysdata;
- 	b->ops = ops;
- 	b->number = b->busn_res.start = bus;
-+	pci_bus_assign_domain_nr(b, parent);
- 	b2 = pci_find_bus(pci_domain_nr(b), bus);
- 	if (b2) {
- 		/* If we already got to this bus through a different bridge, ignore it */
- 		dev_dbg(&b2->dev, "bus already known\n");
--		goto err_out;
-+		goto err_bus_out;
- 	}
- 
--	bridge = pci_alloc_host_bridge(b);
--	if (!bridge)
--		goto err_out;
--
--	bridge->dev.parent = parent;
--	bridge->dev.release = pci_release_host_bridge_dev;
-+	bridge->bus = b;
- 	dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
- 	error = pcibios_root_bridge_prepare(bridge);
--	if (error) {
--		kfree(bridge);
-+	if (error)
- 		goto err_out;
--	}
- 
- 	error = device_register(&bridge->dev);
- 	if (error) {
- 		put_device(&bridge->dev);
--		goto err_out;
-+		goto err_bus_out;
- 	}
- 	b->bridge = get_device(&bridge->dev);
- 	device_enable_async_suspend(b->bridge);
-@@ -1838,8 +1843,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
- class_dev_reg_err:
- 	put_device(&bridge->dev);
- 	device_unregister(&bridge->dev);
--err_out:
-+err_bus_out:
- 	kfree(b);
-+err_out:
-+	kfree(bridge);
- 	return NULL;
- }
- 
-@@ -1936,6 +1943,9 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
- 	if (!found)
- 		pci_bus_update_busn_res_end(b, max);
- 
-+	if (!pci_has_flag(PCI_PROBE_ONLY))
-+		pci_assign_unassigned_bus_resources(b);
++int of_for_each_child_node(struct device *dev,
++			int (*fn)(struct device *dev, void *child, void *data),
++			void *data)
++{
++	struct device_node *child;
++	int ret = 0;
 +
- 	pci_bus_add_devices(b);
- 	return b;
- }
++	for_each_child_of_node(dev->of_node, child) {
++		ret = fn(dev, child, data);
++		if (ret)
++			break;
++	}
++	return ret;
++}
 diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
 index 782e822..d952462 100644
 --- a/drivers/pnp/resource.c
@@ -7133,10 +9129,10 @@ index 0000000..402f168
 +
 +MODULE_LICENSE("GPL v2");
 diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
-index 57d9df8..e075437 100644
+index beea6ca..7038a2d 100644
 --- a/drivers/tty/serial/8250/8250_dw.c
 +++ b/drivers/tty/serial/8250/8250_dw.c
-@@ -313,10 +313,18 @@ static int dw8250_probe_of(struct uart_port *p,
+@@ -310,10 +310,18 @@ static int dw8250_probe_of(struct uart_port *p,
  static int dw8250_probe_acpi(struct uart_8250_port *up,
  			     struct dw8250_data *data)
  {
@@ -7155,7 +9151,7 @@ index 57d9df8..e075437 100644
  	p->iotype = UPIO_MEM32;
  	p->serial_in = dw8250_serial_in32;
  	p->serial_out = dw8250_serial_out32;
-@@ -541,6 +549,7 @@ static const struct acpi_device_id dw8250_acpi_match[] = {
+@@ -536,6 +544,7 @@ static const struct acpi_device_id dw8250_acpi_match[] = {
  	{ "INT3435", 0 },
  	{ "80860F0A", 0 },
  	{ "8086228A", 0 },
@@ -7164,7 +9160,7 @@ index 57d9df8..e075437 100644
  };
  MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match);
 diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
-index c600ccf..10c4775 100644
+index ef9a165..9f1939c 100644
 --- a/drivers/virtio/virtio_mmio.c
 +++ b/drivers/virtio/virtio_mmio.c
 @@ -100,8 +100,7 @@
@@ -7177,7 +9173,7 @@ index c600ccf..10c4775 100644
  
  /* The alignment to use between consumer and producer parts of vring.
   * Currently hardcoded to the page size. */
-@@ -637,6 +636,14 @@ static struct of_device_id virtio_mmio_match[] = {
+@@ -634,6 +633,14 @@ static struct of_device_id virtio_mmio_match[] = {
  };
  MODULE_DEVICE_TABLE(of, virtio_mmio_match);
  
@@ -7192,7 +9188,7 @@ index c600ccf..10c4775 100644
  static struct platform_driver virtio_mmio_driver = {
  	.probe		= virtio_mmio_probe,
  	.remove		= virtio_mmio_remove,
-@@ -644,6 +651,7 @@ static struct platform_driver virtio_mmio_driver = {
+@@ -641,6 +648,7 @@ static struct platform_driver virtio_mmio_driver = {
  		.name	= "virtio-mmio",
  		.owner	= THIS_MODULE,
  		.of_match_table	= virtio_mmio_match,
@@ -7200,23 +9196,8 @@ index c600ccf..10c4775 100644
  	},
  };
  
-diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h
-index c728113..f97804b 100644
---- a/include/acpi/acnames.h
-+++ b/include/acpi/acnames.h
-@@ -59,6 +59,10 @@
- #define METHOD_NAME__PRS        "_PRS"
- #define METHOD_NAME__PRT        "_PRT"
- #define METHOD_NAME__PRW        "_PRW"
-+#define METHOD_NAME__PS0        "_PS0"
-+#define METHOD_NAME__PS1        "_PS1"
-+#define METHOD_NAME__PS2        "_PS2"
-+#define METHOD_NAME__PS3        "_PS3"
- #define METHOD_NAME__REG        "_REG"
- #define METHOD_NAME__SB_        "_SB_"
- #define METHOD_NAME__SEG        "_SEG"
 diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
-index 57ee052..a483e61 100644
+index 57ee052..a1ef42f 100644
 --- a/include/acpi/acpi_bus.h
 +++ b/include/acpi/acpi_bus.h
 @@ -68,6 +68,8 @@ bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs);
@@ -7228,6 +9209,28 @@ index 57ee052..a483e61 100644
  static inline union acpi_object *
  acpi_evaluate_dsm_typed(acpi_handle handle, const u8 *uuid, int rev, int func,
  			union acpi_object *argv4, acpi_object_type type)
+@@ -337,6 +339,13 @@ struct acpi_device_physical_node {
+ 	bool put_online:1;
+ };
+ 
++/* ACPI Device Specific Data (_DSD) */
++struct acpi_device_data {
++	const union acpi_object *pointer;
++	const union acpi_object *properties;
++	const union acpi_object *of_compatible;
++};
++
+ /* Device */
+ struct acpi_device {
+ 	int device_type;
+@@ -353,6 +362,7 @@ struct acpi_device {
+ 	struct acpi_device_wakeup wakeup;
+ 	struct acpi_device_perf performance;
+ 	struct acpi_device_dir dir;
++	struct acpi_device_data data;
+ 	struct acpi_scan_handler *handler;
+ 	struct acpi_hotplug_context *hp;
+ 	struct acpi_driver *driver;
 diff --git a/include/acpi/acpi_io.h b/include/acpi/acpi_io.h
 index 444671e..9d573db 100644
 --- a/include/acpi/acpi_io.h
@@ -7250,118 +9253,11 @@ index 444671e..9d573db 100644
         return ioremap_cache(phys, size);
  }
  
-diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
-index b7c89d4..dc9d037 100644
---- a/include/acpi/acpixf.h
-+++ b/include/acpi/acpixf.h
-@@ -46,7 +46,7 @@
- 
- /* Current ACPICA subsystem version in YYYYMMDD format */
- 
--#define ACPI_CA_VERSION                 0x20140724
-+#define ACPI_CA_VERSION                 0x20140828
- 
- #include <acpi/acconfig.h>
- #include <acpi/actypes.h>
-diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
-index 7626bfe..29e7937 100644
---- a/include/acpi/actbl1.h
-+++ b/include/acpi/actbl1.h
-@@ -952,7 +952,8 @@ enum acpi_srat_type {
- 	ACPI_SRAT_TYPE_CPU_AFFINITY = 0,
- 	ACPI_SRAT_TYPE_MEMORY_AFFINITY = 1,
- 	ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY = 2,
--	ACPI_SRAT_TYPE_RESERVED = 3	/* 3 and greater are reserved */
-+	ACPI_SRAT_TYPE_GICC_AFFINITY = 3,
-+	ACPI_SRAT_TYPE_RESERVED = 4	/* 4 and greater are reserved */
- };
- 
- /*
-@@ -968,7 +969,7 @@ struct acpi_srat_cpu_affinity {
- 	u32 flags;
- 	u8 local_sapic_eid;
- 	u8 proximity_domain_hi[3];
--	u32 reserved;		/* Reserved, must be zero */
-+	u32 clock_domain;
- };
- 
- /* Flags */
-@@ -1010,6 +1011,20 @@ struct acpi_srat_x2apic_cpu_affinity {
- 
- #define ACPI_SRAT_CPU_ENABLED       (1)	/* 00: Use affinity structure */
- 
-+/* 3: GICC Affinity (ACPI 5.1) */
-+
-+struct acpi_srat_gicc_affinity {
-+	struct acpi_subtable_header header;
-+	u32 proximity_domain;
-+	u32 acpi_processor_uid;
-+	u32 flags;
-+	u32 clock_domain;
-+};
-+
-+/* Flags for struct acpi_srat_gicc_affinity */
-+
-+#define ACPI_SRAT_GICC_ENABLED     (1)	/* 00: Use affinity structure */
-+
- /* Reset to default packing */
- 
- #pragma pack()
-diff --git a/include/acpi/actbl3.h b/include/acpi/actbl3.h
-index 787bcc8..5480cb2 100644
---- a/include/acpi/actbl3.h
-+++ b/include/acpi/actbl3.h
-@@ -310,10 +310,15 @@ struct acpi_gtdt_timer_entry {
- 	u32 common_flags;
- };
- 
-+/* Flag Definitions: timer_flags and virtual_timer_flags above */
-+
-+#define ACPI_GTDT_GT_IRQ_MODE               (1)
-+#define ACPI_GTDT_GT_IRQ_POLARITY           (1<<1)
-+
- /* Flag Definitions: common_flags above */
- 
--#define ACPI_GTDT_GT_IS_SECURE_TIMER    (1)
--#define ACPI_GTDT_GT_ALWAYS_ON          (1<<1)
-+#define ACPI_GTDT_GT_IS_SECURE_TIMER        (1)
-+#define ACPI_GTDT_GT_ALWAYS_ON              (1<<1)
- 
- /* 1: SBSA Generic Watchdog Structure */
- 
-diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
-index 975e1cc..2e2161b 100644
---- a/include/asm-generic/io.h
-+++ b/include/asm-generic/io.h
-@@ -331,7 +331,7 @@ static inline void iounmap(void __iomem *addr)
- #ifndef CONFIG_GENERIC_IOMAP
- static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
- {
--	return (void __iomem *) port;
-+	return (void __iomem *)(PCI_IOBASE + (port & IO_SPACE_LIMIT));
- }
- 
- static inline void ioport_unmap(void __iomem *p)
-diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
-index 53b2acc..977e545 100644
---- a/include/asm-generic/pgtable.h
-+++ b/include/asm-generic/pgtable.h
-@@ -249,6 +249,10 @@ static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
- #define pgprot_writecombine pgprot_noncached
- #endif
- 
-+#ifndef pgprot_device
-+#define pgprot_device pgprot_noncached
-+#endif
-+
- /*
-  * When walking page tables, get the address of the next boundary,
-  * or the end address of the range if that comes earlier.  Although no
 diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
-index 35b0c12..d98e96b 100644
+index 206dcc3..660dbfc 100644
 --- a/include/kvm/arm_vgic.h
 +++ b/include/kvm/arm_vgic.h
-@@ -237,17 +237,19 @@ bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,
+@@ -289,17 +289,19 @@ bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,
  #define irqchip_in_kernel(k)	(!!((k)->arch.vgic.in_kernel))
  #define vgic_initialized(k)	((k)->arch.vgic.ready)
  
@@ -7391,10 +9287,18 @@ index 35b0c12..d98e96b 100644
  	return -ENODEV;
  }
 diff --git a/include/linux/acpi.h b/include/linux/acpi.h
-index 807cbc4..4615eb1 100644
+index b7926bb..6c22abf 100644
 --- a/include/linux/acpi.h
 +++ b/include/linux/acpi.h
-@@ -71,6 +71,7 @@ enum acpi_irq_model_id {
+@@ -28,6 +28,7 @@
+ #include <linux/errno.h>
+ #include <linux/ioport.h>	/* for struct resource */
+ #include <linux/device.h>
++#include <linux/property.h>
+ 
+ #ifndef _LINUX
+ #define _LINUX
+@@ -71,6 +72,7 @@ enum acpi_irq_model_id {
  	ACPI_IRQ_MODEL_IOAPIC,
  	ACPI_IRQ_MODEL_IOSAPIC,
  	ACPI_IRQ_MODEL_PLATFORM,
@@ -7402,7 +9306,7 @@ index 807cbc4..4615eb1 100644
  	ACPI_IRQ_MODEL_COUNT
  };
  
-@@ -123,6 +124,10 @@ int acpi_numa_init (void);
+@@ -123,6 +125,10 @@ int acpi_numa_init (void);
  
  int acpi_table_init (void);
  int acpi_table_parse(char *id, acpi_tbl_table_handler handler);
@@ -7413,6 +9317,107 @@ index 807cbc4..4615eb1 100644
  int __init acpi_table_parse_entries(char *id, unsigned long table_size,
  				    int entry_id,
  				    acpi_tbl_entry_handler handler,
+@@ -423,12 +429,8 @@ extern int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
+ const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
+ 					       const struct device *dev);
+ 
+-static inline bool acpi_driver_match_device(struct device *dev,
+-					    const struct device_driver *drv)
+-{
+-	return !!acpi_match_device(drv->acpi_match_table, dev);
+-}
+-
++extern bool acpi_driver_match_device(struct device *dev,
++				     const struct device_driver *drv);
+ int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
+ int acpi_device_modalias(struct device *, char *, int);
+ 
+@@ -658,4 +660,85 @@ do {									\
+ #endif
+ #endif
+ 
++/* Device properties */
++
++#define MAX_ACPI_REFERENCE_ARGS	8
++struct acpi_reference_args {
++	struct acpi_device *adev;
++	size_t nargs;
++	u64 args[MAX_ACPI_REFERENCE_ARGS];
++};
++
++#ifdef CONFIG_ACPI
++int acpi_dev_get_property(struct acpi_device *adev, const char *name,
++			  acpi_object_type type, const union acpi_object **obj);
++int acpi_dev_get_property_array(struct acpi_device *adev, const char *name,
++				acpi_object_type type,
++				const union acpi_object **obj);
++int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name,
++				    const char *cells_name, size_t index,
++				    struct acpi_reference_args *args);
++
++int acpi_dev_prop_get(struct acpi_device *adev, const char *propname,
++		      void **valptr);
++int acpi_dev_prop_read(struct acpi_device *adev, const char *propname,
++		       enum dev_prop_type proptype, void *val);
++int acpi_dev_prop_read_array(struct acpi_device *adev, const char *propname,
++			     enum dev_prop_type proptype, void *val,
++			     size_t nval);
++int acpi_for_each_child_node(struct device *dev,
++			int (*fn)(struct device *dev, void *child, void *data),
++			void *data);
++#else
++static inline int acpi_dev_get_property(struct acpi_device *adev,
++					const char *name, acpi_object_type type,
++					const union acpi_object **obj)
++{
++	return -ENXIO;
++}
++static inline int acpi_dev_get_property_array(struct acpi_device *adev,
++					      const char *name,
++					      acpi_object_type type,
++					      const union acpi_object **obj)
++{
++	return -ENXIO;
++}
++static inline int acpi_dev_get_property_reference(struct acpi_device *adev,
++				const char *name, const char *cells_name,
++				size_t index, struct acpi_reference_args *args)
++{
++	return -ENXIO;
++}
++
++static inline int acpi_dev_prop_get(struct acpi_device *adev,
++				    const char *propname,
++				    void **valptr)
++{
++	return -ENXIO;
++}
++
++static inline int acpi_dev_prop_read(struct acpi_device *adev,
++				     const char *propname,
++				     enum dev_prop_type proptype, void *val)
++{
++	return -ENXIO;
++}
++
++static inline int acpi_dev_prop_read_array(struct acpi_device *adev,
++					   const char *propname,
++					   enum dev_prop_type proptype,
++					   void *val, size_t nval)
++{
++	return -ENXIO;
++}
++
++static inline int acpi_for_each_child_node(struct device *dev,
++			int (*fn)(struct device *dev, void *child, void *data),
++			void *data)
++{
++	return -ENXIO;
++}
++
++#endif
++
+ #endif	/*_LINUX_ACPI_H*/
 diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
 index 653f0e2..5839f98 100644
 --- a/include/linux/clocksource.h
@@ -7428,6 +9433,50 @@ index 653f0e2..5839f98 100644
 +#endif
 +
  #endif /* _LINUX_CLOCKSOURCE_H */
+diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
+index 12f146f..033d2fd 100644
+--- a/include/linux/gpio/consumer.h
++++ b/include/linux/gpio/consumer.h
+@@ -94,6 +94,11 @@ int gpiod_to_irq(const struct gpio_desc *desc);
+ struct gpio_desc *gpio_to_desc(unsigned gpio);
+ int desc_to_gpio(const struct gpio_desc *desc);
+ 
++/* Child properties interface */
++struct gpio_desc *dev_get_named_gpiod_from_child(struct device *dev, void *child,
++						 const char *propname, int index);
++struct gpio_desc *devm_get_named_gpiod_from_child(struct device *dev, void *child,
++						  const char *propname, int index);
+ #else /* CONFIG_GPIOLIB */
+ 
+ static inline struct gpio_desc *__must_check __gpiod_get(struct device *dev,
+diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h
+index 8b62246..ee2d8c6 100644
+--- a/include/linux/gpio_keys.h
++++ b/include/linux/gpio_keys.h
+@@ -2,6 +2,7 @@
+ #define _GPIO_KEYS_H
+ 
+ struct device;
++struct gpio_desc;
+ 
+ /**
+  * struct gpio_keys_button - configuration parameters
+@@ -17,6 +18,7 @@ struct device;
+  *			disable button via sysfs
+  * @value:		axis value for %EV_ABS
+  * @irq:		Irq number in case of interrupt keys
++ * @gpiod:		GPIO descriptor
+  */
+ struct gpio_keys_button {
+ 	unsigned int code;
+@@ -29,6 +31,7 @@ struct gpio_keys_button {
+ 	bool can_disable;
+ 	int value;
+ 	unsigned int irq;
++	struct gpio_desc *gpiod;
+ };
+ 
+ /**
 diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
 new file mode 100644
 index 0000000..ad5b577
@@ -7466,111 +9515,97 @@ index 0000000..ad5b577
 +
 +#endif /* ARM_GIC_ACPI_H_ */
 diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
-index 45e2d8c..2b0f246 100644
+index 13eed92..dc9cb5f 100644
 --- a/include/linux/irqchip/arm-gic.h
 +++ b/include/linux/irqchip/arm-gic.h
-@@ -39,6 +39,8 @@
- #define GIC_DIST_SGI_PENDING_CLEAR	0xf10
- #define GIC_DIST_SGI_PENDING_SET	0xf20
+@@ -55,6 +55,8 @@
+ 					(GICD_INT_DEF_PRI << 8) |\
+ 					GICD_INT_DEF_PRI)
  
 +#define GIC_DIST_SOFTINT_NSATT		0x8000
 +
  #define GICH_HCR			0x0
  #define GICH_VTR			0x4
  #define GICH_VMCR			0x8
-diff --git a/include/linux/of_address.h b/include/linux/of_address.h
-index fb7b722..7ebb877 100644
---- a/include/linux/of_address.h
-+++ b/include/linux/of_address.h
-@@ -23,17 +23,6 @@ struct of_pci_range {
- #define for_each_of_pci_range(parser, range) \
- 	for (; of_pci_range_parser_one(parser, range);)
- 
--static inline void of_pci_range_to_resource(struct of_pci_range *range,
--					    struct device_node *np,
--					    struct resource *res)
--{
--	res->flags = range->flags;
--	res->start = range->cpu_addr;
--	res->end = range->cpu_addr + range->size - 1;
--	res->parent = res->child = res->sibling = NULL;
--	res->name = np->full_name;
--}
--
- /* Translate a DMA address from device space to CPU space */
- extern u64 of_translate_dma_address(struct device_node *dev,
- 				    const __be32 *in_addr);
-@@ -55,7 +44,9 @@ extern void __iomem *of_iomap(struct device_node *device, int index);
- extern const __be32 *of_get_address(struct device_node *dev, int index,
- 			   u64 *size, unsigned int *flags);
- 
-+extern int pci_register_io_range(phys_addr_t addr, resource_size_t size);
- extern unsigned long pci_address_to_pio(phys_addr_t addr);
-+extern phys_addr_t pci_pio_to_address(unsigned long pio);
- 
- extern int of_pci_range_parser_init(struct of_pci_range_parser *parser,
- 			struct device_node *node);
-@@ -138,6 +129,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
- 			       u64 *size, unsigned int *flags);
- extern int of_pci_address_to_resource(struct device_node *dev, int bar,
- 				      struct resource *r);
-+extern int of_pci_range_to_resource(struct of_pci_range *range,
-+				    struct device_node *np,
-+				    struct resource *res);
- #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
- static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
- 				             struct resource *r)
-@@ -153,4 +147,3 @@ static inline const __be32 *of_get_pci_address(struct device_node *dev,
- #endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */
- 
- #endif /* __OF_ADDRESS_H */
--
-diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
-index dde3a4a..1fd207e 100644
---- a/include/linux/of_pci.h
-+++ b/include/linux/of_pci.h
-@@ -15,6 +15,7 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
- int of_pci_get_devfn(struct device_node *np);
- int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
- int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
-+int of_get_pci_domain_nr(struct device_node *node);
- #else
- static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
- {
-@@ -43,6 +44,18 @@ of_pci_parse_bus_range(struct device_node *node, struct resource *res)
- {
- 	return -EINVAL;
+diff --git a/include/linux/leds.h b/include/linux/leds.h
+index e436864..879a113 100644
+--- a/include/linux/leds.h
++++ b/include/linux/leds.h
+@@ -246,6 +246,7 @@ struct led_platform_data {
+ struct gpio_led {
+ 	const char *name;
+ 	const char *default_trigger;
++	struct gpio_desc *gpiod;
+ 	unsigned 	gpio;
+ 	unsigned	active_low : 1;
+ 	unsigned	retain_state_suspended : 1;
+diff --git a/include/linux/of.h b/include/linux/of.h
+index 6545e7a..9962b70 100644
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -23,6 +23,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/topology.h>
+ #include <linux/notifier.h>
++#include <linux/property.h>
+ 
+ #include <asm/byteorder.h>
+ #include <asm/errno.h>
+@@ -355,6 +356,15 @@ const char *of_prop_next_string(struct property *prop, const char *cur);
+ 
+ bool of_console_check(struct device_node *dn, char *name, int index);
+ 
++int of_dev_prop_get(struct device_node *dn, const char *propname, void **valptr);
++int of_dev_prop_read(struct device_node *dn, const char *propname,
++		     enum dev_prop_type proptype, void *val);
++int of_dev_prop_read_array(struct device_node *dn, const char *propname,
++			   enum dev_prop_type proptype, void *val, size_t nval);
++int of_for_each_child_node(struct device *dev,
++			int (*fn)(struct device *dev, void *child, void *data),
++			void *data);
++
+ #else /* CONFIG_OF */
+ 
+ static inline const char* of_node_full_name(const struct device_node *np)
+@@ -582,6 +592,33 @@ static inline const char *of_prop_next_string(struct property *prop,
+ 	return NULL;
  }
+ 
++static inline int of_dev_prop_get(struct device_node *dn, const char *propname,
++				 void **valptr)
++{
++	return -ENXIO;
++}
 +
-+static inline int
-+of_get_pci_domain_nr(struct device_node *node)
++static inline int of_dev_prop_read(struct device_node *dn, const char *propname,
++				   enum dev_prop_type proptype, void *val)
 +{
-+	return -1;
++	return -ENXIO;
 +}
-+#endif
 +
-+#if defined(CONFIG_OF_ADDRESS)
-+int of_pci_get_host_bridge_resources(struct device_node *dev,
-+			unsigned char busno, unsigned char bus_max,
-+			struct list_head *resources, resource_size_t *io_base);
- #endif
- 
- #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
++static inline int of_dev_prop_read_array(struct device_node *dn,
++					 const char *propname,
++					 enum dev_prop_type proptype,
++					 void *val, size_t nval)
++{
++	return -ENXIO;
++}
++
++static inline int of_for_each_child_node(struct device *dev,
++			int (*fn)(struct device *dev, void *child, void *data),
++			void *data)
++{
++	return -ENXIO;
++}
++
+ #define of_match_ptr(_ptr)	NULL
+ #define of_match_node(_matches, _node)	NULL
+ #endif /* CONFIG_OF */
 diff --git a/include/linux/pci.h b/include/linux/pci.h
-index 96453f9..6d540b9 100644
+index 5be8db4..6afba72 100644
 --- a/include/linux/pci.h
 +++ b/include/linux/pci.h
-@@ -457,6 +457,9 @@ struct pci_bus {
- 	unsigned char	primary;	/* number of primary bridge */
- 	unsigned char	max_bus_speed;	/* enum pci_bus_speed */
- 	unsigned char	cur_bus_speed;	/* enum pci_bus_speed */
-+#ifdef CONFIG_PCI_DOMAINS_GENERIC
-+	int		domain_nr;
-+#endif
- 
- 	char		name[48];
- 
-@@ -559,15 +562,6 @@ struct pci_ops {
+@@ -562,15 +562,6 @@ struct pci_ops {
  	int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
  };
  
@@ -7586,48 +9621,7 @@ index 96453f9..6d540b9 100644
  struct pci_bus_region {
  	dma_addr_t start;
  	dma_addr_t end;
-@@ -1103,6 +1097,9 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
- 						  resource_size_t),
- 			void *alignf_data);
- 
-+
-+int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr);
-+
- static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar)
- {
- 	struct pci_bus_region region;
-@@ -1288,17 +1285,47 @@ void pci_cfg_access_unlock(struct pci_dev *dev);
-  */
- #ifdef CONFIG_PCI_DOMAINS
- extern int pci_domains_supported;
-+int pci_get_new_domain_nr(void);
- #else
- enum { pci_domains_supported = 0 };
- static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
- static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }
-+static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
- #endif /* CONFIG_PCI_DOMAINS */
- 
-+/*
-+ * Generic implementation for PCI domain support. If your
-+ * architecture does not need custom management of PCI
-+ * domains then this implementation will be used
-+ */
-+#ifdef CONFIG_PCI_DOMAINS_GENERIC
-+static inline int pci_domain_nr(struct pci_bus *bus)
-+{
-+	return bus->domain_nr;
-+}
-+void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent);
-+#else
-+static inline void pci_bus_assign_domain_nr(struct pci_bus *bus,
-+					struct device *parent)
-+{
-+}
-+#endif
-+
- /* some architectures require additional setup to direct VGA traffic */
- typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode,
+@@ -1325,6 +1316,16 @@ typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode,
  		      unsigned int command_bits, u32 flags);
  void pci_register_set_vga_state(arch_set_vga_state_t func);
  
@@ -7644,7 +9638,7 @@ index 96453f9..6d540b9 100644
  #else /* CONFIG_PCI is not enabled */
  
  /*
-@@ -1400,8 +1427,26 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
+@@ -1426,6 +1427,23 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
  						unsigned int devfn)
  { return NULL; }
  
@@ -7667,11 +9661,8 @@ index 96453f9..6d540b9 100644
 +
  static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
  static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; }
-+static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
- 
- #define dev_is_pci(d) (false)
- #define dev_is_pf(d) (false)
-@@ -1613,7 +1658,6 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev,
+ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
+@@ -1635,7 +1653,6 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev,
  				 enum pcie_reset_state state);
  int pcibios_add_device(struct pci_dev *dev);
  void pcibios_release_device(struct pci_dev *dev);
@@ -7679,19 +9670,219 @@ index 96453f9..6d540b9 100644
  
  #ifdef CONFIG_HIBERNATE_CALLBACKS
  extern struct dev_pm_ops pcibios_pm_ops;
-diff --git a/tools/perf/arch/arm64/include/perf_regs.h b/tools/perf/arch/arm64/include/perf_regs.h
-index e9441b9..1d3f39c 100644
---- a/tools/perf/arch/arm64/include/perf_regs.h
-+++ b/tools/perf/arch/arm64/include/perf_regs.h
-@@ -6,6 +6,8 @@
- #include <asm/perf_regs.h>
- 
- #define PERF_REGS_MASK	((1ULL << PERF_REG_ARM64_MAX) - 1)
-+#define PERF_REGS_MAX	PERF_REG_ARM64_MAX
+diff --git a/include/linux/property.h b/include/linux/property.h
+new file mode 100644
+index 0000000..1a42878
+--- /dev/null
++++ b/include/linux/property.h
+@@ -0,0 +1,207 @@
++/*
++ * property.h - Unified device property interface.
++ *
++ * Copyright (C) 2014, Intel Corporation
++ * Authors: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
++ *          Mika Westerberg <mika.westerberg at linux.intel.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
 +
- #define PERF_REG_IP	PERF_REG_ARM64_PC
- #define PERF_REG_SP	PERF_REG_ARM64_SP
- 
++#ifndef _LINUX_PROPERTY_H_
++#define _LINUX_PROPERTY_H_
++
++#include <linux/device.h>
++
++enum dev_prop_type {
++	DEV_PROP_U8,
++	DEV_PROP_U16,
++	DEV_PROP_U32,
++	DEV_PROP_U64,
++	DEV_PROP_STRING,
++	DEV_PROP_MAX,
++};
++
++int device_get_property(struct device *dev, const char *propname,
++			void **valptr);
++int device_read_property(struct device *dev, const char *propname,
++			 enum dev_prop_type proptype, void *val);
++int device_read_property_array(struct device *dev, const char *propname,
++			       enum dev_prop_type proptype, void *val,
++			       size_t nval);
++int device_get_child_property(struct device *dev, void *child,
++			      const char *propname, void **valptr);
++int device_read_child_property(struct device *dev, void *child,
++			       const char *propname,
++			       enum dev_prop_type proptype, void *val);
++int device_read_child_property_array(struct device *dev, void *child,
++				     const char *propname,
++				     enum dev_prop_type proptype, void *val,
++				     size_t nval);
++int device_for_each_child_node(struct device *dev,
++			int (*fn)(struct device *dev, void *child, void *data),
++			void *data);
++unsigned int device_get_child_node_count(struct device *dev);
++
++static inline int device_property_read_u8(struct device *dev,
++					  const char *propname, u8 *out_value)
++{
++	return device_read_property(dev, propname, DEV_PROP_U8, out_value);
++}
++
++static inline int device_property_read_u16(struct device *dev,
++					  const char *propname, u16 *out_value)
++{
++	return device_read_property(dev, propname, DEV_PROP_U16, out_value);
++}
++
++static inline int device_property_read_u32(struct device *dev,
++					  const char *propname, u32 *out_value)
++{
++	return device_read_property(dev, propname, DEV_PROP_U32, out_value);
++}
++
++static inline int device_property_read_u64(struct device *dev,
++					  const char *propname, u64 *out_value)
++{
++	return device_read_property(dev, propname, DEV_PROP_U64, out_value);
++}
++
++static inline int device_property_read_u8_array(struct device *dev,
++						const char *propname,
++						u8 *val, size_t nval)
++{
++	return device_read_property_array(dev, propname, DEV_PROP_U8, val,
++					  nval);
++}
++
++static inline int device_property_read_u16_array(struct device *dev,
++						 const char *propname,
++						 u16 *val, size_t nval)
++{
++	return device_read_property_array(dev, propname, DEV_PROP_U16, val,
++					  nval);
++}
++
++static inline int device_property_read_u32_array(struct device *dev,
++						 const char *propname,
++						 u32 *val, size_t nval)
++{
++	return device_read_property_array(dev, propname, DEV_PROP_U32, val,
++					  nval);
++}
++
++static inline int device_property_read_u64_array(struct device *dev,
++						 const char *propname,
++						 u64 *val, size_t nval)
++{
++	return device_read_property_array(dev, propname, DEV_PROP_U64, val,
++					  nval);
++}
++
++static inline int device_property_read_string(struct device *dev,
++					      const char *propname,
++					      const char **out_string)
++{
++	return device_read_property(dev, propname, DEV_PROP_STRING, out_string);
++}
++
++static inline int device_property_read_string_array(struct device *dev,
++						    const char *propname,
++						    const char **out_strings,
++						    size_t nstrings)
++{
++	return device_read_property_array(dev, propname, DEV_PROP_STRING,
++					  out_strings, nstrings);
++}
++
++static inline int device_child_property_read_u8(struct device *dev, void *child,
++						const char *propname,
++						u8 *out_value)
++{
++	return device_read_child_property(dev, child, propname, DEV_PROP_U8,
++					  out_value);
++}
++
++static inline int device_child_property_read_u16(struct device *dev, void *child,
++						 const char *propname,
++						 u16 *out_value)
++{
++	return device_read_child_property(dev, child, propname, DEV_PROP_U16,
++					  out_value);
++}
++
++static inline int device_child_property_read_u32(struct device *dev, void *child,
++						 const char *propname,
++						 u32 *out_value)
++{
++	return device_read_child_property(dev, child, propname, DEV_PROP_U32,
++					  out_value);
++}
++
++static inline int device_child_property_read_u64(struct device *dev, void *child,
++						 const char *propname,
++						 u64 *out_value)
++{
++	return device_read_child_property(dev, child, propname, DEV_PROP_U64,
++					  out_value);
++}
++
++static inline int device_child_property_read_u8_array(struct device *dev,
++						      void *child,
++						      const char *propname,
++						      u8 *val, size_t nval)
++{
++	return device_read_child_property_array(dev, child, propname,
++						DEV_PROP_U8, val, nval);
++}
++
++static inline int device_child_property_read_u16_array(struct device *dev,
++						       void *child,
++						       const char *propname,
++						       u16 *val, size_t nval)
++{
++	return device_read_child_property_array(dev, child, propname,
++						DEV_PROP_U16, val, nval);
++}
++
++static inline int device_child_property_read_u32_array(struct device *dev,
++						       void *child,
++						       const char *propname,
++						       u32 *val, size_t nval)
++{
++	return device_read_child_property_array(dev, child, propname,
++						DEV_PROP_U32, val, nval);
++}
++
++static inline int device_child_property_read_u64_array(struct device *dev,
++						       void *child,
++						       const char *propname,
++						       u64 *val, size_t nval)
++{
++	return device_read_child_property_array(dev, child, propname,
++						DEV_PROP_U64, val, nval);
++}
++
++static inline int device_child_property_read_string(struct device *dev,
++						    void *child,
++						    const char *propname,
++						    const char **out_string)
++{
++	return device_read_child_property(dev, child, propname, DEV_PROP_STRING,
++					  out_string);
++}
++
++static inline int device_child_property_read_string_array(struct device *dev,
++						void *child,
++						const char *propname,
++						const char **out_strings,
++						size_t nstrings)
++{
++	return device_read_child_property_array(dev, child, propname,
++						DEV_PROP_STRING,
++						out_strings, nstrings);
++}
++#endif /* _LINUX_PROPERTY_H_ */
 diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
 index 22fa819..9cd5dbd 100644
 --- a/virt/kvm/arm/arch_timer.c
@@ -7839,7 +10030,7 @@ index 22fa819..9cd5dbd 100644
  
  void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu)
 diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
-index 416baed..53bdd33 100644
+index 2935405..196f49e 100644
 --- a/virt/kvm/arm/vgic-v2.c
 +++ b/virt/kvm/arm/vgic-v2.c
 @@ -19,6 +19,7 @@
@@ -7858,7 +10049,7 @@ index 416baed..53bdd33 100644
  #include <asm/kvm_emulate.h>
  #include <asm/kvm_arm.h>
  #include <asm/kvm_mmu.h>
-@@ -177,7 +179,7 @@ static const struct vgic_ops vgic_v2_ops = {
+@@ -159,7 +161,7 @@ static const struct vgic_ops vgic_v2_ops = {
  static struct vgic_params vgic_v2_params;
  
  /**
@@ -7867,7 +10058,7 @@ index 416baed..53bdd33 100644
   * @node:	pointer to the DT node
   * @ops: 	address of a pointer to the GICv2 operations
   * @params:	address of a pointer to HW-specific parameters
-@@ -186,7 +188,7 @@ static struct vgic_params vgic_v2_params;
+@@ -168,7 +170,7 @@ static struct vgic_params vgic_v2_params;
   * in *ops and the HW parameters in *params. Returns an error code
   * otherwise.
   */
@@ -7876,7 +10067,7 @@ index 416baed..53bdd33 100644
  		  const struct vgic_ops **ops,
  		  const struct vgic_params **params)
  {
-@@ -263,3 +265,72 @@ out:
+@@ -245,3 +247,72 @@ out:
  	of_node_put(vgic_node);
  	return ret;
  }
@@ -7976,7 +10167,7 @@ index 1c2c8ee..8b56920 100644
  	int ret = 0;
  	u32 gicv_idx;
 diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
-index 73eba79..ca98a3b 100644
+index 3aaca49..f6e9922 100644
 --- a/virt/kvm/arm/vgic.c
 +++ b/virt/kvm/arm/vgic.c
 @@ -25,9 +25,11 @@
@@ -7991,7 +10182,7 @@ index 73eba79..ca98a3b 100644
  #include <asm/kvm_emulate.h>
  #include <asm/kvm_arm.h>
  #include <asm/kvm_mmu.h>
-@@ -1549,31 +1551,39 @@ static struct notifier_block vgic_cpu_nb = {
+@@ -2427,31 +2429,39 @@ static struct notifier_block vgic_cpu_nb = {
  };
  
  static const struct of_device_id vgic_ids[] = {
@@ -8007,8 +10198,8 @@ index 73eba79..ca98a3b 100644
  int kvm_vgic_hyp_init(void)
  {
  	const struct of_device_id *matched_id;
- 	int (*vgic_probe)(struct device_node *,const struct vgic_ops **,
- 			  const struct vgic_params **);
+ 	const int (*vgic_probe)(struct device_node *,const struct vgic_ops **,
+ 				const struct vgic_params **);
  	struct device_node *vgic_node;
 -	int ret;
 +	int ret = -ENODEV;
diff --git a/kernel.spec b/kernel.spec
index 3b40237..d25ed4a 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -8,7 +8,7 @@ Summary: The Linux kernel
 # be 0.
 %global released_kernel 0
 
-%global aarch64patches 0
+%global aarch64patches 1
 
 # Sign modules on x86.  Make sure the config files match this setting if more
 # architectures are added.
@@ -42,7 +42,7 @@ Summary: The Linux kernel
 # For non-released -rc kernels, this will be appended after the rcX and
 # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
 #
-%global baserelease 1
+%global baserelease 2
 %global fedora_build %{baserelease}
 
 # base_sublevel is the kernel version we're starting with and patching
@@ -2208,6 +2208,13 @@ fi
 #                                    ||----w |
 #                                    ||     ||
 %changelog
+* Tue Oct 21 2014 Kyle McMartin <kyle at fedoraproject.org> - 3.18.0-0.rc1.git1.2
+- Re-enable kernel-arm64.patch after updating.
+- CONFIG_SERIAL_8250_FINTEK moved to generic since it appears on x86-generic
+  and arm64 now.
+- CONFIG_IMX_THERMAL=n added to config-arm64.
+- arm64: disable BPF_JIT temporarily
+
 * Tue Oct 21 2014 Josh Boyer <jwboyer at fedoraproject.org> - 3.18.0-0.rc1.git1.1
 - Linux v3.18-rc1-68-gc2661b806092
 - Make LOG_BUF_SHIFT on arm64 the same as the rest of the arches (rhbz 1123327)


More information about the scm-commits mailing list