summaryrefslogtreecommitdiffstats
path: root/kernel-arm64.patch
diff options
context:
space:
mode:
authorKyle McMartin <kmcmarti@redhat.com>2014-11-11 09:38:12 -0500
committerKyle McMartin <kmcmarti@redhat.com>2014-11-11 09:38:12 -0500
commit81c4dc55f83517f99282c822fa0def3e308414b5 (patch)
tree2adfbd158485261e11d3fe42f1517d7d3b5a5790 /kernel-arm64.patch
parent09115662e15ee83248e62465fead50be5ed85f79 (diff)
downloadkernel-81c4dc55f83517f99282c822fa0def3e308414b5.tar.gz
kernel-81c4dc55f83517f99282c822fa0def3e308414b5.tar.xz
kernel-81c4dc55f83517f99282c822fa0def3e308414b5.zip
Re-enable kernel-arm64.patch, and fix up merge conflicts with 3.18-rc4
Diffstat (limited to 'kernel-arm64.patch')
-rw-r--r--kernel-arm64.patch6556
1 files changed, 4796 insertions, 1760 deletions
diff --git a/kernel-arm64.patch b/kernel-arm64.patch
index 3e32005cb..f5b14ec4f 100644
--- a/kernel-arm64.patch
+++ b/kernel-arm64.patch
@@ -1,8 +1,123 @@
-commit 798bcf9c5057f0acd54154d09abf6fc4fc044e41
+commit ccdf75caa6a1165b8199930983596ef64cf09bd3
Author: Mark Salter <msalter@redhat.com>
-Date: Tue Oct 14 13:51:54 2014 -0400
+Date: Mon Nov 10 17:09:29 2014 -0500
- arm64: [NOT FOR UPSTREAM] fix dma_ops for ACPI and PCI devices
+ DO NOT UPSTREAM - pci/xgene: Provide fixup for ACPI MCFG support
+
+ Xgene doesn't decode bus bits of mmconfig region and only
+ supports devfn 0 of bus 0. For other buses/devices, some
+ internal registers need to be poked. This patch provides
+ a fixup to support ACPI MCFG tables. This is a horrible
+ hack allowing the hardware to be used for PCI testing, but
+ it is not intended to be a long term patch.
+
+ Signed-off-by: Mark Salter <msalter@redhat.com>
+
+commit 4421965a8ea7caae3f50760abce1094e0186c05e
+Author: Mark Salter <msalter@redhat.com>
+Date: Mon Nov 10 17:33:18 2014 -0500
+
+ DO NOT UPSTREAM - provide hook for MCFG fixups
+
+ This is a temprary mechanism needed by at least one early
+ arm64 hardware platform with broken MCFG support. This is
+ not intended for upstream and will go away as soon as newer
+ hardware with fully compliant ECAM becomes available.
+
+ Signed-off-by: Mark Salter <msalter@redhat.com>
+
+commit dcaeb407c91845739a64fb719a8c8d34474371e8
+Author: Mark Salter <msalter@redhat.com>
+Date: Mon Nov 10 17:30:25 2014 -0500
+
+ arm64/pci/acpi: initial support for ACPI probing of PCI
+
+ Signed-off-by: Mark Salter <msalter@redhat.com>
+
+commit 68c8ee5c1ab7b899401750cc359912efbeb40676
+Author: Mark Salter <msalter@redhat.com>
+Date: Mon Nov 10 17:23:57 2014 -0500
+
+ arm64/acpi/pci: add support for parsing MCFG table
+
+ Add support for parsing MCFG table and provide functions to read/write
+ PCI configuration space based on the parsed info. This provides the
+ low-level raw_pci_read/raw_pci_write functionality.
+
+ Signed-off-by: Mark Salter <msalter@redhat.com>
+
+commit fada05b28e93c24e8932539d94a679ce55ff332f
+Author: Mark Salter <msalter@redhat.com>
+Date: Mon Nov 10 16:42:14 2014 -0500
+
+ DO NOT UPSTREAM - pci/xgene: workaround CRS issue
+
+ CRS is not behaving properly for some reason. Until this
+ gets diagnosed properly, pretend not to support it in order
+ to prevent hangs in 3.18 kernel.
+
+ Signed-off-by: Mark Salter <msalter@redhat.com>
+
+commit e917d30f3febf6d88cc5001ad236ca367a211cef
+Author: Duc Dang <dhdang@apm.com>
+Date: Thu Nov 6 17:14:18 2014 -0800
+
+ PCI: X-Gene: assign resource to bus before adding new devices
+
+ X-Gene PCIE driver currently depends on Liviu Dudau's patch
+ https://lkml.org/lkml/2014/9/30/166 in order to assign resource
+ to root bus and endpoint devices. The patch was dropped because
+ it will break x86, powerpc and probably others. So X-Gene PCIE
+ host functionality is currently broken.
+
+ This patch adds function calls to create and scan root_bus as well
+ as assign unassigned bus resource (similar to Liviu Dudau's patch
+ above). This will help resolve the dependency to Liviu Dudau's patch
+ and make X-Gene PCIE work in latest open-source kernel.
+
+ Signed-off-by: Duc Dang <dhdang@apm.com>
+ Signed-off-by: Tanmay Inamdar <tinamdar@apm.com>
+
+commit 6581c0591cafe4fa3b0bd9a25a84a5bf830209fd
+Author: Mark Salter <msalter@redhat.com>
+Date: Mon Nov 10 16:31:05 2014 -0500
+
+ iommu/arm-smmu: fix NULL dereference with ACPI PCI devices
+
+ Fix a NULL dereference in find_mmu_master which occurs when
+ booting with ACPI. In that case, PCI bridges with not have
+ an of_node. Add a check for NULL of_node and bail out if that
+ is the case.
+
+ Signed-off-by: Mark Salter <msalter@redhat.com>
+
+commit ae7850d2b972ee1258878ccc16824aba9d35b653
+Author: Guenter Roeck <linux@roeck-us.net>
+Date: Sun Nov 2 18:19:15 2014 -0800
+
+ netfilter: nft_reject_bridge: Fix powerpc build error
+
+ Fix:
+ net/bridge/netfilter/nft_reject_bridge.c:
+ In function 'nft_reject_br_send_v6_unreach':
+ net/bridge/netfilter/nft_reject_bridge.c:240:3:
+ error: implicit declaration of function 'csum_ipv6_magic'
+ csum_ipv6_magic(&nip6h->saddr, &nip6h->daddr,
+ ^
+ make[3]: *** [net/bridge/netfilter/nft_reject_bridge.o] Error 1
+
+ Seen with powerpc:allmodconfig.
+
+ Fixes: 523b929d5446 ("netfilter: nft_reject_bridge: don't use IP stack to reject traffic")
+ Cc: Pablo Neira Ayuso <pablo@netfilter.org>
+ Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit e2992498e4b2aad3ceac52bfb6faccfd18332236
+Author: Mark Salter <msalter@redhat.com>
+Date: Mon Nov 10 21:35:11 2014 -0500
+
+ DO NOT UPSTREAM - arm64: fix dma_ops for ACPI and PCI devices
Commit 2189064795dc3fb4101e5:
@@ -14,7 +129,7 @@ Date: Tue Oct 14 13:51:54 2014 -0400
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit 4b7a879d4fe95e935a06bd5209026a2278251ce6
+commit ceb5533cf5a6b68b68dc4b8ad61f5671576bdaf2
Author: Mark Salter <msalter@redhat.com>
Date: Thu Aug 14 12:32:13 2014 -0400
@@ -33,7 +148,7 @@ Date: Thu Aug 14 12:32:13 2014 -0400
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit 0e83bbc67aa2ced7b0f62bc9cdbf8026f3a83ea7
+commit 21fef5d50bb3d4465c6b644bc451c1d219967a81
Author: Wei Huang <wei@redhat.com>
Date: Thu Sep 18 20:02:57 2014 -0400
@@ -50,7 +165,7 @@ Date: Thu Sep 18 20:02:57 2014 -0400
Signed-off-by: Wei Huang <wei@redhat.com>
-commit b01e346d3156935d05aada065b69dbd4e8e3c38e
+commit 3357db72822a2c9bc012528c6be3cf861fb3f35c
Author: Wei Huang <wei@redhat.com>
Date: Thu Sep 18 20:02:56 2014 -0400
@@ -63,7 +178,7 @@ Date: Thu Sep 18 20:02:56 2014 -0400
Signed-off-by: Wei Huang <wei@redhat.com>
-commit 1f7fbdb23b3f616344bc6ab42d133528508b4183
+commit dc62803a26a34bb3190c9c1b5e3639ca6ebbf788
Author: Wei Huang <wei@redhat.com>
Date: Thu Sep 18 20:02:55 2014 -0400
@@ -80,15 +195,7 @@ Date: Thu Sep 18 20:02:55 2014 -0400
Signed-off-by: Wei Huang <wei@redhat.com>
-commit f1e1479c450a58b7fc68fec33c39b050dcc4b13d
-Author: Al Stone <ahs3@redhat.com>
-Date: Thu Sep 18 15:46:38 2014 -0600
-
- DO NOT UPSTREAM -- patch to work around bad MAC of 0x0
-
- Signed-off-by: Al Stone <ahs3@redhat.com>
-
-commit b97981d8eaeef88d34b68d6bf6fae3088fce76f6
+commit 18099d49d96bfac5096b8ad1d3d5c6d14f92e0a1
Author: Tom Lendacky <thomas.lendacky@amd.com>
Date: Mon Sep 15 17:02:52 2014 -0600
@@ -99,106 +206,289 @@ Date: Mon Sep 15 17:02:52 2014 -0600
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
-commit dd2c9edb72ff2e36152bae3bdf4f849b155c6178
+commit 7f208a9dffd58379f2e42e226052386e93d4b2dd
Author: Mark Salter <msalter@redhat.com>
Date: Tue Oct 7 12:54:08 2014 -0400
xgene acpi network - first cut
-commit 34f6f9c9a449fce5038a79ef74d85c0cd8aa983d
-Author: Mika Westerberg <mika.westerberg@linux.intel.com>
-Date: Wed Oct 1 04:22:27 2014 +0200
+commit e3ce87d3414a845f8cbf71f0d80f3f3136995ce6
+Author: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Thu Nov 6 12:23:23 2014 +0100
- misc: at25: Add ACPI probing support
+ leds: leds-gpio: Fix legacy GPIO number case
- Add support for matching using DT compatible string from ACPI _DSD.
+ In the legacy case, led_dat->gpiod is initialized correctly, but
+ overwritten later by template->gpiod, which is NULL, causing leds-gpio
+ to fail with:
- Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+ gpiod_direction_output: invalid GPIO
+ leds-gpio: probe of leds-gpio failed with error -22
+
+ Move the initialization of led_dat->gpiod from template->gpiod up, and
+ always use led_dat->gpiod later, to fix this.
+
+ Fixes: 5c51277a9ababfa4 (leds: leds-gpio: Add support for GPIO descriptors)
+ Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+ Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-commit a17b2b5016d76e752f706b5f6b04ffae8ec1728e
+commit f22bf3eef963c9fc4e58e9e96dc7e9d243042b5a
+Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Date: Wed Nov 5 00:29:07 2014 +0100
+
+ ACPI / property: Drop size_prop from acpi_dev_get_property_reference()
+
+ The size_prop argument of the recently added function
+ acpi_dev_get_property_reference() is not used by the only current
+ caller of that function and is very unlikely to be used at any time
+ going forward.
+
+ Namely, for a property whose value is a list of items each containing
+ a references to a device object possibly accompanied by some integers,
+ the number of items in the list can always be computed as the number
+ of elements of type ACPI_TYPE_LOCAL_REFERENCE in the property package.
+ Thus it should never be necessary to provide an additional "cells"
+ property with a value equal to the number of items in that list. It
+ also should never be necessary to provide a "cells" property specifying
+ how many integers are supposed to be following each reference.
+
+ For this reason, drop the size_prop argument from
+ acpi_dev_get_property_reference() and update its caller accordingly.
+
+ Link: http://marc.info/?l=linux-kernel&m=141511255610556&w=2
+ Suggested-by: Grant Likely <grant.likely@linaro.org>
+ Acked-by: Grant Likely <grant.likely@linaro.org>
+ Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+ Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+commit 1bb8c08673f0ca7951c0583665d2496e19368a56
Author: Mika Westerberg <mika.westerberg@linux.intel.com>
-Date: Wed Oct 1 04:21:18 2014 +0200
+Date: Fri Oct 31 13:40:58 2014 +0200
- misc: at25: Make use of device property API
+ leds: leds-gpio: Convert gpio_blink_set() to use GPIO descriptors
- Make use of device property API in this driver so that both DT and ACPI
- based systems can use this driver.
+ Commit 21f2aae91e902aad ("leds: leds-gpio: Add support for GPIO
+ descriptors") already converted most of the driver to use GPIO descriptors.
+ What is still missing is the platform specific hook gpio_blink_set() and
+ board files which pass legacy GPIO numbers to this driver in platform data.
+ In this patch we handle the former and convert gpio_blink_set() to take
+ GPIO descriptor instead. In order to do this we convert the existing four
+ users to accept GPIO descriptor and translate it to legacy GPIO number in
+ the platform code. This effectively "pushes" legacy GPIO number usage from
+ the driver to platforms.
+
+ Also add comment to the remaining block describing that it is legacy code
+ path and we are getting rid of it eventually.
+
+ Suggested-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+ Acked-by: Andrew Lunn <andrew@lunn.ch>
+ Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+ Acked-by: Alexandre Courbot <acourbot@nvidia.com>
+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+commit 1b8f83503e4b9b7168c5d81cabce5b66e4063607
+Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Date: Mon Nov 3 23:39:57 2014 +0100
+
+ ACPI / GPIO: Document ACPI GPIO mappings API
+
+ Document the previously introduced method that can be used by device
+ drivers to provide the GPIO subsystem with mappings between GPIO names
+ (connection IDs) and GpioIo()/GpioInt() resources in _CRS.
+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+ Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-commit 66442ae93d72f35bf046a6001403fdb89fbcfbdf
+commit 49b5f3126e722dd0266d22a2866bb056ede2cf0a
Author: Mika Westerberg <mika.westerberg@linux.intel.com>
-Date: Wed Oct 1 04:20:43 2014 +0200
+Date: Mon Oct 27 12:15:14 2014 +0200
- input: gpio_keys_polled - Add ACPI probing support
+ net: rfkill: gpio: Add default GPIO driver mappings for ACPI
- Allow the driver to probe from ACPI namespace.
+ The driver uses devm_gpiod_get_index(..., index) so that the index refers
+ directly to the GpioIo resource under the ACPI device. The problem with
+ this is that if the ordering changes we get wrong GPIOs.
+
+ With ACPI 5.1 _DSD we can now use names instead to reference GPIOs
+ analogous to Device Tree. However, we still have systems out there that do
+ not provide _DSD at all. These systems must be supported as well.
+
+ Luckily we now have acpi_dev_add_driver_gpios() that can be used to provide
+ mappings for systems where _DSD is not provided and still take advantage of
+ _DSD if it exists.
+
+ This patch changes the driver to create default GPIO mappings if we are
+ running on ACPI system.
+
+ While there we can drop the indices completely and use devm_gpiod_get()
+ with name instead.
- Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+ Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
+ Acked-by: John W. Linville <linville@tuxdriver.com>
+ Acked-by: Linus Walleij <linus.walleij@linaro.org>
+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+commit c9accb22ace8c3318e75fc0bbbca91336dab270d
+Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Date: Mon Nov 3 23:39:41 2014 +0100
+
+ ACPI / GPIO: Driver GPIO mappings for ACPI GPIOs
+
+ Provide a way for device drivers using GPIOs described by ACPI
+ GpioIo resources in _CRS to tell the GPIO subsystem what names
+ (connection IDs) to associate with specific GPIO pins defined
+ in there.
+
+ To do that, a driver needs to define a mapping table as a
+ NULL-terminated array of struct acpi_gpio_mapping objects
+ that each contain a name, a pointer to an array of line data
+ (struct acpi_gpio_params) objects and the size of that array.
+
+ Each struct acpi_gpio_params object consists of three fields,
+ crs_entry_index, line_index, active_low, representing the index of
+ the target GpioIo()/GpioInt() resource in _CRS starting from zero,
+ the index of the target line in that resource starting from zero,
+ and the active-low flag for that line, respectively.
+
+ Next, the mapping table needs to be passed as the second
+ argument to acpi_dev_add_driver_gpios() that will register it with
+ the ACPI device object pointed to by its first argument. That
+ should be done in the driver's .probe() routine.
+
+ On removal, the driver should unregister its GPIO mapping table
+ by calling acpi_dev_remove_driver_gpios() on the ACPI device
+ object where that table was previously registered.
+
+ Included are fixes from Mika Westerberg.
+
+ Acked-by: Alexandre Courbot <acourbot@nvidia.com>
+ Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-commit 7f06c354929e2325f200de26e47189a13100647e
+commit 872e3713eb734e43d3001a6ef957cb67ba2349a3
Author: Aaron Lu <aaron.lu@intel.com>
-Date: Wed Oct 1 04:20:05 2014 +0200
+Date: Tue Oct 21 13:34:00 2014 +0200
- input: gpio_keys_polled - Make use of device property API
+ 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@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+ Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+ Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-commit 1fb6d8d9606826cf1dfdac8a75bc5e3f68e4d0de
-Author: Aaron Lu <aaron.lu@intel.com>
-Date: Wed Oct 1 04:17:46 2014 +0200
+commit ac8ab45966dc9e98cdb44d0ca833c25772eb4745
+Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Date: Mon Oct 27 23:30:10 2014 +0100
- input: gpio_keys_polled - Add support for GPIO descriptors
+ leds: leds-gpio: Make use of device property API
- 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.
+ Make use of device property API in this driver so that both OF and ACPI
+ based system can use the same driver.
+
+ This change contains material from Max Eliaser and Mika Westerberg.
- Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
- Acked-by: Alexandre Courbot <acourbot@nvidia.com>
- Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+ Acked-by: Bryan Wu <cooloney@gmail.com>
+ Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-commit 8cd8efd79a3f822db3ffc2f30f7646584b69d99f
-Author: Max Eliaser <max@meliaserlow.dyndns.tv>
-Date: Wed Oct 1 04:17:02 2014 +0200
+commit d48dca7d09f36535c2f6dba340e796b54aa6667d
+Author: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Tue Oct 21 13:33:59 2014 +0200
- leds: leds-gpio: Add ACPI probing support
+ 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.
- This allows the driver to probe from ACPI namespace.
+ 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: Max Eliaser <max.eliaser@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
- Acked-by: Bryan Wu <cooloney@gmail.com>
+ Acked-by: Alexandre Courbot <acourbot@nvidia.com>
+ Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-commit 14144259abecb65edd35b9d5e717688800628e27
-Author: Max Eliaser <max@meliaserlow.dyndns.tv>
-Date: Wed Oct 1 04:16:25 2014 +0200
+commit fcca136c38aa18deec3ddd3b872ea49e6d082e5a
+Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Date: Tue Nov 4 14:03:59 2014 +0100
- leds: leds-gpio: Make use of device property API
+ Driver core: Unified interface for firmware node properties
+
+ Add new generic routines are provided for retrieving properties from
+ device description objects in the platform firmware in case there are
+ no struct device objects for them (either those objects have not been
+ created yet or they do not exist at all).
+
+ The following functions are provided:
+
+ fwnode_property_present()
+ fwnode_property_read_u8()
+ fwnode_property_read_u16()
+ fwnode_property_read_u32()
+ fwnode_property_read_u64()
+ fwnode_property_read_string()
+ fwnode_property_read_u8_array()
+ fwnode_property_read_u16_array()
+ fwnode_property_read_u32_array()
+ fwnode_property_read_u64_array()
+ fwnode_property_read_string_array()
+
+ in analogy with the corresponding functions for struct device added
+ previously. For all of them, the first argument is a pointer to struct
+ fwnode_handle (new type) that allows a device description object
+ (depending on what platform firmware interface is in use) to be
+ obtained.
+
+ Add a new macro device_for_each_child_node() for iterating over the
+ children of the device description object associated with a given
+ device and a new function device_get_child_node_count() returning the
+ number of a given device's child nodes.
- Make use of device property API in this driver so that both OF and ACPI
- based system can use the same driver.
+ The interface covers both ACPI and Device Trees.
- Signed-off-by: Max Eliaser <max.eliaser@intel.com>
+ Suggested-by: Grant Likely <grant.likely@linaro.org>
+ Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ Acked-by: Grant Likely <grant.likely@linaro.org>
+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+commit 4ac0bb216349cce71aea75f6156d44c59fc18086
+Author: Aaron Lu <aaron.lu@intel.com>
+Date: Tue Oct 21 23:30:25 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@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+ Acked-by: Alexandre Courbot <acourbot@nvidia.com>
+ Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+ Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+ Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-commit 998f66211496063e464918fcdb4e40e99fcf2501
+commit 17907d91fb1bd542b9503cc5223a070039b8d031
Author: Mika Westerberg <mika.westerberg@linux.intel.com>
-Date: Wed Oct 1 04:15:41 2014 +0200
+Date: Mon Oct 27 23:29:32 2014 +0100
leds: leds-gpio: Add support for GPIO descriptors
@@ -210,11 +500,13 @@ Date: Wed Oct 1 04:15:41 2014 +0200
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Acked-by: Bryan Wu <cooloney@gmail.com>
+ Acked-by: Arnd Bergmann <arnd@arndb.de>
+ Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-commit ecf8d19a6019f60c567615c46bec6f4501c03c99
+commit 2781ab92fd33f2270c7b5e1628db0a180ed3ab03
Author: Mika Westerberg <mika.westerberg@linux.intel.com>
-Date: Wed Oct 1 04:15:01 2014 +0200
+Date: Tue Oct 21 13:33:56 2014 +0200
gpio: sch: Consolidate core and resume banks
@@ -228,32 +520,12 @@ Date: Wed Oct 1 04:15:01 2014 +0200
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
+ Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-commit f87218916f4a9bcd2acdf8db1a4dbf8db5592036
-Author: Mika Westerberg <mika.westerberg@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@linux.intel.com>
- Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-commit 2edae8da3e10c8b9d679637693e9d26a0cb9440f
+commit 732feab25f90c338e9ef36457a3591f322f53264
Author: Mika Westerberg <mika.westerberg@linux.intel.com>
-Date: Wed Oct 1 04:12:41 2014 +0200
+Date: Wed Oct 29 15:41:01 2014 +0100
gpio / ACPI: Add support for _DSD device properties
@@ -311,41 +583,49 @@ Date: Wed Oct 1 04:12:41 2014 +0200
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
+ Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-commit 01164a93badc2df11a1f1bfdf7d46e3253a0a6ec
+commit 6b23a29f06a006a48d7fb94eef42452552144fb9
Author: Mika Westerberg <mika.westerberg@linux.intel.com>
-Date: Wed Oct 1 04:11:20 2014 +0200
+Date: Tue Oct 21 13:33:56 2014 +0200
- ACPI: Document ACPI device specific properties
+ misc: at25: Make use of device property API
+
+ Make use of device property API in this driver so that both DT and ACPI
+ based systems can use this driver.
- This document describes the data format and interfaces of ACPI device
- specific properties.
+ In addition we hard-code the name of the chip to be "at25" for the
+ reason that there is no common mechanism to fetch name of the firmware
+ node. The only existing user (arch/arm/boot/dts/phy3250.dts) uses the
+ same name so it should continue to work.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
- Signed-off-by: Darren Hart <dvhart@linux.intel.com>
+ Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-commit 1ea48df9784142befa0cdb6cb79f7fd405a7a103
+commit c901445ec7d1f37d9fd2250dd4390f395b954ef3
Author: Mika Westerberg <mika.westerberg@linux.intel.com>
-Date: Wed Oct 1 04:10:40 2014 +0200
+Date: Tue Oct 21 13:33:56 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.
+ compatible property using driver's .of_match_table instead if the driver
+ is missing .acpi_match_table.
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@linux.intel.com>
+ Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-commit f15380516841e837f8e20ed18c0039e052bb6187
+commit 7eace032b0201dfb110586080dd0628ec48c0d5c
Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Date: Wed Oct 1 04:10:03 2014 +0200
+Date: Tue Nov 4 01:28:56 2014 +0100
Driver core: Unified device properties interface for platform firmware
@@ -355,34 +635,25 @@ Date: Wed Oct 1 04:10:03 2014 +0200
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 following general helper functions are added:
+
+ device_property_present()
+ device_property_read_u8()
+ device_property_read_u16()
+ device_property_read_u32()
+ device_property_read_u64()
+ device_property_read_string()
+ device_property_read_u8_array()
+ device_property_read_u16_array()
+ device_property_read_u32_array()
+ device_property_read_u64_array()
+ device_property_read_string_array()
+
+ The first one allows the caller to check if the given property is
+ present. The next 5 of them allow single-valued properties of
+ various types to be retrieved in a uniform way. The remaining 5 are
+ for reading properties with multiple values (arrays of either numbers
+ or strings).
The interface covers both ACPI and Device Trees.
@@ -390,11 +661,13 @@ Date: Wed Oct 1 04:10:03 2014 +0200
Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+ Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+ Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-commit 6b0beaa05b29a299e62293fa4ea4dad0053f31b1
+commit c2d6966e876bb42c76d03d3eb207bfa754657d8b
Author: Mika Westerberg <mika.westerberg@linux.intel.com>
-Date: Wed Oct 1 04:08:56 2014 +0200
+Date: Tue Oct 21 13:33:55 2014 +0200
ACPI: Add support for device specific properties
@@ -444,24 +717,27 @@ Date: Wed Oct 1 04:08:56 2014 +0200
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
+ Reviewed-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-commit ca68950ecf22403e9d0cacdcd86fb4c245de6b9f
+commit 3f675aef809d3f82bf1aa0700065ddf798d1eb86
Author: Mark Salter <msalter@redhat.com>
Date: Tue Sep 30 17:19:24 2014 -0400
- arm64: avoid need for console= to enable serial console
+ [NOT FOR UPSTREAM] 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.
+ override these assumed preferences. This is just a hack to
+ get the behavior we want from SPCR table support. Once SPCR
+ is supported, we can drop this.
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit 6194557254f1ed05638237a64f45f2ec08aa2523
+commit 20d7a3414d18cea0ed8982a5c538e7548bc3bb0a
Author: Tom Lendacky <thomas.lendacky@amd.com>
Date: Tue Sep 9 23:33:17 2014 -0400
@@ -473,7 +749,7 @@ Date: Tue Sep 9 23:33:17 2014 -0400
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit 0c9b242dd24b3ddf2e87209cb07c4bc7f5da21c4
+commit 286f94e27659e7eb45e4b54b4e3c0f9a3b9f9fd4
Author: Tom Lendacky <thomas.lendacky@amd.com>
Date: Tue Sep 9 23:34:07 2014 -0400
@@ -485,7 +761,7 @@ Date: Tue Sep 9 23:34:07 2014 -0400
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit 7697f77962035de040c847f4c331eb91dc1c7c91
+commit 7e7eade04b5fe90bb30a68aa52f0881b354e7d1d
Author: Graeme Gregory <graeme.gregory@linaro.org>
Date: Fri Jul 26 17:55:02 2013 +0100
@@ -495,7 +771,7 @@ Date: Fri Jul 26 17:55:02 2013 +0100
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
-commit 3025ec9f5711f2773be702464bf3150aa914bd66
+commit a1b37e75322dfbd359c86e51ee624511811c93b6
Author: Graeme Gregory <graeme.gregory@linaro.org>
Date: Wed Jul 24 11:29:48 2013 +0100
@@ -508,7 +784,7 @@ Date: Wed Jul 24 11:29:48 2013 +0100
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
-commit a41a9bd6569e079f0572d4b106ffa95d2c16ad06
+commit 29fe31c2a0e6ce57695c1341351c2579d159e446
Author: Mark Salter <msalter@redhat.com>
Date: Thu Sep 18 15:05:23 2014 -0400
@@ -521,7 +797,7 @@ Date: Thu Sep 18 15:05:23 2014 -0400
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit 6e86c887dd05557830a38aa8fd93fab03a409b69
+commit 0875f7e4b6b078859a3765aac54c345980b2748c
Author: Mark Salter <msalter@redhat.com>
Date: Sun Sep 14 09:44:44 2014 -0400
@@ -531,13 +807,13 @@ Date: Sun Sep 14 09:44:44 2014 -0400
Temporarily revert for backwards compatibility with rh-0.12-1 firmware
-commit 81bcad4ccaf54357a6e3d51a135e07a67ce122ee
+commit 31bf2a5577ffb5b318bb9f5d80a9f26224674521
Author: Mark Salter <msalter@redhat.com>
Date: Mon Aug 11 13:46:43 2014 -0400
xgene: add support for ACPI-probed serial port
-commit d99f65d46bcc6a28262ff18506b0f2abd10d789e
+commit f099d9ceac69d7fda70e5d3ee8200f8585f4ff88
Author: Mark Salter <msalter@redhat.com>
Date: Sat Aug 9 12:01:20 2014 -0400
@@ -545,7 +821,7 @@ Date: Sat Aug 9 12:01:20 2014 -0400
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit 977b4da81b8b80d02f54f2fc799fb292b22ade12
+commit 7020f9dda064514d58da5701a351d4773a1d274f
Author: Mark Salter <msalter@redhat.com>
Date: Tue Sep 9 22:59:48 2014 -0400
@@ -561,15 +837,7 @@ Date: Tue Sep 9 22:59:48 2014 -0400
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit b0be9a425fd397fbed0b720a310e82d5d422f0da
-Author: Mark Salter <msalter@redhat.com>
-Date: Tue Sep 23 12:35:17 2014 -0400
-
- arm64/acpi: make acpi disabled by default
-
- Signed-off-by: Mark Salter <msalter@redhat.com>
-
-commit 2dd589faf326c07b981093f73a9c7448ddf4afbf
+commit 17b60c76da131d5fb9c401ec43404c911fe57f39
Author: Hanjun Guo <hanjun.guo@linaro.org>
Date: Thu Aug 28 14:26:16 2014 -0400
@@ -583,7 +851,7 @@ Date: Thu Aug 28 14:26:16 2014 -0400
[fixed up for 3.17-rc]
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit 1857c8d68b23fb57f6f6c64d09e3ce183244d399
+commit fc47393ae2927cb1069c2e15a7b142998702b05d
Author: Al Stone <ahs3@redhat.com>
Date: Thu Aug 28 13:14:16 2014 -0400
@@ -591,7 +859,7 @@ Date: Thu Aug 28 13:14:16 2014 -0400
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit 4529b4dbbaa8732c742300f3abe8db83e08670e8
+commit 7100a707311becfd1cbfc26ad8298cc290877db5
Author: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Date: Tue Sep 9 15:37:15 2014 -0500
@@ -617,7 +885,7 @@ Date: Tue Sep 9 15:37:15 2014 -0500
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
-commit 2bf2a4a102bbe2abf7b2306e89d4d59fb7ade8d2
+commit 397bc93ab853400f7146b8be14bd6cc044df9830
Author: Graeme Gregory <graeme.gregory@linaro.org>
Date: Wed Aug 13 13:47:18 2014 +0100
@@ -632,7 +900,7 @@ Date: Wed Aug 13 13:47:18 2014 +0100
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
-commit 5c62121c6de8268b06d563596953ce71d292733a
+commit 1e6ba230a5e0c03916b0134d846204e64c477972
Author: Mark Salter <msalter@redhat.com>
Date: Mon Sep 8 11:58:46 2014 -0400
@@ -646,7 +914,7 @@ Date: Mon Sep 8 11:58:46 2014 -0400
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit c4f70201c3e20f95c1a96929cf8e524a82dddf81
+commit b3ae15f9e484bab186a5ed697bb25f0244b5aa50
Author: Graeme Gregory <graeme.gregory@linaro.org>
Date: Mon Sep 8 10:36:44 2014 -0400
@@ -658,7 +926,7 @@ Date: Mon Sep 8 10:36:44 2014 -0400
Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
-commit e632bb50e732757dd8ac56f94785b86c300585ba
+commit 4b29bf89ba430787509cb06a6aa38fafeb910b56
Author: Mark Salter <msalter@redhat.com>
Date: Mon Sep 8 17:04:28 2014 -0400
@@ -670,9 +938,9 @@ Date: Mon Sep 8 17:04:28 2014 -0400
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit 51ba60203fe3cb844f1b56389dc840ecf0264817
+commit 58bb9299b1b2a87bd8002ee1bd6eb90138cc4f30
Author: Graeme Gregory <graeme.gregory@linaro.org>
-Date: Fri Sep 12 22:00:16 2014 +0800
+Date: Fri Oct 17 21:37:14 2014 +0800
Documentation: ACPI for ARM64
@@ -680,11 +948,12 @@ Date: Fri Sep 12 22:00:16 2014 +0800
on ARM64.
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
+ Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit 49c2936aebfdc0d6fb6f8a2ed85295e4370afac7
+commit 47e5e8a11d7d0f4930c2e98671a973f3edac313f
Author: Graeme Gregory <graeme.gregory@linaro.org>
-Date: Fri Sep 12 22:00:15 2014 +0800
+Date: Fri Oct 17 21:37:13 2014 +0800
ARM64 / ACPI: Enable ARM64 in Kconfig
@@ -698,9 +967,9 @@ Date: Fri Sep 12 22:00:15 2014 +0800
Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit 4a1bcc17290231af1cfbef33aa6ec77aca609389
+commit 3738397b4a8e91102db2af9ad29919a19425b3f0
Author: Al Stone <al.stone@linaro.org>
-Date: Fri Sep 12 22:00:14 2014 +0800
+Date: Fri Oct 17 21:37:12 2014 +0800
ARM64 / ACPI: Select ACPI_REDUCED_HARDWARE_ONLY if ACPI is enabled on ARM64
@@ -712,9 +981,9 @@ Date: Fri Sep 12 22:00:14 2014 +0800
Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit 2863c8dd559eaa85dbec982045ae8201bdd0216e
+commit 77476629347ec5b72b13e0f3d2cf71604286298c
Author: Hanjun Guo <hanjun.guo@linaro.org>
-Date: Fri Sep 12 22:00:13 2014 +0800
+Date: Fri Oct 17 21:37:11 2014 +0800
ARM64 / ACPI: Parse GTDT to initialize arch timer
@@ -724,9 +993,9 @@ Date: Fri Sep 12 22:00:13 2014 +0800
Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit 75398d7dfd0a9bb67c70568bbc49e79d43681516
+commit 1386d5f6353e7a13d34df5302bc7e4bd1c6aae28
Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
-Date: Fri Sep 12 22:00:12 2014 +0800
+Date: Fri Oct 17 21:37:10 2014 +0800
ARM64 / ACPI: Add GICv2 specific ACPI boot support
@@ -742,9 +1011,9 @@ Date: Fri Sep 12 22:00:12 2014 +0800
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit 325e4412a370d58213bd1cd9de5a5f104dd2bab4
+commit 5213320ccc37374bbf6facc7f7e3c9246bc933c3
Author: Hanjun Guo <hanjun.guo@linaro.org>
-Date: Fri Sep 12 22:00:11 2014 +0800
+Date: Fri Oct 17 21:37:09 2014 +0800
ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
@@ -758,9 +1027,9 @@ Date: Fri Sep 12 22:00:11 2014 +0800
Originally-by: Amit Daniel Kachhap <amit.daniel@samsung.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit 4537275d3b1611bb1102eadfce56af2d36d1c25b
+commit d1c5a9cdd33f04d4ca5f8ef1b8aed16552fc4f2d
Author: Hanjun Guo <hanjun.guo@linaro.org>
-Date: Fri Sep 12 22:00:10 2014 +0800
+Date: Fri Oct 17 21:37:08 2014 +0800
ACPI / processor: Make it possible to get CPU hardware ID via GICC
@@ -772,9 +1041,9 @@ Date: Fri Sep 12 22:00:10 2014 +0800
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit 5ae8a2bbb06f1833c6494fc7a5f30931cc4b5d9a
+commit 9db9a0235e80b8a80af1a000fac4127333b2a2e6
Author: Hanjun Guo <hanjun.guo@linaro.org>
-Date: Fri Sep 12 22:00:09 2014 +0800
+Date: Fri Oct 17 21:37:07 2014 +0800
ARM64 / ACPI: Parse MADT for SMP initialization
@@ -791,21 +1060,29 @@ Date: Fri Sep 12 22:00:09 2014 +0800
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
-commit 4a3aed9caf1780e72030a7efc32d28a32d3ed603
+commit 1a5a392de06147924052458a6c2fd182dcd4d509
Author: Hanjun Guo <hanjun.guo@linaro.org>
-Date: Fri Sep 12 22:00:08 2014 +0800
+Date: Fri Oct 17 21:37:06 2014 +0800
ACPI / table: Print GIC information when MADT is parsed
When MADT is parsed, print GIC information to make the boot
- log look pretty.
+ log look pretty:
+
+ ACPI: GICC (acpi_id[0x0000] address[00000000e112f000] MPDIR[0x0] enabled)
+ ACPI: GICC (acpi_id[0x0001] address[00000000e112f000] MPDIR[0x1] enabled)
+ ...
+ ACPI: GICC (acpi_id[0x0201] address[00000000e112f000] MPDIR[0x201] enabled)
+
+ These information will be very helpful to bring up early systems to
+ see if acpi_id and MPIDR are matched or not as spec defined.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
-commit d9f88c9f5385ac2ae7c87ca0ee63e8e77a37ca09
+commit dbb10ccb37b11731a79bc004da46e482a7152be4
Author: Hanjun Guo <hanjun.guo@linaro.org>
-Date: Fri Sep 12 22:00:07 2014 +0800
+Date: Fri Oct 17 21:37:05 2014 +0800
ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
@@ -832,9 +1109,9 @@ Date: Fri Sep 12 22:00:07 2014 +0800
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
-commit f5b32d09a98c2d5353915d2bcc3d7fa3151b6890
+commit f367d6c84f50ad7e1944ef6ec7aca8b01fd82051
Author: Hanjun Guo <hanjun.guo@linaro.org>
-Date: Fri Sep 12 22:00:06 2014 +0800
+Date: Fri Oct 17 21:37:04 2014 +0800
ARM64 / ACPI: Make PCI optional for ACPI on ARM64
@@ -847,38 +1124,40 @@ Date: Fri Sep 12 22:00:06 2014 +0800
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit 445abae9b9e86d9bd81b3cbffc5d20e8cb375ab0
+commit 2926fd3502c857db06ab41caa8f628089287d6f4
Author: Graeme Gregory <graeme.gregory@linaro.org>
-Date: Fri Sep 12 22:00:05 2014 +0800
+Date: Fri Oct 17 21:37:03 2014 +0800
ARM64 / ACPI: If we chose to boot from acpi then disable FDT
If the early boot methods of acpi are happy that we have valid ACPI
- tables and acpi=off has not been passed. Then do not unflat
- devicetree effectively disabling further hardware probing from DT.
+ tables and acpi=force has been passed, then do not unflat devicetree
+ effectively disabling further hardware probing from DT.
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit fad554282770ff7d0a0b002bb2c3d289ad5cc187
+commit d40d81475b41044935ee4eb455a58308e0f070ac
Author: Al Stone <al.stone@linaro.org>
-Date: Fri Sep 12 22:00:04 2014 +0800
+Date: Fri Oct 17 21:37:02 2014 +0800
- ARM64 / ACPI: Introduce early_param for "acpi"
+ ARM64 / ACPI: Introduce early_param for "acpi" and pass acpi=force to enable ACPI
- Introduce one early parameters "off" for "acpi" to disable ACPI on
- ARM64.
+ Introduce one early parameters "off" and "force" for "acpi", acpi=off
+ will be the default behavior for ARM64, so introduce acpi=force to
+ enable ACPI on ARM64.
- This ensures the kernel uses the DT on a platform that provides both
- ACPI tables and DT.
+ Disable ACPI before early parameters parsed, and enable it to pass
+ "acpi=force" if people want use ACPI on ARM64. This ensures DT be
+ the prefer one if ACPI table and DT both are provided at this moment.
Signed-off-by: Al Stone <al.stone@linaro.org>
Signed-off-by: Graeme Gregory <graeme.gregory@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit ed545c4a15e82373747e2ca4dd44c313a5cbfdbc
+commit 19ddd869d20be9d05e37a3e867f3c1c379bc0a07
Author: Graeme Gregory <graeme.gregory@linaro.org>
-Date: Fri Sep 12 22:00:03 2014 +0800
+Date: Fri Oct 17 21:37:01 2014 +0800
ARM64 / ACPI: Introduce sleep-arm.c
@@ -891,9 +1170,9 @@ Date: Fri Sep 12 22:00:03 2014 +0800
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit f6b5641dd6b5bf915ee9c18bb0f44f07b858bfc2
+commit b2247b541995418caafcfc9f12e57b444fdee75d
Author: Al Stone <al.stone@linaro.org>
-Date: Fri Sep 12 22:00:02 2014 +0800
+Date: Fri Oct 17 21:37:00 2014 +0800
ARM64 / ACPI: Get RSDP and ACPI boot-time tables
@@ -923,9 +1202,9 @@ Date: Fri Sep 12 22:00:02 2014 +0800
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit 7a5a04722c2527962e4b1ebc979e185a64ed11b4
+commit ff7fee61b5c51bc24b358a6521ee9ac0c81c4ae6
Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
-Date: Fri Sep 12 22:00:01 2014 +0800
+Date: Fri Oct 17 21:36:59 2014 +0800
ACPI / table: Count matched and successfully parsed entries without specifying max entries
@@ -938,12 +1217,13 @@ Date: Fri Sep 12 22:00:01 2014 +0800
NOTE: This change has no impact to x86 and ia64 archs since existing code
checks for error occurrence only (acpi_parse_entries(...,0) < 0).
+ Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit 80eb7126770fd6b5c595e4733fb3194bda75f25b
+commit 77a4d1f4423591c4f0bed7d580afb7fc7cacb082
Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>
-Date: Fri Sep 12 22:00:00 2014 +0800
+Date: Fri Oct 17 21:36:58 2014 +0800
ACPI / table: Add new function to get table entries
@@ -954,35 +1234,33 @@ Date: Fri Sep 12 22:00:00 2014 +0800
each call. e.g. as in acpi_table_parse_madt() which is
normally called after acpi_table_parse().
+ Acked-by: Grant Likely <grant.likely@linaro.org>
Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org>
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
-commit 36633ceecab0b57354030ba4e796c3eccb0084a8
-Author: Hanjun Guo <hanjun.guo@linaro.org>
-Date: Fri Sep 12 21:59:59 2014 +0800
+commit 17a565aba814f8cb39d27afb0dbf3834be83ac41
+Author: Mark Salter <msalter@redhat.com>
+Date: Sat Nov 8 22:25:48 2014 -0500
- ARM64: Move the init of cpu_logical_map(0) before unflatten_device_tree()
+ arm64: use UEFI for reboot
- It always make sense to initialize CPU0's logical map entry from the
- hardware values, so move the initialization of cpu_logical_map(0)
- before unflatten_device_tree() which is needed by ACPI code later.
+ Wire in support for UEFI reboot. We want UEFI reboot to have
+ highest priority for capsule support.
- Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
+ Signed-off-by: Mark Salter <msalter@redhat.com>
-commit 1029a72c660016d7b566f9b91156068f4a86ccb7
+commit c66bae4dfb9dbf577e4692fd034cb80703f687a6
Author: Mark Salter <msalter@redhat.com>
-Date: Tue Jun 24 09:50:28 2014 -0400
+Date: Sat Nov 8 15:25:41 2014 -0500
- arm64: use EFI as last resort for reboot and poweroff
+ arm64: use UEFI as last resort for poweroff
- Wire in support for EFI reboot and poweroff functions. We use these
- only if no other mechanism has been registered with arm_pm_reboot
- and/or pm_power_off respectively.
+ Wire in support for poweroff via UEFI.
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit 0fdae79847bdc64aee1a765c0bb5ee99ed95eb0e
+commit ddc5d1b9a52d9c17fd975fd6ee22be7d6ce5e496
Author: Mark Salter <msalter@redhat.com>
Date: Thu Jul 17 13:34:50 2014 -0400
@@ -1000,7 +1278,7 @@ Date: Thu Jul 17 13:34:50 2014 -0400
Signed-off-by: Mark Salter <msalter@redhat.com>
-commit 6e00476b0a33370988b3fee8551c0a8d98206bd2
+commit 8675c7685ea64e0fda9cebbed08e3f30a71589cf
Author: Kyle McMartin <kmcmarti@redhat.com>
Date: Tue May 13 22:25:26 2014 -0400
@@ -1070,38 +1348,464 @@ Date: Tue May 13 22:25:26 2014 -0400
Signed-off-by: Kyle McMartin <kmcmarti@redhat.com>
Signed-off-by: Donald Dutile <ddutile@redhat.com>
- Documentation/acpi/properties.txt | 410 ++++++++++++
- Documentation/arm64/arm-acpi.txt | 218 +++++++
+commit ff46d52dc804aeff783ff55b4b6dc489da20bc11
+Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Fri Nov 7 14:12:34 2014 +0000
+
+ arm64: kvm: eliminate literal pool entries
+
+ Replace two instances of 'ldr xN, =(constant)' in the world switch
+ hot path with 'mov' instructions.
+
+ Acked-by: Marc Zyngier <marc.zyngier@arm.com>
+ Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+ Signed-off-by: Will Deacon <will.deacon@arm.com>
+
+commit 6ddb6f9d2fe1ecab0b812b3adc4ba4bc0cf19ad8
+Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Fri Nov 7 14:12:33 2014 +0000
+
+ arm64: ftrace: eliminate literal pool entries
+
+ Replace ldr xN, =<symbol> with adrp/add or adrp/ldr [as appropriate]
+ in the implementation of _mcount(), which may be called very often.
+
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+ Signed-off-by: Will Deacon <will.deacon@arm.com>
+
+commit 35939bd2c847d742ab82049b2cc79c086e0e7130
+Author: Mark Rutland <mark.rutland@arm.com>
+Date: Tue Nov 4 10:50:16 2014 +0000
+
+ arm64: log physical ID of boot CPU
+
+ In certain debugging scenarios it's useful to know the physical ID (i.e.
+ the MPIDR_EL1.Aff* fields) of the boot CPU, but we don't currently log
+ this as we do for 32-bit ARM kernels.
+
+ This patch makes the kernel log the physical ID of the boot CPU early in
+ the boot process. The CPU logical map initialisation is folded in to
+ smp_setup_processor_id (which contrary to its name is also called by UP
+ kernels). This is called before setup_arch, so should not adversely
+ affect existing cpu_logical_map users.
+
+ Acked-by: Sudeep Holla <sudeep.holla@arm.com>
+ Acked-by: Catalin Marinas <catalin.marinas@arm.com>
+ Acked-by: Lorenzo Pieralisis <lorenzo.pieralisi@arm.com>
+ Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+ Signed-off-by: Will Deacon <will.deacon@arm.com>
+
+commit aea6f516118cedb6f9e8d2ab23ab5a09c275e68d
+Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Mon Nov 3 16:50:01 2014 +0000
+
+ arm64/crypto: use crypto instructions to generate AES key schedule
+
+ This patch implements the AES key schedule generation using ARMv8
+ Crypto Instructions. It replaces the table based C implementation
+ in aes_generic.ko, which means we can drop the dependency on that
+ module.
+
+ Tested-by: Steve Capper <steve.capper@linaro.org>
+ Acked-by: Steve Capper <steve.capper@linaro.org>
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+ Signed-off-by: Will Deacon <will.deacon@arm.com>
+
+commit 0844cddfa0ad22093ef94fdf203fe50cb92222db
+Author: Geoff Levand <geoff@infradead.org>
+Date: Fri Oct 31 23:06:47 2014 +0000
+
+ arm64/kvm: Fix assembler compatibility of macros
+
+ Some of the macros defined in kvm_arm.h are useful in assembly files, but are
+ not compatible with the assembler. Change any C language integer constant
+ definitions using appended U, UL, or ULL to the UL() preprocessor macro. Also,
+ add a preprocessor include of the asm/memory.h file which defines the UL()
+ macro.
+
+ Fixes build errors like these when using kvm_arm.h in assembly
+ source files:
+
+ Error: unexpected characters following instruction at operand 3 -- `and x0,x1,#((1U<<25)-1)'
+
+ Acked-by: Mark Rutland <mark.rutland@arm.com>
+ Signed-off-by: Geoff Levand <geoff@infradead.org>
+ Signed-off-by: Will Deacon <will.deacon@arm.com>
+
+commit 94141ed36a5e0a2159deadfcc29a504b55bb352d
+Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Tue Oct 28 12:24:20 2014 +0000
+
+ arm64/dt: add machine name to kernel call stack dump output
+
+ This installs the machine name as recorded by setup_machine_fdt()
+ as dump stack arch description. This results in the string to be
+ included in call stack dumps, as is shown here:
+
+ ...
+ Bad mode in Synchronous Abort handler detected, code 0x84000005
+ CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.18.0-rc2+ #548
+ > Hardware name: linux,dummy-virt (DT)
+ task: ffffffc07c870000 ti: ffffffc07c878000 task.ti: ffffffc07c878000
+ PC is at 0x0
+ ...
+
+ Note that systems that support DMI/SMBIOS may override this later.
+
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+ Signed-off-by: Will Deacon <will.deacon@arm.com>
+
+commit a3b3b6027369ce53251bb381c9b87031bbd75464
+Author: Steve Capper <steve.capper@linaro.org>
+Date: Fri Oct 24 13:22:20 2014 +0100
+
+ arm64: xchg: Implement cmpxchg_double
+
+ The arm64 architecture has the ability to exclusively load and store
+ a pair of registers from an address (ldxp/stxp). Also the SLUB can take
+ advantage of a cmpxchg_double implementation to avoid taking some
+ locks.
+
+ This patch provides an implementation of cmpxchg_double for 64-bit
+ pairs, and activates the logic required for the SLUB to use these
+ functions (HAVE_ALIGNED_STRUCT_PAGE and HAVE_CMPXCHG_DOUBLE).
+
+ Also definitions of this_cpu_cmpxchg_8 and this_cpu_cmpxchg_double_8
+ are wired up to cmpxchg_local and cmpxchg_double_local (rather than the
+ stock implementations that perform non-atomic operations with
+ interrupts disabled) as they are used by the SLUB.
+
+ On a Juno platform running on only the A57s I get quite a noticeable
+ performance improvement with 5 runs of hackbench on v3.17:
+
+ Baseline | With Patch
+ -----------------+-----------
+ Mean 119.2312 | 106.1782
+ StdDev 0.4919 | 0.4494
+
+ (times taken to complete `./hackbench 100 process 1000', in seconds)
+
+ Signed-off-by: Steve Capper <steve.capper@linaro.org>
+ Signed-off-by: Will Deacon <will.deacon@arm.com>
+
+commit e21d5b44cf03b31feac7854a5953d17ef94d76d9
+Author: Joonwoo Park <joonwoop@codeaurora.org>
+Date: Tue Oct 21 01:59:03 2014 +0100
+
+ arm64: optimize memcpy_{from,to}io() and memset_io()
+
+ Optimize memcpy_{from,to}io() and memset_io() by transferring in 64 bit
+ as much as possible with minimized barrier usage. This simplest
+ optimization brings faster throughput compare to current byte-by-byte read
+ and write with barrier in the loop. Code's skeleton is taken from the
+ powerpc.
+
+ Link: http://lkml.kernel.org/p/20141020133304.GH23751@e104818-lin.cambridge.arm.com
+ Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+ Reviewed-by: Trilok Soni <tsoni@codeaurora.org>
+ Signed-off-by: Joonwoo Park <joonwoop@codeaurora.org>
+ Signed-off-by: Will Deacon <will.deacon@arm.com>
+
+commit c8f2e7e08d50c4adb77a0fac4a2871c100ef2f51
+Author: Min-Hua Chen <orca.chen@gmail.com>
+Date: Thu Oct 9 16:53:10 2014 +0100
+
+ arm64: fix data type for physical address
+
+ Use phys_addr_t for physical address in alloc_init_pud. Although
+ phys_addr_t and unsigned long are 64 bit in arm64, it is better
+ to use phys_addr_t to describe physical addresses.
+
+ Signed-off-by: Min-Hua Chen <orca.chen@gmail.com>
+ Signed-off-by: Will Deacon <will.deacon@arm.com>
+
+commit 674f32f5ef38c93af7a273a725a0a89b4b8a38a1
+Author: Mark Rutland <mark.rutland@arm.com>
+Date: Thu Oct 23 16:33:33 2014 +0100
+
+ efi: efi-stub: notify on DTB absence
+
+ In the absence of a DTB configuration table, the EFI stub will happily
+ continue attempting to boot a kernel, despite the fact that this kernel
+ may not function without a description of the hardware. In this case, as
+ with a typo'd "dtb=" option (e.g. "dbt=") or many other possible
+ failures, the only output seen by the user will be the rather terse
+ output from the EFI stub:
+
+ EFI stub: Booting Linux Kernel...
+
+ To aid those attempting to debug such failures, this patch adds a notice
+ when no DTB is found, making the output more helpful:
+
+ EFI stub: Booting Linux Kernel...
+ EFI stub: Generating empty DTB
+
+ Additionally, a positive acknowledgement is added when a user-specified
+ DTB is in use:
+
+ EFI stub: Booting Linux Kernel...
+ EFI stub: Using DTB from command line
+
+ Similarly, a positive acknowledgement is added when a DTB from a
+ configuration table is in use:
+
+ EFI stub: Booting Linux Kernel...
+ EFI stub: Using DTB from configuration table
+
+ Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+ Acked-by: Leif Lindholm <leif.lindholm@linaro.org>
+ Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+ Acked-by: Roy Franz <roy.franz@linaro.org>
+ Acked-by: Matt Fleming <matt.fleming@intel.com>
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit 872cf856a3fc4cff5190af2f79cfc3ac410eae17
+Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Wed Oct 15 09:36:50 2014 +0200
+
+ arm64: dmi: set DMI string as dump stack arch description
+
+ This sets the DMI string, containing system type, serial number,
+ firmware version etc. as dump stack arch description, so that oopses
+ and other kernel stack dumps automatically have this information
+ included, if available.
+
+ Tested-by: Leif Lindholm <leif.lindholm@linaro.org>
+ Acked-by: Leif Lindholm <leif.lindholm@linaro.org>
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit 2a2978d3748379bb9a0889c866b210f288c45160
+Author: Yi Li <yi.li@linaro.org>
+Date: Sat Oct 4 23:46:43 2014 +0800
+
+ arm64: dmi: Add SMBIOS/DMI support
+
+ SMBIOS is important for server hardware vendors. It implements a spec for
+ providing descriptive information about the platform. Things like serial
+ numbers, physical layout of the ports, build configuration data, and the like.
+
+ Signed-off-by: Yi Li <yi.li@linaro.org>
+ Tested-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+ Tested-by: Leif Lindholm <leif.lindholm@linaro.org>
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit c0f06f02f228ca722a2b850363c342f63e6214a6
+Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Tue Oct 14 16:41:27 2014 +0200
+
+ dmi: add support for SMBIOS 3.0 64-bit entry point
+
+ The DMTF SMBIOS reference spec v3.0.0 defines a new 64-bit entry point,
+ which enables support for SMBIOS structure tables residing at a physical
+ offset over 4 GB. This is especially important for upcoming arm64
+ platforms whose system RAM resides entirely above the 4 GB boundary.
+
+ For the UEFI case, this code attempts to detect the new SMBIOS 3.0
+ header magic at the offset passed in the SMBIOS3_TABLE_GUID UEFI
+ configuration table. If this configuration table is not provided, or
+ if we fail to parse the header, we fall back to using the legacy
+ SMBIOS_TABLE_GUID configuration table. This is in line with the spec,
+ that allows both configuration tables to be provided, but mandates that
+ they must point to the same structure table, unless the version pointed
+ to by the 64-bit entry point is a superset of the 32-bit one.
+
+ For the non-UEFI case, the detection logic is modified to look for the
+ SMBIOS 3.0 header magic before it looks for the legacy header magic.
+
+ Note that this patch is based on version 3.0.0d [draft] of the
+ specification, which is expected not to deviate from the final version
+ in ways that would affect the correctness of this implementation.
+
+ Tested-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+ Acked-by: Leif Lindholm <leif.lindholm@linaro.org>
+ Tested-by: Leif Lindholm <leif.lindholm@linaro.org>
+ Cc: Andrew Morton <akpm@linux-foundation.org>
+ Cc: Tony Luck <tony.luck@intel.com>
+ Acked-by: Matt Fleming <matt.fleming@intel.com>
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit 4ebf40f890ebad9458abc56e00d4814bc881fb9d
+Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Tue Oct 14 16:34:47 2014 +0200
+
+ efi: dmi: add support for SMBIOS 3.0 UEFI configuration table
+
+ This adds support to the UEFI side for detecting the presence of
+ a SMBIOS 3.0 64-bit entry point. This allows the actual SMBIOS
+ structure table to reside at a physical offset over 4 GB, which
+ cannot be supported by the legacy SMBIOS 32-bit entry point.
+
+ Since the firmware can legally provide both entry points, store
+ the SMBIOS 3.0 entry point in a separate variable, and let the
+ DMI decoding layer decide which one will be used.
+
+ Tested-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+ Acked-by: Leif Lindholm <leif.lindholm@linaro.org>
+ Acked-by: Matt Fleming <matt.fleming@intel.com>
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit 90c66a6923311d477c68543f945f543558b91eec
+Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Fri Oct 17 12:44:11 2014 +0200
+
+ arm64/efi: drop redundant set_bit(EFI_CONFIG_TABLES)
+
+ The EFI_CONFIG_TABLES bit already gets set by efi_config_init(),
+ so there is no reason to set it again after this function returns
+ successfully.
+
+ Acked-by: Will Deacon <will.deacon@arm.com>
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit bbc705f61c1aebddb5bf80f75964b6da40c55ca9
+Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Mon Oct 20 15:31:57 2014 +0200
+
+ arm64/efi: invert UEFI memory region reservation logic
+
+ Instead of reserving the memory regions based on which types we know
+ need to be reserved, consider only regions of the following types as
+ free for general use by the OS:
+
+ EFI_LOADER_CODE
+ EFI_LOADER_DATA
+ EFI_BOOT_SERVICES_CODE
+ EFI_BOOT_SERVICES_DATA
+ EFI_CONVENTIONAL_MEMORY
+
+ Note that this also fixes a problem with the original code, which would
+ misidentify a EFI_RUNTIME_SERVICES_DATA region as not reserved if it
+ does not have the EFI_MEMORY_RUNTIME attribute set. However, it is
+ perfectly legal for the firmware not to request a virtual mapping for
+ EFI_RUNTIME_SERVICES_DATA regions that contain configuration tables, in
+ which case the EFI_MEMORY_RUNTIME attribute would not be set.
+
+ Acked-by: Roy Franz <roy.franz@linaro.org>
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit d6e4e04244cb7b4670759bd83679ead21df55a8a
+Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Fri Oct 10 18:42:55 2014 +0200
+
+ arm64/efi: set PE/COFF file alignment to 512 bytes
+
+ Change our PE/COFF header to use the minimum file alignment of
+ 512 bytes (0x200), as mandated by the PE/COFF spec v8.3
+
+ Also update the linker script so that the Image file itself is also a
+ round multiple of FileAlignment.
+
+ Acked-by: Catalin Marinas <catalin.marinas@arm.com>
+ Acked-by: Roy Franz <roy.franz@linaro.org>
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit e9e7422d7035c64a16771d47dcd9f907adc5070d
+Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Fri Oct 10 11:25:24 2014 +0200
+
+ arm64/efi: set PE/COFF section alignment to 4 KB
+
+ Position independent AArch64 code needs to be linked and loaded at the
+ same relative offset from a 4 KB boundary, or adrp/add and adrp/ldr
+ pairs will not work correctly. (This is how PC relative symbol
+ references with a 4 GB reach are emitted)
+
+ We need to declare this in the PE/COFF header, otherwise the PE/COFF
+ loader may load the Image and invoke the stub at an offset which
+ violates this rule.
+
+ Reviewed-by: Roy Franz <roy.franz@linaro.org>
+ Acked-by: Mark Rutland <mark.rutland@arm.com>
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit 2d2346a11e6ac9be30ac5590a7ec4b47bda35870
+Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Wed Oct 8 16:11:27 2014 +0200
+
+ arm64/efi: efistub: jump to 'stext' directly, not through the header
+
+ After the EFI stub has done its business, it jumps into the kernel by
+ branching to offset #0 of the loaded Image, which is where it expects
+ to find the header containing a 'branch to stext' instruction.
+
+ However, the UEFI spec 2.1.1 states the following regarding PE/COFF
+ image loading:
+ "A UEFI image is loaded into memory through the LoadImage() Boot
+ Service. This service loads an image with a PE32+ format into memory.
+ This PE32+ loader is required to load all sections of the PE32+ image
+ into memory."
+
+ In other words, it is /not/ required to load parts of the image that are
+ not covered by a PE/COFF section, so it may not have loaded the header
+ at the expected offset, as it is not covered by any PE/COFF section.
+
+ So instead, jump to 'stext' directly, which is at the base of the
+ PE/COFF .text section, by supplying a symbol 'stext_offset' to
+ efi-entry.o which contains the relative offset of stext into the Image.
+ Also replace other open coded calculations of the same value with a
+ reference to 'stext_offset'
+
+ Acked-by: Mark Rutland <mark.rutland@arm.com>
+ Acked-by: Roy Franz <roy.franz@linaro.org>
+ Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+ Documentation/acpi/gpio-properties.txt | 96 +++
+ Documentation/arm64/arm-acpi.txt | 323 ++++++++++
+ Documentation/gpio/consumer.txt | 18 +
Documentation/kernel-parameters.txt | 3 +-
- arch/arm64/Kconfig | 6 +
+ arch/arm/mach-s3c24xx/h1940-bluetooth.c | 4 +-
+ arch/arm/mach-s3c24xx/h1940.h | 4 +-
+ arch/arm/mach-s3c24xx/mach-h1940.c | 3 +-
+ arch/arm/mach-s3c24xx/mach-rx1950.c | 3 +-
+ arch/arm/plat-orion/gpio.c | 3 +-
+ arch/arm/plat-orion/include/plat/orion-gpio.h | 5 +-
+ arch/arm64/Kconfig | 22 +
arch/arm64/Makefile | 1 +
+ arch/arm64/crypto/Kconfig | 5 +-
+ arch/arm64/crypto/aes-ce-ccm-glue.c | 4 +-
+ arch/arm64/crypto/aes-ce-cipher.c | 112 +++-
+ arch/arm64/crypto/aes-ce-setkey.h | 5 +
+ arch/arm64/crypto/aes-glue.c | 18 +-
arch/arm64/include/asm/acenv.h | 18 +
- arch/arm64/include/asm/acpi.h | 99 +++
+ arch/arm64/include/asm/acpi.h | 102 +++
+ arch/arm64/include/asm/cmpxchg.h | 71 +++
arch/arm64/include/asm/cpu_ops.h | 1 +
+ arch/arm64/include/asm/dmi.h | 31 +
arch/arm64/include/asm/elf.h | 3 +-
+ arch/arm64/include/asm/kvm_arm.h | 21 +-
+ arch/arm64/include/asm/pci.h | 51 ++
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/acpi.c | 398 ++++++++++++
arch/arm64/kernel/cpu_ops.c | 8 +-
- arch/arm64/kernel/efi.c | 11 +
- arch/arm64/kernel/process.c | 6 +
+ arch/arm64/kernel/efi-entry.S | 3 +-
+ arch/arm64/kernel/efi.c | 74 ++-
+ arch/arm64/kernel/entry-ftrace.S | 21 +-
+ arch/arm64/kernel/head.S | 24 +-
+ arch/arm64/kernel/io.c | 66 +-
+ arch/arm64/kernel/pci.c | 97 ++-
arch/arm64/kernel/psci.c | 78 ++-
- arch/arm64/kernel/setup.c | 64 +-
+ arch/arm64/kernel/setup.c | 67 +-
arch/arm64/kernel/smp.c | 2 +-
arch/arm64/kernel/smp_parking_protocol.c | 110 ++++
arch/arm64/kernel/time.c | 7 +
+ arch/arm64/kernel/vmlinux.lds.S | 17 +
+ arch/arm64/kvm/hyp.S | 4 +-
arch/arm64/mm/dma-mapping.c | 103 +++
- arch/arm64/pci/Makefile | 1 +
- arch/arm64/pci/pci.c | 28 +
+ arch/arm64/mm/mmu.c | 2 +-
+ arch/arm64/pci/Makefile | 2 +
+ arch/arm64/pci/mmconfig.c | 292 +++++++++
+ arch/arm64/pci/pci.c | 461 ++++++++++++++
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/property.c | 551 ++++++++++++++++
+ drivers/acpi/scan.c | 129 +++-
drivers/acpi/sleep-arm.c | 28 +
drivers/acpi/tables.c | 115 +++-
drivers/acpi/utils.c | 26 +
@@ -1109,23 +1813,27 @@ Date: Tue May 13 22:25:26 2014 -0400
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/base/property.c | 431 +++++++++++++
+ drivers/clocksource/arm_arch_timer.c | 120 +++-
+ drivers/firmware/dmi_scan.c | 79 ++-
+ drivers/firmware/efi/efi.c | 4 +
+ drivers/firmware/efi/libstub/arm-stub.c | 11 +-
+ drivers/gpio/devres.c | 32 +
drivers/gpio/gpio-sch.c | 293 ++++-----
- drivers/gpio/gpiolib-acpi.c | 78 ++-
- drivers/gpio/gpiolib.c | 86 ++-
+ drivers/gpio/gpiolib-acpi.c | 117 +++-
+ drivers/gpio/gpiolib.c | 85 ++-
drivers/gpio/gpiolib.h | 7 +-
- drivers/input/keyboard/gpio_keys_polled.c | 163 ++---
+ drivers/input/keyboard/gpio_keys_polled.c | 112 ++--
+ drivers/iommu/arm-smmu.c | 8 +-
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/leds/leds-gpio.c | 140 ++--
+ drivers/misc/eeprom/at25.c | 34 +-
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-main.c | 289 +++++++--
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 +
@@ -1135,471 +1843,166 @@ Date: Tue May 13 22:25:26 2014 -0400
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/of/base.c | 33 +
+ drivers/pci/host/pci-xgene.c | 174 ++++-
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 +
+ drivers/xen/efi.c | 1 +
+ include/acpi/acpi_bus.h | 30 +
include/acpi/acpi_io.h | 6 +
+ include/asm-generic/vmlinux.lds.h | 7 +
include/kvm/arm_vgic.h | 20 +-
- include/linux/acpi.h | 95 ++-
+ include/linux/acpi.h | 141 +++-
include/linux/clocksource.h | 6 +
- include/linux/gpio/consumer.h | 5 +
+ include/linux/efi.h | 6 +-
+ include/linux/gpio/consumer.h | 7 +
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/leds.h | 3 +-
+ include/linux/of.h | 34 +
include/linux/pci.h | 37 +-
- include/linux/property.h | 207 ++++++
+ include/linux/property.h | 143 +++++
+ net/bridge/netfilter/nft_reject_bridge.c | 1 +
+ net/rfkill/rfkill-gpio.c | 18 +-
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(-)
+ 123 files changed, 6825 insertions(+), 1116 deletions(-)
-diff --git a/Documentation/acpi/properties.txt b/Documentation/acpi/properties.txt
+diff --git a/Documentation/acpi/gpio-properties.txt b/Documentation/acpi/gpio-properties.txt
new file mode 100644
-index 0000000..13a93c5
+index 0000000..ae36fcf
--- /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.
++++ b/Documentation/acpi/gpio-properties.txt
+@@ -0,0 +1,96 @@
++_DSD Device Properties Related to GPIO
++--------------------------------------
++
++With the release of ACPI 5.1 and the _DSD configuration objecte names
++can finally be given to GPIOs (and other things as well) returned by
++_CRS. Previously, we were only able to use an integer index to find
++the corresponding GPIO, which is pretty error prone (it depends on
++the _CRS output ordering, for example).
++
++With _DSD we can now query GPIOs using a name instead of an integer
++index, like the ASL example below 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 a 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.
++
++ACPI GPIO Mappings Provided by Drivers
++--------------------------------------
++
++There are systems in which the ACPI tables do not contain _DSD but provide _CRS
++with GpioIo()/GpioInt() resources and device drivers still need to work with
++them.
++
++In those cases ACPI device identification objects, _HID, _CID, _CLS, _SUB, _HRV,
++available to the driver can be used to identify the device and that is supposed
++to be sufficient to determine the meaning and purpose of all of the GPIO lines
++listed by the GpioIo()/GpioInt() resources returned by _CRS. In other words,
++the driver is supposed to know what to use the GpioIo()/GpioInt() resources for
++once it has identified the device. Having done that, it can simply assign names
++to the GPIO lines it is going to use and provide the GPIO subsystem with a
++mapping between those names and the ACPI GPIO resources corresponding to them.
++
++To do that, the driver needs to define a mapping table as a NULL-terminated
++array of struct acpi_gpio_mapping objects that each contain a name, a pointer
++to an array of line data (struct acpi_gpio_params) objects and the size of that
++array. Each struct acpi_gpio_params object consists of three fields,
++crs_entry_index, line_index, active_low, representing the index of the target
++GpioIo()/GpioInt() resource in _CRS starting from zero, the index of the target
++line in that resource starting from zero, and the active-low flag for that line,
++respectively, in analogy with the _DSD GPIO property format specified above.
++
++For the example Bluetooth device discussed previously the data structures in
++question would look like this:
++
++static const struct acpi_gpio_params reset_gpio = { 1, 1, false };
++static const struct acpi_gpio_params shutdown_gpio = { 0, 0, false };
++
++static const struct acpi_gpio_mapping bluetooth_acpi_gpios[] = {
++ { "reset-gpio", &reset_gpio, 1 },
++ { "shutdown-gpio", &shutdown_gpio, 1 },
++ { },
++};
+
-+It is preferred that new devices get a proper _HID allocated for them
-+instead of inventing new DT "compatible" devices.
++Next, the mapping table needs to be passed as the second argument to
++acpi_dev_add_driver_gpios() that will register it with the ACPI device object
++pointed to by its first argument. That should be done in the driver's .probe()
++routine. On removal, the driver should unregister its GPIO mapping table by
++calling acpi_dev_remove_driver_gpios() on the ACPI device object where that
++table was previously registered.
diff --git a/Documentation/arm64/arm-acpi.txt b/Documentation/arm64/arm-acpi.txt
new file mode 100644
-index 0000000..b7dc826
+index 0000000..17cf96d
--- /dev/null
+++ b/Documentation/arm64/arm-acpi.txt
-@@ -0,0 +1,218 @@
+@@ -0,0 +1,323 @@
+ACPI on ARMv8 Servers
+---------------------
-+
+ACPI can be used for ARMv8 general purpose servers designed to follow
-+the SBSA specification (currently available to people with an ARM login at
-+http://silver.arm.com).
++the ARM SBSA (Server Base System Architecture) specification, currently
++available to those with an ARM login at http://silver.arm.com.
++
++The ARMv8 kernel implements the reduced hardware model of ACPI version
++5.1 and its corresponding errata. Links to the specification and all
++external documents it refers to are managed by the UEFI Forum. The
++specification is available at http://www.uefi.org/specifications and
++external documents can be found via http://www.uefi.org/acpi.
+
-+The kernel will implement minimum ACPI version is 5.1 + errata as released by
-+the UEFI Forum, which is available at <http://www.uefi.org/acpi/specs>.
++If an ARMv8 system does not meet the requirements of the SBSA, or cannot
++be described using the mechanisms defined in the required ACPI specifications,
++then it is likely that Device Tree (DT) is more suitable than ACPI for the
++hardware.
+
-+If the machine does not meet the requirements of the SBSA, or cannot be
-+described in the required ACPI specifications then it is likely that Device Tree
-+(DT) is more suitable for the hardware.
+
+Relationship with Device Tree
+-----------------------------
-+
+ACPI support in drivers and subsystems for ARMv8 should never be mutually
+exclusive with DT support at compile time.
+
@@ -1610,131 +2013,226 @@ index 0000000..b7dc826
+of booting with either scheme (in kernels with both schemes enabled at compile
+time).
+
-+When booting using ACPI tables the /chosen node in DT will still be parsed
-+to extract the kernel command line and initrd path. No other section of
-+the DT will be used.
++When booting using ACPI tables, the /chosen node in DT will still be parsed
++to extract the kernel command line and initrd path. No other section of the
++DT will be used.
++
+
+Booting using ACPI tables
+-------------------------
-+
-+Currently, the only defined method to pass ACPI tables to the kernel on ARMv8
++The only defined method for passing ACPI tables to the kernel on ARMv8
+is via the UEFI system configuration table.
+
-+The UEFI implementation MUST set the ACPI_20_TABLE_GUID to point to the
-+RSDP table (the table with the ACPI signature "RSD PTR ").
++Processing of ACPI tables may be disabled by passing acpi=off on the kernel
++command line; this is the default behavior. If acpi=force is used, the kernel
++will ONLY use device configuration information contained in the ACPI tables.
+
-+The pointer to the RSDP table will be retrieved from EFI by the ACPI core.
++In order for the kernel to load and use ACPI tables, the UEFI implementation
++MUST set the ACPI_20_TABLE_GUID to point to the RSDP table (the table with
++the ACPI signature "RSD PTR "). If this pointer is incorrect and acpi=force
++is used, the kernel will disable ACPI and try to use DT to boot.
+
-+Processing of ACPI tables may be disabled by passing acpi=off on the kernel
-+command line.
++If the pointer to the RSDP table is correct, the table will be mapped into
++the kernel by the ACPI core, using the address provided by UEFI.
+
-+DO use an XSDT; RSDTs are deprecated and should not be used on arm64. They
-+only allow for 32-bit addresses.
++The ACPI core will then locate and map in all other ACPI tables provided by
++using the addresses in the RSDP table to find the XSDT (eXtended System
++Description Table). The XSDT in turn provides the addresses to all other
++ACPI tables provided by the system firmware; the ACPI core will then traverse
++this table and map in the tables listed.
+
-+DO NOT use the 32-bit address fields in the FADT; they are deprecated. The
-+64-bit alternatives MUST be used.
++The ACPI core will ignore any provided RSDT (Root System Description Table).
++RSDTs have been deprecated and are ignored on arm64 since they only allow
++for 32-bit addresses.
+
-+The minimum set of tables MUST include RSDP, XSDT, FACS, FADT, DSDT, MADT
-+and GTDT. If PCI is used the MCFG table MUST also be present.
++Further, the ACPI core will only use the 64-bit address fields in the FADT
++(Fixed ACPI Description Table). Any 32-bit address fields in the FADT will
++be ignored on arm64.
+
-+ACPI Detection
-+--------------
++Hardware reduced mode (see Section 4.1 of the ACPI 5.1 specification) will
++be enforced by the ACPI core on arm64. Doing so allows the ACPI core to
++run less complex code since it no longer has to provide support for legacy
++hardware from other architectures.
+
-+Drivers should determine their probe() type by checking for ACPI_HANDLE,
-+or .of_node, or other information in the device structure. This is
-+detailed further in the "Driver Recommendations" section.
++For the ACPI core to operate properly, and in turn provide the information
++the kernel needs to configure devices, it expects to find the following
++tables (all section numbers refer to the ACPI 5.1 specfication):
+
-+In non-driver code If the presence of ACPI needs to be detected at runtime,
-+then check the value of acpi_disabled. If CONFIG_ACPI is not set,
-+acpi_disabled will always be 1.
++ -- RSDP (Root System Description Pointer), section 5.2.5
+
-+Device Enumeration
-+------------------
++ -- XSDT (eXtended System Description Table), section 5.2.8
+
-+Device descriptions in ACPI should use standard recognized ACPI interfaces.
-+These are far simpler than the information provided via Device Tree. Drivers
-+should take into account this simplicity and work with sensible defaults.
++ -- FACS (Firmware ACPI Control Structure), section 5.2.10
++
++ -- FADT (Fixed ACPI Description Table), section 5.2.9
+
-+On no account should a Device Tree attempt to be replicated in ASL using such
-+constructs as Name(KEY0, "Value1") type constructs. Additional driver specific
-+data should be represented with the appropriate _DSD (ACPI Section 6.2.5)
-+structure. _DSM (ACPI Section 9.14.1) should only be used if _DSD cannot
-+represent the data required.
++ -- DSDT (Differentiated System Description Table), section
++ 5.2.11.1
+
-+This data should be rare and not OS specific. For x86 ACPI has taken to
-+identifying itself as Windows because it was found that only one path was
-+routinely tested. For ARMv8 it would be preferable to have only one well
-+tested path.
++ -- MADT (Multiple APIC Description Table), section 5.2.12
+
-+_DSD covers more than the generic server case and care should be taken not to
-+replicate highly specific embedded behaviour from DT into generic servers.
++ -- GTDT (Generic Timer Description Table), section 5.2.24
+
-+Common _DSD bindings should be submitted to ASWG to be included in the
-+document :-
++ -- If PCI is supported, the MCFG (Memory mapped ConFiGuration
++ Table), section 5.2.6, specifically Table 5-31.
+
-+http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel.htm
++If the above tables are not all present, the kernel may or may not be
++able to boot properly since it may not be able to configure all of the
++devices available.
++
++
++ACPI Detection
++--------------
++Drivers should determine their probe() type by checking for a null
++value for ACPI_HANDLE, or checking .of_node, or other information in
++the device structure. This is detailed further in the "Driver
++Recommendations" section.
++
++In non-driver code, if the presence of ACPI needs to be detected at
++runtime, then check the value of acpi_disabled. If CONFIG_ACPI is not
++set, acpi_disabled will always be 1.
++
++
++Device Enumeration
++------------------
++Device descriptions in ACPI should use standard recognized ACPI interfaces.
++These can contain less information than is typically provided via a Device
++Tree description for the same device. This is also one of the reasons that
++ACPI can be useful -- the driver takes into account that it may have less
++detailed information about the device and uses sensible defaults instead.
++If done properly in the driver, the hardware can change and improve over
++time without the driver having to change at all.
++
++Clocks provide an excellent example. In DT, clocks need to be specified
++and the drivers need to take them into account. In ACPI, the assumption
++is that UEFI will leave the device in a reasonable default state, including
++any clock settings. If for some reason the driver needs to change a clock
++value, this can be done in an ACPI method; all the driver needs to do is
++invoke the method and not concern itself with what the method needs to do
++to change the clock. Changing the hardware can then take place over time
++by changing what the ACPI method does, and not the driver.
++
++ACPI drivers should only look at one specific ASL object -- the _DSD object
++-- for device driver parameters (known in DT as "bindings", or "Device
++Properties" in ACPI). Not all DT bindings will be recognized. The UEFI
++Forum provides a mechanism for registering such bindings [URL TBD by ASWG]
++so that they may be used on any operating system supporting ACPI. Device
++properties that have not been registered with the UEFI Forum should not be
++used.
++
++Drivers should look for device properties in the _DSD object ONLY; the _DSD
++object is described in the ACPI specification section 6.2.5, but more
++specifically, use the _DSD Device Properties UUID:
++
++ -- UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301
++
++ -- http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf)
++
++The kernel has an interface for looking up device properties in a manner
++independent of whether DT or ACPI is being used and that interface should
++be used; it can eliminate some duplication of code paths in driver probing
++functions and discourage divergence between DT bindings and ACPI device
++properties.
++
++ACPI tables are described with a formal language called ASL, the ACPI
++Source Language (section 19 of the specification). This means that there
++are always multiple ways to describe the same thing -- including device
++properties. For example, device properties could use an ASL construct
++that looks like this: Name(KEY0, "value0"). An ACPI device driver would
++then retrieve the value of the property by evaluating the KEY0 object.
++However, using Name() this way has multiple problems: (1) ACPI limits
++names ("KEY0") to four characters unlike DT; (2) there is no industry
++wide registry that maintains a list of names, minimzing re-use; (3)
++there is also no registry for the definition of property values ("value0"),
++again making re-use difficult; and (4) how does one maintain backward
++compatibility as new hardware comes out? The _DSD method was created
++to solve precisely these sorts of problems; Linux drivers should ALWAYS
++use the _DSD method for device properties and nothing else.
++
++The _DSM object (ACPI Section 9.14.1) could also be used for conveying
++device properties to a driver. Linux drivers should only expect it to
++be used if _DSD cannot represent the data required, and there is no way
++to create a new UUID for the _DSD object. Note that there is even less
++regulation of the use of _DSM than there is of _DSD. Drivers that depend
++on the contents of _DSM objects will be more difficult to maintain over
++time because of this.
++
++The _DSD object is a very flexible mechanism in ACPI, as are the registered
++Device Properties. This flexibility allows _DSD to cover more than just the
++generic server case and care should be taken in device drivers not to expect
++it to replicate highly specific embedded behaviour from DT.
++
++Both DT bindings and ACPI device properties for device drivers have review
++processes. Use them. And, before creating new device properties, check to
++be sure that they have not been defined before and either registered in the
++Linux kernel documentation or the UEFI Forum. If the device drivers supports
++ACPI and DT, please make sure the device properties are consistent in both
++places.
+
-+If these bindings are mirrored from DT care should be taken to ensure they are
-+reviewed as DT bindings before submission to limit divergance in bindings.
+
+Programmable Power Control Resources
+------------------------------------
-+
+Programmable power control resources include such resources as voltage/current
+providers (regulators) and clock sources.
+
-+For power control of these resources they should be represented with Power
-+Resource Objects (ACPI Section 7.1). The ACPI core will then handle correctly
-+enabling/disabling of resources as they are needed.
++The kernel assumes that power control of these resources is represented with
++Power Resource Objects (ACPI section 7.1). The ACPI core will then handle
++correctly enabling and disabling resources as they are needed. In order to
++get that to work, ACPI assumes each device has defined D-states and that these
++can be controlled through the optional ACPI methods _PS0, _PS1, _PS2, and _PS3;
++in ACPI, _PS0 is the method to invoke to turn a device full on, and _PS3 is for
++turning a device full off.
++
++The kernel ACPI code will also assume that the _PS? methods follow the normal
++ACPI rules for such methods:
+
-+The ACPI 5.1 specification does not contain any standard binding for these
-+objects to enable programmable levels or rates so this should be avoided if
-+possible and the resources set to appropriate levels by the firmware. If this is
-+not possible then any manipulation should be abstracted in ASL.
++ -- If either _PS0 or _PS3 is implemented, then the other method must also
++ be implemented.
+
-+Each device in ACPI has D-states and these can be controlled through
-+the optional methods _PS0..._PS3 where _PS0 is full on and _PS3 is full off.
++ -- If a device requires usage or setup of a power resource when on, the ASL
++ should organize that it is allocated/enabled using the _PS0 method.
+
-+If either _PS0 or _PS3 is implemented, then the other method must also be
-+implemented.
++ -- Resources allocated or enabled in the _PS0 method should be disabled
++ or de-allocated in the _PS3 method.
+
-+If a device requires usage or setup of a power resource when on, the ASL
-+should organize that it is allocated/enabled using the _PS0 method.
++ -- Firmware will leave the resources in a reasonable state before handing
++ over control to the kernel.
+
-+Resources allocated/enabled in the _PS0 method should be disabled/de-allocated
-+in the _PS3 method.
++Such code in _PS? methods will of course be very platform specific. But,
++this allows the driver to abstract out the interface for operating the device
++and avoid having to read special non-standard values from ACPI tables. Further,
++abstracting the use of these resources allows the hardware to change over time
++without requiring updates to the driver.
+
-+Such code in _PS? methods will of course be very platform specific but
-+should allow the driver to operate the device without special non-standard
-+values being read from ASL. Further, abstracting the use of these resources
-+allows hardware revisions without requiring updates to the kernel.
+
+Clocks
+------
++ACPI makes the assumption that clocks are initialized by the firmware --
++UEFI, in this case -- to some working value before control is handed over
++to the kernel. This has implications for devices such as UARTs, or SoC
++driven LCD displays, for example.
+
-+Like clocks that are part of the power resources there is no standard way
-+to represent a clock tree in ACPI 5.1 in a similar manner to how it is
-+described in DT.
-+
-+Devices affected by this include things like UARTs, SoC driven LCD displays,
-+etc.
++When the kernel boots, the clock is assumed to be set to reasonable
++working value. If for some reason the frequency needs to change -- e.g.,
++throttling for power management -- the device driver should expect that
++process to be abstracted out into some ACPI method that can be invoked
++(please see the ACPI specification for further recommendations on standard
++methods to be expected). If is not, there is no direct way for ACPI to
++control the clocks.
+
-+The firmware (for example, UEFI) should initialize these clocks to fixed working
-+values before the kernel is executed.
+
+Driver Recommendations
+----------------------
++DO NOT remove any DT handling when adding ACPI support for a driver. The
++same device may be used on many different systems.
+
-+DO NOT remove any FDT handling when adding ACPI support for a driver. Different
-+systems may use the same device.
-+
-+DO try and keep complex sections of ACPI and DT functionality separate. This
-+may mean a patch to break out some complex DT to another function before
-+the patch to add ACPI. This may happen in other functions but is most likely
-+in probe function. This gives a clearer flow of data for reviewing driver
-+source.
-+
-+probe() :-
++DO try to structure the driver so that it is data driven. That is, set up
++a struct containing internal per-device state based on defaults and whatever
++else must be discovered by the driver probe function. Then, have the rest
++of the driver operate off of the contents of that struct. Doing so should
++allow most divergence between ACPI and DT functionality to be kept local to
++the probe function instead of being scattered throughout the driver. For
++example:
+
+static int device_probe_dt(struct platform_device *pdev)
+{
@@ -1765,10 +2263,9 @@ index 0000000..b7dc826
+ ...
+}
+
-+DO keep the MODULE_DEVICE_TABLE entries together in the driver to make it clear
-+the different names the driver is probed for, both from DT and from ACPI.
-+
-+module device tables :-
++DO keep the MODULE_DEVICE_TABLE entries together in the driver to make it
++clear the different names the driver is probed for, both from DT and from
++ACPI:
+
+static struct of_device_id virtio_mmio_match[] = {
+ { .compatible = "virtio,mmio", },
@@ -1782,27 +2279,64 @@ index 0000000..b7dc826
+};
+MODULE_DEVICE_TABLE(acpi, virtio_mmio_acpi_match);
+
++
+ASWG
+----
-+
-+The following areas are not yet well defined for ARM in the current ACPI
-+specification and are expected to be worked through in the UEFI ACPI
-+Specification Working Group (ASWG) <http://www.uefi.org/workinggroups>.
-+Participation in this group is open to all UEFI members.
-+
-+ - ACPI based CPU topology
-+ - ACPI based Power management
-+ - CPU idle control based on PSCI
-+ - CPU performance control (CPPC)
-+ - ACPI based SMMU
-+ - ITS support for GIC in MADT
-+
-+No code shall be accepted into the kernel unless it complies with the released
-+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.
++The following areas are not yet fully defined for ARM in the 5.1 version
++of the ACPI specification and are expected to be worked through in the
++UEFI ACPI Specification Working Group (ASWG):
++
++ -- ACPI based CPU topology
++ -- ACPI based Power management
++ -- CPU idle control based on PSCI
++ -- CPU performance control (CPPC)
++ -- ACPI based SMMU
++ -- ITS support for GIC in MADT
++
++Participation in this group is open to all UEFI members. Please see
++http://www.uefi.org/workinggroup for details on group membership.
++
++It is the intent of the ARMv8 ACPI kernel code to follow the ACPI specification
++as closely as possible, and to only implement functionality that complies with
++the released standards from UEFI ASWG. As a practical matter, there will be
++vendors that provide bad ACPI tables or violate the standards in some way.
++If this is because of errors, quirks and fixups may be necessary, but will
++be avoided if possible. If there are features missing from ACPI that preclude
++it from being used on a platform, ECRs (Engineering Change Requests) should be
++submitted to ASWG and go through the normal approval process; for those that
++are not UEFI members, many other members of the Linux community are and would
++likely be willing to assist in submitting ECRs.
+diff --git a/Documentation/gpio/consumer.txt b/Documentation/gpio/consumer.txt
+index 6ce5441..859918d 100644
+--- a/Documentation/gpio/consumer.txt
++++ b/Documentation/gpio/consumer.txt
+@@ -219,6 +219,24 @@ part of the IRQ interface, e.g. IRQF_TRIGGER_FALLING, as are system wakeup
+ capabilities.
+
+
++GPIOs and ACPI
++==============
++
++On ACPI systems, GPIOs are described by GpioIo()/GpioInt() resources listed by
++the _CRS configuration objects of devices. Those resources do not provide
++connection IDs (names) for GPIOs, so it is necessary to use an additional
++mechanism for this purpose.
++
++Systems compliant with ACPI 5.1 or newer may provide a _DSD configuration object
++which, among other things, may be used to provide connection IDs for specific
++GPIOs described by the GpioIo()/GpioInt() resources in _CRS. If that is the
++case, it will be handled by the GPIO subsystem automatically. However, if the
++_DSD is not present, the mappings between GpioIo()/GpioInt() resources and GPIO
++connection IDs need to be provided by device drivers.
++
++For details refer to Documentation/acpi/gpio-properties.txt
++
++
+ Interacting With the Legacy GPIO Subsystem
+ ==========================================
+ Many kernel subsystems still handle GPIOs using the legacy integer-based
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
-index 7dbe5ec..bb69b63 100644
+index 479f332..6187d9b 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
@@ -1810,7 +2344,7 @@ index 7dbe5ec..bb69b63 100644
- acpi= [HW,ACPI,X86]
-+ acpi= [HW,ACPI,X86,ARM]
++ acpi= [HW,ACPI,X86,ARM64]
Advanced Configuration and Power Interface
Format: { force | off | strict | noirq | rsdt }
force -- enable ACPI if default was off
@@ -1818,22 +2352,157 @@ index 7dbe5ec..bb69b63 100644
strictly ACPI specification compliant.
rsdt -- prefer RSDT over (default) XSDT
copy_dsdt -- copy DSDT to memory
-+ For ARM64, ONLY "acpi=off" is available.
++ For ARM64, ONLY "acpi=off" or "acpi=force" are available
See also Documentation/power/runtime_pm.txt, pci=noacpi
+diff --git a/arch/arm/mach-s3c24xx/h1940-bluetooth.c b/arch/arm/mach-s3c24xx/h1940-bluetooth.c
+index b4d14b8..9c8b127 100644
+--- a/arch/arm/mach-s3c24xx/h1940-bluetooth.c
++++ b/arch/arm/mach-s3c24xx/h1940-bluetooth.c
+@@ -41,7 +41,7 @@ static void h1940bt_enable(int on)
+ mdelay(10);
+ gpio_set_value(S3C2410_GPH(1), 0);
+
+- h1940_led_blink_set(-EINVAL, GPIO_LED_BLINK, NULL, NULL);
++ h1940_led_blink_set(NULL, GPIO_LED_BLINK, NULL, NULL);
+ }
+ else {
+ gpio_set_value(S3C2410_GPH(1), 1);
+@@ -50,7 +50,7 @@ static void h1940bt_enable(int on)
+ mdelay(10);
+ gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 0);
+
+- h1940_led_blink_set(-EINVAL, GPIO_LED_NO_BLINK_LOW, NULL, NULL);
++ h1940_led_blink_set(NULL, GPIO_LED_NO_BLINK_LOW, NULL, NULL);
+ }
+ }
+
+diff --git a/arch/arm/mach-s3c24xx/h1940.h b/arch/arm/mach-s3c24xx/h1940.h
+index 2950cc4..596d9f6 100644
+--- a/arch/arm/mach-s3c24xx/h1940.h
++++ b/arch/arm/mach-s3c24xx/h1940.h
+@@ -19,8 +19,10 @@
+ #define H1940_SUSPEND_RESUMEAT (0x30081000)
+ #define H1940_SUSPEND_CHECK (0x30080000)
+
++struct gpio_desc;
++
+ extern void h1940_pm_return(void);
+-extern int h1940_led_blink_set(unsigned gpio, int state,
++extern int h1940_led_blink_set(struct gpio_desc *desc, int state,
+ unsigned long *delay_on,
+ unsigned long *delay_off);
+
+diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c
+index d35ddc1..d40d4f5 100644
+--- a/arch/arm/mach-s3c24xx/mach-h1940.c
++++ b/arch/arm/mach-s3c24xx/mach-h1940.c
+@@ -359,10 +359,11 @@ static struct platform_device h1940_battery = {
+
+ static DEFINE_SPINLOCK(h1940_blink_spin);
+
+-int h1940_led_blink_set(unsigned gpio, int state,
++int h1940_led_blink_set(struct gpio_desc *desc, int state,
+ unsigned long *delay_on, unsigned long *delay_off)
+ {
+ int blink_gpio, check_gpio1, check_gpio2;
++ int gpio = desc ? desc_to_gpio(desc) : -EINVAL;
+
+ switch (gpio) {
+ case H1940_LATCH_LED_GREEN:
+diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c
+index c3f2682..1d35ff3 100644
+--- a/arch/arm/mach-s3c24xx/mach-rx1950.c
++++ b/arch/arm/mach-s3c24xx/mach-rx1950.c
+@@ -250,9 +250,10 @@ static void rx1950_disable_charger(void)
+
+ static DEFINE_SPINLOCK(rx1950_blink_spin);
+
+-static int rx1950_led_blink_set(unsigned gpio, int state,
++static int rx1950_led_blink_set(struct gpio_desc *desc, int state,
+ unsigned long *delay_on, unsigned long *delay_off)
+ {
++ int gpio = desc_to_gpio(desc);
+ int blink_gpio, check_gpio;
+
+ switch (gpio) {
+diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
+index b61a3bc..b357053 100644
+--- a/arch/arm/plat-orion/gpio.c
++++ b/arch/arm/plat-orion/gpio.c
+@@ -306,9 +306,10 @@ EXPORT_SYMBOL(orion_gpio_set_blink);
+
+ #define ORION_BLINK_HALF_PERIOD 100 /* ms */
+
+-int orion_gpio_led_blink_set(unsigned gpio, int state,
++int orion_gpio_led_blink_set(struct gpio_desc *desc, int state,
+ unsigned long *delay_on, unsigned long *delay_off)
+ {
++ unsigned gpio = desc_to_gpio(desc);
+
+ if (delay_on && delay_off && !*delay_on && !*delay_off)
+ *delay_on = *delay_off = ORION_BLINK_HALF_PERIOD;
+diff --git a/arch/arm/plat-orion/include/plat/orion-gpio.h b/arch/arm/plat-orion/include/plat/orion-gpio.h
+index e763988..e856b07 100644
+--- a/arch/arm/plat-orion/include/plat/orion-gpio.h
++++ b/arch/arm/plat-orion/include/plat/orion-gpio.h
+@@ -14,12 +14,15 @@
+ #include <linux/init.h>
+ #include <linux/types.h>
+ #include <linux/irqdomain.h>
++
++struct gpio_desc;
++
+ /*
+ * Orion-specific GPIO API extensions.
+ */
+ void orion_gpio_set_unused(unsigned pin);
+ void orion_gpio_set_blink(unsigned pin, int blink);
+-int orion_gpio_led_blink_set(unsigned gpio, int state,
++int orion_gpio_led_blink_set(struct gpio_desc *desc, int state,
+ unsigned long *delay_on, unsigned long *delay_off);
+
+ #define GPIO_INPUT_OK (1 << 0)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
-index ac9afde..14423f3 100644
+index 9532f8d..80a82ac 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_BINFMT_ELF_RANDOMIZE_PIE
+@@ -4,6 +4,7 @@ config ARM64
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select ARCH_HAS_SG_CHAIN
-@@ -267,6 +268,9 @@ config SMP
+ select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
++ select ACPI_REDUCED_HARDWARE_ONLY if ACPI
+ select ARCH_USE_CMPXCHG_LOCKREF
+ select ARCH_SUPPORTS_ATOMIC_RMW
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+@@ -34,6 +35,7 @@ config ARM64
+ select GENERIC_TIME_VSYSCALL
+ select HANDLE_DOMAIN_IRQ
+ select HARDIRQS_SW_RESEND
++ select HAVE_ALIGNED_STRUCT_PAGE if SLUB
+ select HAVE_ARCH_AUDITSYSCALL
+ select HAVE_ARCH_JUMP_LABEL
+ select HAVE_ARCH_KGDB
+@@ -41,6 +43,7 @@ config ARM64
+ select HAVE_BPF_JIT
+ select HAVE_C_RECORDMCOUNT
+ select HAVE_CC_STACKPROTECTOR
++ select HAVE_CMPXCHG_DOUBLE
+ select HAVE_DEBUG_BUGVERBOSE
+ select HAVE_DEBUG_KMEMLEAK
+ select HAVE_DMA_API_DEBUG
+@@ -185,6 +188,9 @@ config PCI_DOMAINS_GENERIC
+ config PCI_SYSCALL
+ def_bool PCI
+
++config PCI_MMCONFIG
++ def_bool y if PCI && ACPI
++
+ source "drivers/pci/Kconfig"
+ source "drivers/pci/pcie/Kconfig"
+ source "drivers/pci/hotplug/Kconfig"
+@@ -268,6 +274,9 @@ config SMP
If you don't know what to do here, say N.
@@ -1843,7 +2512,25 @@ index ac9afde..14423f3 100644
config SCHED_MC
bool "Multi-core scheduler support"
depends on SMP
-@@ -453,6 +457,8 @@ source "drivers/Kconfig"
+@@ -401,6 +410,17 @@ config EFI
+ allow the kernel to be booted as an EFI application. This
+ is only useful on systems that have UEFI firmware.
+
++config DMI
++ bool "Enable support for SMBIOS (DMI) tables"
++ depends on EFI
++ default y
++ help
++ This enables SMBIOS/DMI feature for systems.
++
++ This option is only useful on systems that have UEFI firmware.
++ However, even with this option, the resultant kernel should
++ continue to boot on existing non-UEFI platforms.
++
+ endmenu
+
+ menu "Userspace binary formats"
+@@ -454,6 +474,8 @@ source "drivers/Kconfig"
source "drivers/firmware/Kconfig"
@@ -1864,6 +2551,271 @@ index 20901ff..983d72a 100644
libs-y := arch/arm64/lib/ $(libs-y)
libs-y += $(LIBGCC)
libs-$(CONFIG_EFI_STUB) += drivers/firmware/efi/libstub/
+diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
+index 5562652..a38b02c 100644
+--- a/arch/arm64/crypto/Kconfig
++++ b/arch/arm64/crypto/Kconfig
+@@ -27,20 +27,19 @@ config CRYPTO_AES_ARM64_CE
+ tristate "AES core cipher using ARMv8 Crypto Extensions"
+ depends on ARM64 && KERNEL_MODE_NEON
+ select CRYPTO_ALGAPI
+- select CRYPTO_AES
+
+ config CRYPTO_AES_ARM64_CE_CCM
+ tristate "AES in CCM mode using ARMv8 Crypto Extensions"
+ depends on ARM64 && KERNEL_MODE_NEON
+ select CRYPTO_ALGAPI
+- select CRYPTO_AES
++ select CRYPTO_AES_ARM64_CE
+ select CRYPTO_AEAD
+
+ config CRYPTO_AES_ARM64_CE_BLK
+ tristate "AES in ECB/CBC/CTR/XTS modes using ARMv8 Crypto Extensions"
+ depends on ARM64 && KERNEL_MODE_NEON
+ select CRYPTO_BLKCIPHER
+- select CRYPTO_AES
++ select CRYPTO_AES_ARM64_CE
+ select CRYPTO_ABLK_HELPER
+
+ config CRYPTO_AES_ARM64_NEON_BLK
+diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c
+index 9e6cdde..0ac73b8 100644
+--- a/arch/arm64/crypto/aes-ce-ccm-glue.c
++++ b/arch/arm64/crypto/aes-ce-ccm-glue.c
+@@ -16,6 +16,8 @@
+ #include <linux/crypto.h>
+ #include <linux/module.h>
+
++#include "aes-ce-setkey.h"
++
+ static int num_rounds(struct crypto_aes_ctx *ctx)
+ {
+ /*
+@@ -48,7 +50,7 @@ static int ccm_setkey(struct crypto_aead *tfm, const u8 *in_key,
+ struct crypto_aes_ctx *ctx = crypto_aead_ctx(tfm);
+ int ret;
+
+- ret = crypto_aes_expand_key(ctx, in_key, key_len);
++ ret = ce_aes_expandkey(ctx, in_key, key_len);
+ if (!ret)
+ return 0;
+
+diff --git a/arch/arm64/crypto/aes-ce-cipher.c b/arch/arm64/crypto/aes-ce-cipher.c
+index 2075e1a..ce47792 100644
+--- a/arch/arm64/crypto/aes-ce-cipher.c
++++ b/arch/arm64/crypto/aes-ce-cipher.c
+@@ -14,6 +14,8 @@
+ #include <linux/crypto.h>
+ #include <linux/module.h>
+
++#include "aes-ce-setkey.h"
++
+ MODULE_DESCRIPTION("Synchronous AES cipher using ARMv8 Crypto Extensions");
+ MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+ MODULE_LICENSE("GPL v2");
+@@ -124,6 +126,114 @@ static void aes_cipher_decrypt(struct crypto_tfm *tfm, u8 dst[], u8 const src[])
+ kernel_neon_end();
+ }
+
++/*
++ * aes_sub() - use the aese instruction to perform the AES sbox substitution
++ * on each byte in 'input'
++ */
++static u32 aes_sub(u32 input)
++{
++ u32 ret;
++
++ __asm__("dup v1.4s, %w[in] ;"
++ "movi v0.16b, #0 ;"
++ "aese v0.16b, v1.16b ;"
++ "umov %w[out], v0.4s[0] ;"
++
++ : [out] "=r"(ret)
++ : [in] "r"(input)
++ : "v0","v1");
++
++ return ret;
++}
++
++int ce_aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key,
++ unsigned int key_len)
++{
++ /*
++ * The AES key schedule round constants
++ */
++ static u8 const rcon[] = {
++ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36,
++ };
++
++ u32 kwords = key_len / sizeof(u32);
++ struct aes_block *key_enc, *key_dec;
++ int i, j;
++
++ if (key_len != AES_KEYSIZE_128 &&
++ key_len != AES_KEYSIZE_192 &&
++ key_len != AES_KEYSIZE_256)
++ return -EINVAL;
++
++ memcpy(ctx->key_enc, in_key, key_len);
++ ctx->key_length = key_len;
++
++ kernel_neon_begin_partial(2);
++ for (i = 0; i < sizeof(rcon); i++) {
++ u32 *rki = ctx->key_enc + (i * kwords);
++ u32 *rko = rki + kwords;
++
++ rko[0] = ror32(aes_sub(rki[kwords - 1]), 8) ^ rcon[i] ^ rki[0];
++ rko[1] = rko[0] ^ rki[1];
++ rko[2] = rko[1] ^ rki[2];
++ rko[3] = rko[2] ^ rki[3];
++
++ if (key_len == AES_KEYSIZE_192) {
++ if (i >= 7)
++ break;
++ rko[4] = rko[3] ^ rki[4];
++ rko[5] = rko[4] ^ rki[5];
++ } else if (key_len == AES_KEYSIZE_256) {
++ if (i >= 6)
++ break;
++ rko[4] = aes_sub(rko[3]) ^ rki[4];
++ rko[5] = rko[4] ^ rki[5];
++ rko[6] = rko[5] ^ rki[6];
++ rko[7] = rko[6] ^ rki[7];
++ }
++ }
++
++ /*
++ * Generate the decryption keys for the Equivalent Inverse Cipher.
++ * This involves reversing the order of the round keys, and applying
++ * the Inverse Mix Columns transformation on all but the first and
++ * the last one.
++ */
++ key_enc = (struct aes_block *)ctx->key_enc;
++ key_dec = (struct aes_block *)ctx->key_dec;
++ j = num_rounds(ctx);
++
++ key_dec[0] = key_enc[j];
++ for (i = 1, j--; j > 0; i++, j--)
++ __asm__("ld1 {v0.16b}, %[in] ;"
++ "aesimc v1.16b, v0.16b ;"
++ "st1 {v1.16b}, %[out] ;"
++
++ : [out] "=Q"(key_dec[i])
++ : [in] "Q"(key_enc[j])
++ : "v0","v1");
++ key_dec[i] = key_enc[0];
++
++ kernel_neon_end();
++ return 0;
++}
++EXPORT_SYMBOL(ce_aes_expandkey);
++
++int ce_aes_setkey(struct crypto_tfm *tfm, const u8 *in_key,
++ unsigned int key_len)
++{
++ struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
++ int ret;
++
++ ret = ce_aes_expandkey(ctx, in_key, key_len);
++ if (!ret)
++ return 0;
++
++ tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
++ return -EINVAL;
++}
++EXPORT_SYMBOL(ce_aes_setkey);
++
+ static struct crypto_alg aes_alg = {
+ .cra_name = "aes",
+ .cra_driver_name = "aes-ce",
+@@ -135,7 +245,7 @@ static struct crypto_alg aes_alg = {
+ .cra_cipher = {
+ .cia_min_keysize = AES_MIN_KEY_SIZE,
+ .cia_max_keysize = AES_MAX_KEY_SIZE,
+- .cia_setkey = crypto_aes_set_key,
++ .cia_setkey = ce_aes_setkey,
+ .cia_encrypt = aes_cipher_encrypt,
+ .cia_decrypt = aes_cipher_decrypt
+ }
+diff --git a/arch/arm64/crypto/aes-ce-setkey.h b/arch/arm64/crypto/aes-ce-setkey.h
+new file mode 100644
+index 0000000..f08a647
+--- /dev/null
++++ b/arch/arm64/crypto/aes-ce-setkey.h
+@@ -0,0 +1,5 @@
++
++int ce_aes_setkey(struct crypto_tfm *tfm, const u8 *in_key,
++ unsigned int key_len);
++int ce_aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key,
++ unsigned int key_len);
+diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c
+index 79cd911..801aae3 100644
+--- a/arch/arm64/crypto/aes-glue.c
++++ b/arch/arm64/crypto/aes-glue.c
+@@ -16,9 +16,13 @@
+ #include <linux/module.h>
+ #include <linux/cpufeature.h>
+
++#include "aes-ce-setkey.h"
++
+ #ifdef USE_V8_CRYPTO_EXTENSIONS
+ #define MODE "ce"
+ #define PRIO 300
++#define aes_setkey ce_aes_setkey
++#define aes_expandkey ce_aes_expandkey
+ #define aes_ecb_encrypt ce_aes_ecb_encrypt
+ #define aes_ecb_decrypt ce_aes_ecb_decrypt
+ #define aes_cbc_encrypt ce_aes_cbc_encrypt
+@@ -30,6 +34,8 @@ MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 Crypto Extensions");
+ #else
+ #define MODE "neon"
+ #define PRIO 200
++#define aes_setkey crypto_aes_set_key
++#define aes_expandkey crypto_aes_expand_key
+ #define aes_ecb_encrypt neon_aes_ecb_encrypt
+ #define aes_ecb_decrypt neon_aes_ecb_decrypt
+ #define aes_cbc_encrypt neon_aes_cbc_encrypt
+@@ -79,10 +85,10 @@ static int xts_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
+ int ret;
+
+- ret = crypto_aes_expand_key(&ctx->key1, in_key, key_len / 2);
++ ret = aes_expandkey(&ctx->key1, in_key, key_len / 2);
+ if (!ret)
+- ret = crypto_aes_expand_key(&ctx->key2, &in_key[key_len / 2],
+- key_len / 2);
++ ret = aes_expandkey(&ctx->key2, &in_key[key_len / 2],
++ key_len / 2);
+ if (!ret)
+ return 0;
+
+@@ -288,7 +294,7 @@ static struct crypto_alg aes_algs[] = { {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+- .setkey = crypto_aes_set_key,
++ .setkey = aes_setkey,
+ .encrypt = ecb_encrypt,
+ .decrypt = ecb_decrypt,
+ },
+@@ -306,7 +312,7 @@ static struct crypto_alg aes_algs[] = { {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+- .setkey = crypto_aes_set_key,
++ .setkey = aes_setkey,
+ .encrypt = cbc_encrypt,
+ .decrypt = cbc_decrypt,
+ },
+@@ -324,7 +330,7 @@ static struct crypto_alg aes_algs[] = { {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+- .setkey = crypto_aes_set_key,
++ .setkey = aes_setkey,
+ .encrypt = ctr_encrypt,
+ .decrypt = ctr_encrypt,
+ },
diff --git a/arch/arm64/include/asm/acenv.h b/arch/arm64/include/asm/acenv.h
new file mode 100644
index 0000000..b49166f
@@ -1890,10 +2842,10 @@ index 0000000..b49166f
+#endif /* _ASM_ACENV_H */
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
new file mode 100644
-index 0000000..7f6cd91
+index 0000000..6e692f4
--- /dev/null
+++ b/arch/arm64/include/asm/acpi.h
-@@ -0,0 +1,99 @@
+@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2013-2014, Linaro Ltd.
+ * Author: Al Stone <al.stone@linaro.org>
@@ -1936,23 +2888,27 @@ index 0000000..7f6cd91
+ acpi_noirq = 1;
+}
+
-+/* MPIDR value provided in GICC structure is 64 bits, but
-+ * the acpi processor driver use the 32 bits cpu hardware
-+ * ID (apic_id on intel platform) everywhere, it is pretty
-+ * hard to modify the acpi processor driver to accept the
-+ * 64 bits MPIDR value, at the same time, only 32 bits of
-+ * the MPIDR is used in the 64 bits MPIDR, just pack the
-+ * Affx fields into a single 32 bit identifier to accommodate
-+ * the acpi processor drivers.
++static inline void enable_acpi(void)
++{
++ acpi_disabled = 0;
++ acpi_pci_disabled = 0;
++ acpi_noirq = 0;
++}
++
++/* MPIDR value provided in GICC structure is 64 bits, but the
++ * existing apic_id (CPU hardware ID) using in acpi processor
++ * driver is 32-bit, to conform to the same datatype we need
++ * to repack the GICC structure MPIDR.
++ *
++ * Only 32 bits of MPIDR are used:
++ *
++ * Bits [0:7] Aff0;
++ * Bits [8:15] Aff1;
++ * Bits [16:23] Aff2;
++ * Bits [32:39] Aff3;
+ */
-+static inline u32 pack_mpidr_into_32_bits(u64 mpidr)
++static inline u32 pack_mpidr(u64 mpidr)
+{
-+ /*
-+ * Bits [0:7] Aff0;
-+ * Bits [8:15] Aff1;
-+ * Bits [16:23] Aff2;
-+ * Bits [32:39] Aff3;
-+ */
+ return (u32) ((mpidr & 0xff00000000) >> 8) | mpidr;
+}
+
@@ -1964,7 +2920,7 @@ index 0000000..7f6cd91
+ * cpu_logical_map(cpu) is the mapping of MPIDR and the logical cpu,
+ * and MPIDR is the cpu hardware ID we needed to pack.
+ */
-+#define cpu_physical_id(cpu) pack_mpidr_into_32_bits(cpu_logical_map(cpu))
++#define cpu_physical_id(cpu) pack_mpidr(cpu_logical_map(cpu))
+
+/*
+ * It's used from ACPI core in kdump to boot UP system with SMP kernel,
@@ -1984,15 +2940,110 @@ index 0000000..7f6cd91
+extern int acpi_get_cpu_parked_address(int cpu, u64 *addr);
+
+#else
-+
++static inline void disable_acpi(void) { }
+static inline bool acpi_psci_present(void) { return false; }
+static inline bool acpi_psci_use_hvc(void) { return false; }
+static inline void acpi_smp_init_cpus(void) { }
+static inline int acpi_get_cpu_parked_address(int cpu, u64 *addr) { return -EOPNOTSUPP; }
-+
+#endif /* CONFIG_ACPI */
+
+#endif /*_ASM_ACPI_H*/
+diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
+index ddb9d78..89e397b 100644
+--- a/arch/arm64/include/asm/cmpxchg.h
++++ b/arch/arm64/include/asm/cmpxchg.h
+@@ -19,6 +19,7 @@
+ #define __ASM_CMPXCHG_H
+
+ #include <linux/bug.h>
++#include <linux/mmdebug.h>
+
+ #include <asm/barrier.h>
+
+@@ -152,6 +153,51 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+ return oldval;
+ }
+
++#define system_has_cmpxchg_double() 1
++
++static inline int __cmpxchg_double(volatile void *ptr1, volatile void *ptr2,
++ unsigned long old1, unsigned long old2,
++ unsigned long new1, unsigned long new2, int size)
++{
++ unsigned long loop, lost;
++
++ switch (size) {
++ case 8:
++ VM_BUG_ON((unsigned long *)ptr2 - (unsigned long *)ptr1 != 1);
++ do {
++ asm volatile("// __cmpxchg_double8\n"
++ " ldxp %0, %1, %2\n"
++ " eor %0, %0, %3\n"
++ " eor %1, %1, %4\n"
++ " orr %1, %0, %1\n"
++ " mov %w0, #0\n"
++ " cbnz %1, 1f\n"
++ " stxp %w0, %5, %6, %2\n"
++ "1:\n"
++ : "=&r"(loop), "=&r"(lost), "+Q" (*(u64 *)ptr1)
++ : "r" (old1), "r"(old2), "r"(new1), "r"(new2));
++ } while (loop);
++ break;
++ default:
++ BUILD_BUG();
++ }
++
++ return !lost;
++}
++
++static inline int __cmpxchg_double_mb(volatile void *ptr1, volatile void *ptr2,
++ unsigned long old1, unsigned long old2,
++ unsigned long new1, unsigned long new2, int size)
++{
++ int ret;
++
++ smp_mb();
++ ret = __cmpxchg_double(ptr1, ptr2, old1, old2, new1, new2, size);
++ smp_mb();
++
++ return ret;
++}
++
+ static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+ {
+@@ -182,6 +228,31 @@ static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
+ __ret; \
+ })
+
++#define cmpxchg_double(ptr1, ptr2, o1, o2, n1, n2) \
++({\
++ int __ret;\
++ __ret = __cmpxchg_double_mb((ptr1), (ptr2), (unsigned long)(o1), \
++ (unsigned long)(o2), (unsigned long)(n1), \
++ (unsigned long)(n2), sizeof(*(ptr1)));\
++ __ret; \
++})
++
++#define cmpxchg_double_local(ptr1, ptr2, o1, o2, n1, n2) \
++({\
++ int __ret;\
++ __ret = __cmpxchg_double((ptr1), (ptr2), (unsigned long)(o1), \
++ (unsigned long)(o2), (unsigned long)(n1), \
++ (unsigned long)(n2), sizeof(*(ptr1)));\
++ __ret; \
++})
++
++#define this_cpu_cmpxchg_8(ptr, o, n) \
++ cmpxchg_local(raw_cpu_ptr(&(ptr)), o, n)
++
++#define this_cpu_cmpxchg_double_8(ptr1, ptr2, o1, o2, n1, n2) \
++ cmpxchg_double_local(raw_cpu_ptr(&(ptr1)), raw_cpu_ptr(&(ptr2)), \
++ o1, o2, n1, n2)
++
+ #define cmpxchg64(ptr,o,n) cmpxchg((ptr),(o),(n))
+ #define cmpxchg64_local(ptr,o,n) cmpxchg_local((ptr),(o),(n))
+
diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
index 6f8e2ef..978f567 100644
--- a/arch/arm64/include/asm/cpu_ops.h
@@ -2005,8 +3056,45 @@ index 6f8e2ef..978f567 100644
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/dmi.h b/arch/arm64/include/asm/dmi.h
+new file mode 100644
+index 0000000..69d37d8
+--- /dev/null
++++ b/arch/arm64/include/asm/dmi.h
+@@ -0,0 +1,31 @@
++/*
++ * arch/arm64/include/asm/dmi.h
++ *
++ * Copyright (C) 2013 Linaro Limited.
++ * Written by: Yi Li (yi.li@linaro.org)
++ *
++ * based on arch/ia64/include/asm/dmi.h
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file "COPYING" in the main directory of this archive
++ * for more details.
++ */
++
++#ifndef __ASM_DMI_H
++#define __ASM_DMI_H
++
++#include <linux/io.h>
++#include <linux/slab.h>
++
++/*
++ * According to section 2.3.6 of the UEFI spec, the firmware should not
++ * request a virtual mapping for configuration tables such as SMBIOS.
++ * This means we have to map them before use.
++ */
++#define dmi_early_remap(x, l) ioremap_cache(x, l)
++#define dmi_early_unmap(x, l) iounmap(x)
++#define dmi_remap(x, l) ioremap_cache(x, l)
++#define dmi_unmap(x) iounmap(x)
++#define dmi_alloc(l) kzalloc(l, GFP_KERNEL)
++
++#endif
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
-index 01d3aab..8186df6 100644
+index 1f65be3..c0f89a0 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -114,7 +114,8 @@ typedef struct user_fpsimd_state elf_fpregset_t;
@@ -2019,6 +3107,130 @@ index 01d3aab..8186df6 100644
#define CORE_DUMP_USE_REGSET
#define ELF_EXEC_PAGESIZE PAGE_SIZE
+diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
+index 7fd3e27..8afb863 100644
+--- a/arch/arm64/include/asm/kvm_arm.h
++++ b/arch/arm64/include/asm/kvm_arm.h
+@@ -18,6 +18,7 @@
+ #ifndef __ARM64_KVM_ARM_H__
+ #define __ARM64_KVM_ARM_H__
+
++#include <asm/memory.h>
+ #include <asm/types.h>
+
+ /* Hyp Configuration Register (HCR) bits */
+@@ -160,9 +161,9 @@
+ #endif
+
+ #define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
+-#define VTTBR_BADDR_MASK (((1LLU << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
+-#define VTTBR_VMID_SHIFT (48LLU)
+-#define VTTBR_VMID_MASK (0xffLLU << VTTBR_VMID_SHIFT)
++#define VTTBR_BADDR_MASK (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
++#define VTTBR_VMID_SHIFT (UL(48))
++#define VTTBR_VMID_MASK (UL(0xFF) << VTTBR_VMID_SHIFT)
+
+ /* Hyp System Trap Register */
+ #define HSTR_EL2_TTEE (1 << 16)
+@@ -185,13 +186,13 @@
+
+ /* Exception Syndrome Register (ESR) bits */
+ #define ESR_EL2_EC_SHIFT (26)
+-#define ESR_EL2_EC (0x3fU << ESR_EL2_EC_SHIFT)
+-#define ESR_EL2_IL (1U << 25)
++#define ESR_EL2_EC (UL(0x3f) << ESR_EL2_EC_SHIFT)
++#define ESR_EL2_IL (UL(1) << 25)
+ #define ESR_EL2_ISS (ESR_EL2_IL - 1)
+ #define ESR_EL2_ISV_SHIFT (24)
+-#define ESR_EL2_ISV (1U << ESR_EL2_ISV_SHIFT)
++#define ESR_EL2_ISV (UL(1) << ESR_EL2_ISV_SHIFT)
+ #define ESR_EL2_SAS_SHIFT (22)
+-#define ESR_EL2_SAS (3U << ESR_EL2_SAS_SHIFT)
++#define ESR_EL2_SAS (UL(3) << ESR_EL2_SAS_SHIFT)
+ #define ESR_EL2_SSE (1 << 21)
+ #define ESR_EL2_SRT_SHIFT (16)
+ #define ESR_EL2_SRT_MASK (0x1f << ESR_EL2_SRT_SHIFT)
+@@ -205,16 +206,16 @@
+ #define ESR_EL2_FSC_TYPE (0x3c)
+
+ #define ESR_EL2_CV_SHIFT (24)
+-#define ESR_EL2_CV (1U << ESR_EL2_CV_SHIFT)
++#define ESR_EL2_CV (UL(1) << ESR_EL2_CV_SHIFT)
+ #define ESR_EL2_COND_SHIFT (20)
+-#define ESR_EL2_COND (0xfU << ESR_EL2_COND_SHIFT)
++#define ESR_EL2_COND (UL(0xf) << ESR_EL2_COND_SHIFT)
+
+
+ #define FSC_FAULT (0x04)
+ #define FSC_PERM (0x0c)
+
+ /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
+-#define HPFAR_MASK (~0xFUL)
++#define HPFAR_MASK (~UL(0xf))
+
+ #define ESR_EL2_EC_UNKNOWN (0x00)
+ #define ESR_EL2_EC_WFI (0x01)
+diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
+index 872ba93..2f287a6 100644
+--- a/arch/arm64/include/asm/pci.h
++++ b/arch/arm64/include/asm/pci.h
+@@ -33,5 +33,56 @@ static inline int pci_proc_domain(struct pci_bus *bus)
+ }
+ #endif /* CONFIG_PCI */
+
++/* "PCI MMCONFIG %04x [bus %02x-%02x]" */
++#define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2)
++
++#define PCI_MMCFG_BUS_OFFSET(bus) ((bus) << 20)
++
++struct acpi_device;
++
++struct pci_sysdata {
++ int domain; /* PCI domain */
++ int node; /* NUMA node */
++ struct acpi_device *companion; /* ACPI companion device */
++ void *iommu; /* IOMMU private data */
++};
++
++struct acpi_pci_root;
++struct pci_mmcfg_region;
++
++typedef int (*acpi_mcfg_fixup_t)(struct acpi_pci_root *root,
++ struct pci_mmcfg_region *cfg);
++
++struct pci_mmcfg_region {
++ struct list_head list;
++ struct resource res;
++ int (*read)(struct pci_mmcfg_region *cfg, unsigned int bus,
++ unsigned int devfn, int reg, int len, u32 *value);
++ int (*write)(struct pci_mmcfg_region *cfg, unsigned int bus,
++ unsigned int devfn, int reg, int len, u32 value);
++ acpi_mcfg_fixup_t fixup;
++ void *data;
++ u64 address;
++ char __iomem *virt;
++ u16 segment;
++ u8 start_bus;
++ u8 end_bus;
++ char name[PCI_MMCFG_RESOURCE_NAME_LEN];
++};
++
++struct acpi_mcfg_fixup {
++ char oem_id[7];
++ char oem_table_id[9];
++ acpi_mcfg_fixup_t hook;
++};
++
++/* Designate a routine to fix up buggy MCFG */
++#define DECLARE_ACPI_MCFG_FIXUP(oem_id, table_id, hook) \
++ static const struct acpi_mcfg_fixup __acpi_fixup_##hook __used \
++ __attribute__((__section__(".acpi_fixup_mcfg"), aligned((sizeof(void *))))) \
++ = { {oem_id}, {table_id}, hook };
++
++extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
++
+ #endif /* __KERNEL__ */
+ #endif /* __ASM_PCI_H */
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
@@ -2085,10 +3297,10 @@ index 5bd029b..f4ba4fe 100644
obj-m += $(arm64-obj-m)
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
new file mode 100644
-index 0000000..5486426
+index 0000000..06a96be
--- /dev/null
+++ b/arch/arm64/kernel/acpi.c
-@@ -0,0 +1,397 @@
+@@ -0,0 +1,398 @@
+/*
+ * ARM64 Specific Low-Level ACPI Boot Support
+ *
@@ -2119,10 +3331,8 @@ index 0000000..5486426
+#include <asm/cputype.h>
+#include <asm/cpu_ops.h>
+
-+#define ARM64_ACPI_DISABLED_DEFAULT 1
-+
+int acpi_noirq; /* skip ACPI IRQ initialization */
-+int acpi_disabled = ARM64_ACPI_DISABLED_DEFAULT;
++int acpi_disabled;
+EXPORT_SYMBOL(acpi_disabled);
+
+int acpi_pci_disabled; /* skip ACPI PCI scan and IRQ initialization */
@@ -2172,7 +3382,7 @@ index 0000000..5486426
+ int cpu;
+
+ if (mpidr == INVALID_HWID) {
-+ pr_info("Skip invalid cpu hardware ID\n");
++ pr_info("Skip MADT cpu entry with invalid MPIDR\n");
+ return -EINVAL;
+ }
+
@@ -2196,7 +3406,7 @@ index 0000000..5486426
+ for_each_possible_cpu(cpu) {
+ if (cpu_logical_map(cpu) == mpidr) {
+ pr_err("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n",
-+ mpidr);
++ mpidr);
+ return -EINVAL;
+ }
+ }
@@ -2204,7 +3414,10 @@ index 0000000..5486426
+ /* allocate a logical cpu id for the new comer */
+ cpu = cpumask_next_zero(-1, cpu_possible_mask);
+ } else {
-+ /* First GICC entry must be BSP as ACPI spec said */
++ /*
++ * First GICC entry must be BSP as ACPI spec said
++ * in section 5.2.12.15
++ */
+ if (cpu_logical_map(0) != mpidr) {
+ pr_err("First GICC entry with MPIDR 0x%llx is not BSP\n",
+ mpidr);
@@ -2360,7 +3573,7 @@ index 0000000..5486426
+ /*
+ * Revision in table header is the FADT Major revision,
+ * and there is a minor revision of FADT which was introduced
-+ * by ACPI 5.1, we only deal with ACPI 5.1 or higher revision
++ * by ACPI 5.1, we only deal with ACPI 5.1 or newer revision
+ * to get arm boot flags, or we will disable ACPI.
+ */
+ if (table->revision > 5 ||
@@ -2378,7 +3591,7 @@ index 0000000..5486426
+ boot_method = "parking-protocol";
+
+ if (!boot_method)
-+ pr_warn("has no boot support, will not bring up secondary CPUs\n");
++ pr_warn("No boot method, will not bring up secondary CPUs\n");
+ return -EOPNOTSUPP;
+ }
+
@@ -2457,9 +3670,9 @@ index 0000000..5486426
+
+ /* "acpi=off" disables both ACPI table parsing and interpreter */
+ if (strcmp(arg, "off") == 0)
-+ acpi_disabled = 1;
-+ else if (strcmp(arg, "on") == 0)
-+ acpi_disabled = 0;
++ disable_acpi();
++ else if (strcmp(arg, "force") == 0) /* force ACPI to be enabled */
++ enable_acpi();
+ else
+ return -EINVAL; /* Core will print when we return error */
+
@@ -2516,51 +3729,456 @@ index cce9524..1d90f31 100644
{
const struct cpu_operations **ops = supported_cpu_ops;
+diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S
+index 619b1dd..a0016d3 100644
+--- a/arch/arm64/kernel/efi-entry.S
++++ b/arch/arm64/kernel/efi-entry.S
+@@ -61,7 +61,8 @@ ENTRY(efi_stub_entry)
+ */
+ mov x20, x0 // DTB address
+ ldr x0, [sp, #16] // relocated _text address
+- mov x21, x0
++ ldr x21, =stext_offset
++ add x21, x0, x21
+
+ /*
+ * Flush dcache covering current runtime addresses
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
-index 03aaa99..6c4de44 100644
+index 95c49eb..f9de195 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
-@@ -479,3 +479,14 @@ err_unmap:
+@@ -11,6 +11,7 @@
+ *
+ */
+
++#include <linux/dmi.h>
+ #include <linux/efi.h>
+ #include <linux/export.h>
+ #include <linux/memblock.h>
+@@ -112,8 +113,6 @@ static int __init uefi_init(void)
+ efi.systab->hdr.revision & 0xffff, vendor);
+
+ retval = efi_config_init(NULL);
+- if (retval == 0)
+- set_bit(EFI_CONFIG_TABLES, &efi.flags);
+
+ out:
+ early_memunmap(efi.systab, sizeof(efi_system_table_t));
+@@ -125,17 +124,17 @@ out:
+ */
+ static __init int is_reserve_region(efi_memory_desc_t *md)
+ {
+- if (!is_normal_ram(md))
++ switch (md->type) {
++ case EFI_LOADER_CODE:
++ case EFI_LOADER_DATA:
++ case EFI_BOOT_SERVICES_CODE:
++ case EFI_BOOT_SERVICES_DATA:
++ case EFI_CONVENTIONAL_MEMORY:
+ return 0;
+-
+- if (md->attribute & EFI_MEMORY_RUNTIME)
+- return 1;
+-
+- if (md->type == EFI_ACPI_RECLAIM_MEMORY ||
+- md->type == EFI_RESERVED_TYPE)
+- return 1;
+-
+- return 0;
++ default:
++ break;
++ }
++ return is_normal_ram(md);
+ }
+
+ static __init void reserve_regions(void)
+@@ -471,3 +470,54 @@ err_unmap:
return -1;
}
early_initcall(arm64_enter_virtual_mode);
+
++static int __init arm64_dmi_init(void)
++{
++ /*
++ * On arm64, DMI depends on UEFI, and dmi_scan_machine() needs to
++ * be called early because dmi_id_init(), which is an arch_initcall
++ * itself, depends on dmi_scan_machine() having been called already.
++ */
++ dmi_scan_machine();
++ if (dmi_available)
++ dmi_set_dump_stack_arch_desc();
++ return 0;
++}
++core_initcall(arm64_dmi_init);
++
+/*
+ * If nothing else is handling pm_power_off, use EFI
+ *
-+ * This is called from a late_initcall after other mechanisms
-+ * have had a chance to register a handler.
++ * When Guenter Roeck's power-off handler call chain patches land,
++ * we just need to return true unconditionally.
+ */
+bool efi_poweroff_required(void)
+{
+ return pm_power_off == NULL;
+}
-diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
-index c3065db..99edd1f 100644
---- a/arch/arm64/kernel/process.c
-+++ b/arch/arm64/kernel/process.c
-@@ -43,6 +43,7 @@
- #include <linux/hw_breakpoint.h>
- #include <linux/personality.h>
- #include <linux/notifier.h>
-+#include <linux/efi.h>
-
- #include <asm/compat.h>
- #include <asm/cacheflush.h>
-@@ -157,6 +158,11 @@ void machine_restart(char *cmd)
- do_kernel_restart(cmd);
-
- /*
-+ * If all else fails, try EFI
-+ */
++
++static int arm64_efi_restart(struct notifier_block *this,
++ unsigned long mode, void *cmd)
++{
+ efi_reboot(reboot_mode, cmd);
++ return NOTIFY_DONE;
++}
++
++static struct notifier_block arm64_efi_restart_nb = {
++ .notifier_call = arm64_efi_restart,
++ .priority = INT_MAX,
++};
++
++static int __init arm64_register_efi_restart(void)
++{
++ int ret = 0;
++
++ if (efi_enabled(EFI_RUNTIME_SERVICES)) {
++ ret = register_restart_handler(&arm64_efi_restart_nb);
++ if (ret)
++ pr_err("%s: cannot register restart handler, %d\n",
++ __func__, ret);
++ }
++ return ret;
++}
++late_initcall(arm64_register_efi_restart);
+diff --git a/arch/arm64/kernel/entry-ftrace.S b/arch/arm64/kernel/entry-ftrace.S
+index 38e704e..08cafc5 100644
+--- a/arch/arm64/kernel/entry-ftrace.S
++++ b/arch/arm64/kernel/entry-ftrace.S
+@@ -98,8 +98,8 @@
+ ENTRY(_mcount)
+ mcount_enter
+
+- ldr x0, =ftrace_trace_function
+- ldr x2, [x0]
++ adrp x0, ftrace_trace_function
++ ldr x2, [x0, #:lo12:ftrace_trace_function]
+ adr x0, ftrace_stub
+ cmp x0, x2 // if (ftrace_trace_function
+ b.eq skip_ftrace_call // != ftrace_stub) {
+@@ -115,14 +115,15 @@ skip_ftrace_call: // return;
+ mcount_exit // return;
+ // }
+ skip_ftrace_call:
+- ldr x1, =ftrace_graph_return
+- ldr x2, [x1] // if ((ftrace_graph_return
+- cmp x0, x2 // != ftrace_stub)
+- b.ne ftrace_graph_caller
+-
+- ldr x1, =ftrace_graph_entry // || (ftrace_graph_entry
+- ldr x2, [x1] // != ftrace_graph_entry_stub))
+- ldr x0, =ftrace_graph_entry_stub
++ adrp x1, ftrace_graph_return
++ ldr x2, [x1, #:lo12:ftrace_graph_return]
++ cmp x0, x2 // if ((ftrace_graph_return
++ b.ne ftrace_graph_caller // != ftrace_stub)
++
++ adrp x1, ftrace_graph_entry // || (ftrace_graph_entry
++ adrp x0, ftrace_graph_entry_stub // != ftrace_graph_entry_stub))
++ ldr x2, [x1, #:lo12:ftrace_graph_entry]
++ add x0, x0, #:lo12:ftrace_graph_entry_stub
+ cmp x0, x2
+ b.ne ftrace_graph_caller // ftrace_graph_caller();
+
+diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
+index 0a6e4f9..5a76e3a 100644
+--- a/arch/arm64/kernel/head.S
++++ b/arch/arm64/kernel/head.S
+@@ -132,6 +132,8 @@ efi_head:
+ #endif
+
+ #ifdef CONFIG_EFI
++ .globl stext_offset
++ .set stext_offset, stext - efi_head
+ .align 3
+ pe_header:
+ .ascii "PE"
+@@ -155,12 +157,12 @@ optional_header:
+ .long 0 // SizeOfInitializedData
+ .long 0 // SizeOfUninitializedData
+ .long efi_stub_entry - efi_head // AddressOfEntryPoint
+- .long stext - efi_head // BaseOfCode
++ .long stext_offset // BaseOfCode
+
+ extra_header_fields:
+ .quad 0 // ImageBase
+- .long 0x20 // SectionAlignment
+- .long 0x8 // FileAlignment
++ .long 0x1000 // SectionAlignment
++ .long PECOFF_FILE_ALIGNMENT // FileAlignment
+ .short 0 // MajorOperatingSystemVersion
+ .short 0 // MinorOperatingSystemVersion
+ .short 0 // MajorImageVersion
+@@ -172,7 +174,7 @@ extra_header_fields:
+ .long _end - efi_head // SizeOfImage
+
+ // Everything before the kernel image is considered part of the header
+- .long stext - efi_head // SizeOfHeaders
++ .long stext_offset // SizeOfHeaders
+ .long 0 // CheckSum
+ .short 0xa // Subsystem (EFI application)
+ .short 0 // DllCharacteristics
+@@ -217,16 +219,24 @@ section_table:
+ .byte 0
+ .byte 0 // end of 0 padding of section name
+ .long _end - stext // VirtualSize
+- .long stext - efi_head // VirtualAddress
++ .long stext_offset // VirtualAddress
+ .long _edata - stext // SizeOfRawData
+- .long stext - efi_head // PointerToRawData
++ .long stext_offset // PointerToRawData
+
+ .long 0 // PointerToRelocations (0 for executables)
+ .long 0 // PointerToLineNumbers (0 for executables)
+ .short 0 // NumberOfRelocations (0 for executables)
+ .short 0 // NumberOfLineNumbers (0 for executables)
+ .long 0xe0500020 // Characteristics (section flags)
+- .align 5
+
+ /*
- * Whoops - the architecture was unable to reboot.
- */
- printk("Reboot failed -- System halted\n");
++ * EFI will load stext onwards at the 4k section alignment
++ * described in the PE/COFF header. To ensure that instruction
++ * sequences using an adrp and a :lo12: immediate will function
++ * correctly at this alignment, we must ensure that stext is
++ * placed at a 4k boundary in the Image to begin with.
++ */
++ .align 12
+ #endif
+
+ ENTRY(stext)
+diff --git a/arch/arm64/kernel/io.c b/arch/arm64/kernel/io.c
+index 7d37ead..354be2a 100644
+--- a/arch/arm64/kernel/io.c
++++ b/arch/arm64/kernel/io.c
+@@ -25,12 +25,26 @@
+ */
+ void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
+ {
+- unsigned char *t = to;
+- while (count) {
++ while (count && (!IS_ALIGNED((unsigned long)from, 8) ||
++ !IS_ALIGNED((unsigned long)to, 8))) {
++ *(u8 *)to = __raw_readb(from);
++ from++;
++ to++;
+ count--;
+- *t = readb(from);
+- t++;
++ }
++
++ while (count >= 8) {
++ *(u64 *)to = __raw_readq(from);
++ from += 8;
++ to += 8;
++ count -= 8;
++ }
++
++ while (count) {
++ *(u8 *)to = __raw_readb(from);
+ from++;
++ to++;
++ count--;
+ }
+ }
+ EXPORT_SYMBOL(__memcpy_fromio);
+@@ -40,12 +54,26 @@ EXPORT_SYMBOL(__memcpy_fromio);
+ */
+ void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
+ {
+- const unsigned char *f = from;
+- while (count) {
++ while (count && (!IS_ALIGNED((unsigned long)to, 8) ||
++ !IS_ALIGNED((unsigned long)from, 8))) {
++ __raw_writeb(*(volatile u8 *)from, to);
++ from++;
++ to++;
+ count--;
+- writeb(*f, to);
+- f++;
++ }
++
++ while (count >= 8) {
++ __raw_writeq(*(volatile u64 *)from, to);
++ from += 8;
++ to += 8;
++ count -= 8;
++ }
++
++ while (count) {
++ __raw_writeb(*(volatile u8 *)from, to);
++ from++;
+ to++;
++ count--;
+ }
+ }
+ EXPORT_SYMBOL(__memcpy_toio);
+@@ -55,10 +83,28 @@ EXPORT_SYMBOL(__memcpy_toio);
+ */
+ void __memset_io(volatile void __iomem *dst, int c, size_t count)
+ {
+- while (count) {
++ u64 qc = (u8)c;
++
++ qc |= qc << 8;
++ qc |= qc << 16;
++ qc |= qc << 32;
++
++ while (count && !IS_ALIGNED((unsigned long)dst, 8)) {
++ __raw_writeb(c, dst);
++ dst++;
+ count--;
+- writeb(c, dst);
++ }
++
++ while (count >= 8) {
++ __raw_writeq(qc, dst);
++ dst += 8;
++ count -= 8;
++ }
++
++ while (count) {
++ __raw_writeb(c, dst);
+ dst++;
++ count--;
+ }
+ }
+ EXPORT_SYMBOL(__memset_io);
+diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
+index ce5836c..978cd21 100644
+--- a/arch/arm64/kernel/pci.c
++++ b/arch/arm64/kernel/pci.c
+@@ -17,6 +17,8 @@
+ #include <linux/of_pci.h>
+ #include <linux/of_platform.h>
+ #include <linux/slab.h>
++#include <linux/acpi.h>
++#include <linux/pci-acpi.h>
+
+ #include <asm/pci-bridge.h>
+
+@@ -37,34 +39,99 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+ return res->start;
+ }
+
++int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
++{
++ struct pci_sysdata *sd;
++
++ if (!acpi_disabled) {
++ sd = bridge->bus->sysdata;
++ ACPI_COMPANION_SET(&bridge->dev, sd->companion);
++ }
++ return 0;
++}
++
+ /*
+ * 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);
++ if (acpi_disabled)
++ dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
+
+ return 0;
+ }
+
++void pcibios_add_bus(struct pci_bus *bus)
++{
++ if (!acpi_disabled)
++ acpi_pci_add_bus(bus);
++}
+
+-#ifdef CONFIG_PCI_DOMAINS_GENERIC
+-static bool dt_domain_found = false;
++void pcibios_remove_bus(struct pci_bus *bus)
++{
++ if (!acpi_disabled)
++ acpi_pci_remove_bus(bus);
++}
++
++int pcibios_enable_irq(struct pci_dev *dev)
++{
++ if (!acpi_disabled && !pci_dev_msi_enabled(dev))
++ acpi_pci_irq_enable(dev);
++ return 0;
++}
++
++int pcibios_disable_irq(struct pci_dev *dev)
++{
++ if (!acpi_disabled && !pci_dev_msi_enabled(dev))
++ acpi_pci_irq_disable(dev);
++ return 0;
++}
+
++int pcibios_enable_device(struct pci_dev *dev, int bars)
++{
++ int err;
++
++ err = pci_enable_resources(dev, bars);
++ if (err < 0)
++ return err;
++
++ if (!pci_dev_msi_enabled(dev))
++ return pcibios_enable_irq(dev);
++ return 0;
++}
++
++#ifdef CONFIG_PCI_DOMAINS_GENERIC
+ 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();
+- }
++ int domain = -1;
+
+- bus->domain_nr = domain;
++ if (acpi_disabled)
++ domain = of_get_pci_domain_nr(parent->of_node);
++ else {
++ struct pci_sysdata *sd = bus->sysdata;
++
++ domain = sd->domain;
++ }
++ if (domain >= 0)
++ bus->domain_nr = domain;
+ }
+ #endif
++
++static int __init pcibios_assign_resources(void)
++{
++ struct pci_bus *root_bus;
++
++ if (acpi_disabled)
++ return 0;
++
++ list_for_each_entry(root_bus, &pci_root_buses, node) {
++ pcibios_resource_survey_bus(root_bus);
++ pci_assign_unassigned_root_bus_resources(root_bus);
++ }
++ return 0;
++}
++/*
++ * fs_initcall comes after subsys_initcall, so we know acpi scan
++ * has run.
++ */
++fs_initcall(pcibios_assign_resources);
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
-index 866c1c8..f8a981e 100644
+index 663da77..2d0deda 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -15,6 +15,7 @@
@@ -2684,7 +4302,7 @@ index 866c1c8..f8a981e 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 2437196..c1144a1 100644
+index 2437196..4c7029d 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -43,6 +43,7 @@
@@ -2706,13 +4324,41 @@ index 2437196..c1144a1 100644
unsigned int processor_id;
EXPORT_SYMBOL(processor_id);
-@@ -386,22 +391,34 @@ void __init setup_arch(char **cmdline_p)
+@@ -116,12 +121,16 @@ void __init early_print(const char *str, ...)
+
+ void __init smp_setup_processor_id(void)
+ {
++ u64 mpidr = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
++ cpu_logical_map(0) = mpidr;
++
+ /*
+ * clear __my_cpu_offset on boot CPU to avoid hang caused by
+ * using percpu variable early, for example, lockdep will
+ * access percpu variable inside lock_release
*/
- local_async_enable();
+ set_my_cpu_offset(0);
++ pr_info("Booting Linux on physical CPU 0x%lx\n", (unsigned long)mpidr);
+ }
-+ if (acpi_disabled)
-+ disable_acpi();
+ bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
+@@ -312,6 +321,7 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
+ }
+
+ machine_name = of_flat_dt_get_machine_name();
++ dump_stack_set_arch_desc("%s (DT)", machine_name);
+ }
+
+ /*
+@@ -378,6 +388,8 @@ void __init setup_arch(char **cmdline_p)
+
+ early_ioremap_init();
+
++ disable_acpi();
+
+ parse_early_param();
+
+ /*
+@@ -389,19 +401,27 @@ void __init setup_arch(char **cmdline_p)
efi_init();
arm64_memblock_init();
@@ -2727,9 +4373,6 @@ index 2437196..c1144a1 100644
- unflatten_device_tree();
-
- psci_init();
--
- cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
-- cpu_read_bootcpu_ops();
+ if (acpi_disabled) {
+ unflatten_device_tree();
+ psci_dt_init();
@@ -2741,13 +4384,15 @@ index 2437196..c1144a1 100644
+ psci_acpi_init();
+ acpi_smp_init_cpus();
+ }
-+
+
+- cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
+- cpu_read_bootcpu_ops();
#ifdef CONFIG_SMP
- smp_init_cpus();
smp_build_mpidr_hash();
#endif
-@@ -414,6 +431,19 @@ void __init setup_arch(char **cmdline_p)
+@@ -414,6 +434,19 @@ void __init setup_arch(char **cmdline_p)
#endif
}
@@ -2767,7 +4412,7 @@ index 2437196..c1144a1 100644
static int __init arm64_device_init(void)
{
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-@@ -506,3 +536,25 @@ const struct seq_operations cpuinfo_op = {
+@@ -506,3 +539,25 @@ const struct seq_operations cpuinfo_op = {
.stop = c_stop,
.show = c_show
};
@@ -2947,8 +4592,60 @@ 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/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
+index edf8715..4596f46 100644
+--- a/arch/arm64/kernel/vmlinux.lds.S
++++ b/arch/arm64/kernel/vmlinux.lds.S
+@@ -32,6 +32,22 @@ jiffies = jiffies_64;
+ *(.hyp.text) \
+ VMLINUX_SYMBOL(__hyp_text_end) = .;
+
++/*
++ * The size of the PE/COFF section that covers the kernel image, which
++ * runs from stext to _edata, must be a round multiple of the PE/COFF
++ * FileAlignment, which we set to its minimum value of 0x200. 'stext'
++ * itself is 4 KB aligned, so padding out _edata to a 0x200 aligned
++ * boundary should be sufficient.
++ */
++PECOFF_FILE_ALIGNMENT = 0x200;
++
++#ifdef CONFIG_EFI
++#define PECOFF_EDATA_PADDING \
++ .pecoff_edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGNMENT); }
++#else
++#define PECOFF_EDATA_PADDING
++#endif
++
+ SECTIONS
+ {
+ /*
+@@ -103,6 +119,7 @@ SECTIONS
+ _data = .;
+ _sdata = .;
+ RW_DATA_SECTION(64, PAGE_SIZE, THREAD_SIZE)
++ PECOFF_EDATA_PADDING
+ _edata = .;
+
+ BSS_SECTION(0, 0, 0)
+diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
+index b72aa9f..fbe909f 100644
+--- a/arch/arm64/kvm/hyp.S
++++ b/arch/arm64/kvm/hyp.S
+@@ -761,10 +761,10 @@
+ .macro activate_traps
+ ldr x2, [x0, #VCPU_HCR_EL2]
+ msr hcr_el2, x2
+- ldr x2, =(CPTR_EL2_TTA)
++ mov x2, #CPTR_EL2_TTA
+ msr cptr_el2, x2
+
+- ldr x2, =(1 << 15) // Trap CP15 Cr=15
++ mov x2, #(1 << 15) // Trap CP15 Cr=15
+ msr hstr_el2, x2
+
+ mrs x2, mdcr_el2
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
-index d920942..fda70ab 100644
+index d920942..705a9ce 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -23,8 +23,14 @@
@@ -3015,7 +4712,7 @@ index d920942..fda70ab 100644
+ status = acpi_check_coherency(ACPI_HANDLE(dev),
+ &coherent);
+ if (ACPI_FAILURE(status) || coherent)
-+ set_dma_ops(dev, &coherent_swiotlb_dma_ops);
++ set_dma_ops(_dev, &coherent_swiotlb_dma_ops);
+ break;
+ }
+ dev = dev->parent;
@@ -3074,49 +4771,794 @@ index d920942..fda70ab 100644
dma_ops = &noncoherent_swiotlb_dma_ops;
return swiotlb_late_init_with_default_size(swiotlb_size);
+diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
+index 0bf90d2..f4f8b50 100644
+--- a/arch/arm64/mm/mmu.c
++++ b/arch/arm64/mm/mmu.c
+@@ -202,7 +202,7 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
+ }
+
+ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
+- unsigned long end, unsigned long phys,
++ unsigned long end, phys_addr_t phys,
+ int map_io)
+ {
+ pud_t *pud;
diff --git a/arch/arm64/pci/Makefile b/arch/arm64/pci/Makefile
new file mode 100644
-index 0000000..b8d5dbd
+index 0000000..7038b51
--- /dev/null
+++ b/arch/arm64/pci/Makefile
-@@ -0,0 +1 @@
+@@ -0,0 +1,2 @@
+obj-y += pci.o
++obj-$(CONFIG_ACPI) += mmconfig.o
+diff --git a/arch/arm64/pci/mmconfig.c b/arch/arm64/pci/mmconfig.c
+new file mode 100644
+index 0000000..e83e0d5
+--- /dev/null
++++ b/arch/arm64/pci/mmconfig.c
+@@ -0,0 +1,292 @@
++/*
++ * mmconfig.c - Low-level direct PCI config space access via MMCONFIG
++ *
++ * Borrowed heavily from x86
++ */
++
++#include <linux/pci.h>
++#include <linux/acpi.h>
++#include <linux/init.h>
++#include <linux/bitmap.h>
++#include <linux/dmi.h>
++#include <linux/slab.h>
++#include <linux/mutex.h>
++#include <linux/rculist.h>
++#include <linux/rcupdate.h>
++
++#define PREFIX "PCI: "
++
++/* Indicate if the mmcfg resources have been placed into the resource table. */
++static bool pci_mmcfg_running_state;
++static bool pci_mmcfg_arch_init_failed;
++static DEFINE_MUTEX(pci_mmcfg_lock);
++
++LIST_HEAD(pci_mmcfg_list);
++
++struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
++{
++ struct pci_mmcfg_region *cfg;
++
++ list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
++ if (cfg->segment == segment &&
++ cfg->start_bus <= bus && bus <= cfg->end_bus)
++ return cfg;
++
++ return NULL;
++}
++
++static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
++{
++ void __iomem *addr;
++ u64 start, size;
++ int num_buses;
++
++ start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
++ num_buses = cfg->end_bus - cfg->start_bus + 1;
++ size = PCI_MMCFG_BUS_OFFSET(num_buses);
++ addr = ioremap_nocache(start, size);
++ if (addr)
++ addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
++ return addr;
++}
++
++void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
++{
++ if (cfg && cfg->virt) {
++ iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
++ cfg->virt = NULL;
++ }
++}
++
++void __init pci_mmcfg_arch_free(void)
++{
++ struct pci_mmcfg_region *cfg;
++
++ list_for_each_entry(cfg, &pci_mmcfg_list, list)
++ pci_mmcfg_arch_unmap(cfg);
++}
++
++int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
++{
++ cfg->virt = mcfg_ioremap(cfg);
++ if (!cfg->virt) {
++ pr_err(PREFIX "can't map MMCONFIG at %pR\n", &cfg->res);
++ return -ENOMEM;
++ }
++
++ return 0;
++}
++
++static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
++{
++ if (cfg->res.parent)
++ release_resource(&cfg->res);
++ list_del(&cfg->list);
++ kfree(cfg);
++}
++
++static void __init free_all_mmcfg(void)
++{
++ struct pci_mmcfg_region *cfg, *tmp;
++
++ pci_mmcfg_arch_free();
++ list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list)
++ pci_mmconfig_remove(cfg);
++}
++
++static void list_add_sorted(struct pci_mmcfg_region *new)
++{
++ struct pci_mmcfg_region *cfg;
++
++ /* keep list sorted by segment and starting bus number */
++ list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) {
++ if (cfg->segment > new->segment ||
++ (cfg->segment == new->segment &&
++ cfg->start_bus >= new->start_bus)) {
++ list_add_tail_rcu(&new->list, &cfg->list);
++ return;
++ }
++ }
++ list_add_tail_rcu(&new->list, &pci_mmcfg_list);
++}
++
++static struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
++ int end, u64 addr)
++{
++ struct pci_mmcfg_region *new;
++ struct resource *res;
++
++ if (addr == 0)
++ return NULL;
++
++ new = kzalloc(sizeof(*new), GFP_KERNEL);
++ if (!new)
++ return NULL;
++
++ new->address = addr;
++ new->segment = segment;
++ new->start_bus = start;
++ new->end_bus = end;
++
++ res = &new->res;
++ res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
++ res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1;
++ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
++ snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
++ "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
++ res->name = new->name;
++
++ return new;
++}
++
++static struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start,
++ int end, u64 addr)
++{
++ struct pci_mmcfg_region *new;
++
++ new = pci_mmconfig_alloc(segment, start, end, addr);
++ if (new) {
++ mutex_lock(&pci_mmcfg_lock);
++ list_add_sorted(new);
++ mutex_unlock(&pci_mmcfg_lock);
++
++ pr_info(PREFIX
++ "MMCONFIG for domain %04x [bus %02x-%02x] at %pR "
++ "(base %#lx)\n",
++ segment, start, end, &new->res, (unsigned long)addr);
++ }
++
++ return new;
++}
++
++extern struct acpi_mcfg_fixup __start_acpi_mcfg_fixups[];
++extern struct acpi_mcfg_fixup __end_acpi_mcfg_fixups[];
++
++static int __init pci_parse_mcfg(struct acpi_table_header *header)
++{
++ struct acpi_table_mcfg *mcfg;
++ struct acpi_mcfg_allocation *cfg_table, *cfg;
++ struct acpi_mcfg_fixup *fixup;
++ struct pci_mmcfg_region *new;
++ unsigned long i;
++ int entries;
++
++ if (!header)
++ return -EINVAL;
++
++ mcfg = (struct acpi_table_mcfg *)header;
++
++ /* how many config structures do we have */
++ free_all_mmcfg();
++ entries = 0;
++ i = header->length - sizeof(struct acpi_table_mcfg);
++ while (i >= sizeof(struct acpi_mcfg_allocation)) {
++ entries++;
++ i -= sizeof(struct acpi_mcfg_allocation);
++ }
++ if (entries == 0) {
++ pr_err(PREFIX "MMCONFIG has no entries\n");
++ return -ENODEV;
++ }
++
++ fixup = __start_acpi_mcfg_fixups;
++ while (fixup < __end_acpi_mcfg_fixups) {
++ if (!strncmp(fixup->oem_id, header->oem_id, 6) &&
++ !strncmp(fixup->oem_table_id, header->oem_table_id, 8))
++ break;
++ ++fixup;
++ }
++
++ cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1];
++ for (i = 0; i < entries; i++) {
++ cfg = &cfg_table[i];
++
++ new = pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number,
++ cfg->end_bus_number, cfg->address);
++ if (!new) {
++ pr_warn(PREFIX "no memory for MCFG entries\n");
++ free_all_mmcfg();
++ return -ENOMEM;
++ }
++ if (fixup < __end_acpi_mcfg_fixups)
++ new->fixup = fixup->hook;
++ }
++
++ return 0;
++}
++
++int __init pci_mmcfg_arch_init(void)
++{
++ struct pci_mmcfg_region *cfg;
++
++ list_for_each_entry(cfg, &pci_mmcfg_list, list)
++ if (pci_mmcfg_arch_map(cfg)) {
++ pci_mmcfg_arch_free();
++ return 0;
++ }
++
++ return 1;
++}
++
++static void __init __pci_mmcfg_init(int early)
++{
++ if (list_empty(&pci_mmcfg_list)) {
++ pr_info("No MCFG table found!\n");
++ pci_mmcfg_arch_init_failed = true;
++ return;
++ }
++
++ if (!pci_mmcfg_arch_init()) {
++ pr_info("pci_mmcfg_arch_init failed!\n");
++ free_all_mmcfg();
++ pci_mmcfg_arch_init_failed = true;
++ }
++}
++
++void __init pci_mmcfg_early_init(void)
++{
++ acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
++
++ __pci_mmcfg_init(1);
++}
++
++static int __init pci_mmcfg_init(void)
++{
++ pci_mmcfg_early_init();
++ return 0;
++}
++arch_initcall(pci_mmcfg_init);
++
++void __init pci_mmcfg_late_init(void)
++{
++ /* MMCONFIG hasn't been enabled yet, try again */
++ if (pci_mmcfg_arch_init_failed) {
++ acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
++ __pci_mmcfg_init(0);
++ }
++}
++
++static int __init pci_mmcfg_late_insert_resources(void)
++{
++ struct pci_mmcfg_region *cfg;
++
++ pci_mmcfg_running_state = true;
++
++ /*
++ * Attempt to insert the mmcfg resources but not with the busy flag
++ * marked so it won't cause request errors when __request_region is
++ * called.
++ */
++ list_for_each_entry(cfg, &pci_mmcfg_list, list)
++ if (!cfg->res.parent)
++ insert_resource(&iomem_resource, &cfg->res);
++
++ return 0;
++}
++
++/*
++ * Perform MMCONFIG resource insertion after PCI initialization to allow for
++ * misprogrammed MCFG tables that state larger sizes but actually conflict
++ * with other system resources.
++ */
++late_initcall(pci_mmcfg_late_insert_resources);
diff --git a/arch/arm64/pci/pci.c b/arch/arm64/pci/pci.c
new file mode 100644
-index 0000000..b03b0eb
+index 0000000..0166475
--- /dev/null
+++ b/arch/arm64/pci/pci.c
-@@ -0,0 +1,28 @@
+@@ -0,0 +1,461 @@
+#include <linux/acpi.h>
++#include <linux/of_address.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
-+/**
-+ * raw_pci_read - Platform-specific PCI config space access.
-+ *
-+ * Default empty implementation. Replace with an architecture-specific setup
-+ * routine, if necessary.
++struct pci_root_info {
++ struct acpi_device *bridge;
++ char name[16];
++ unsigned int res_num;
++ struct resource *res;
++ resource_size_t *res_offset;
++ struct pci_sysdata sd;
++ u16 segment;
++ u8 start_bus;
++ u8 end_bus;
++};
++
++static char __iomem *pci_dev_base(struct pci_mmcfg_region *cfg,
++ unsigned int bus, unsigned int devfn)
++{
++ return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
++}
++
++static int __raw_pci_read(struct pci_mmcfg_region *cfg, unsigned int bus,
++ unsigned int devfn, int reg, int len, u32 *value)
++{
++ char __iomem *addr = pci_dev_base(cfg, bus, devfn) + (reg & ~3);
++ int shift = (reg & 3) * 8;
++ u32 v;
++
++ v = readl(addr) >> shift;
++ switch (len) {
++ case 1:
++ *value = v & 0xff;
++ break;
++ case 2:
++ *value = v & 0xffff;
++ break;
++ case 4:
++ *value = v;
++ break;
++ }
++ return 0;
++}
++
++static int __raw_pci_write(struct pci_mmcfg_region *cfg, unsigned int bus,
++ unsigned int devfn, int reg, int len, u32 value)
++{
++ char __iomem *addr = pci_dev_base(cfg, bus, devfn) + (reg & ~3);
++ int mask = 0, shift = (reg & 3) * 8;
++ u32 v;
++
++ switch (len) {
++ case 1:
++ mask = 0xff << shift;
++ break;
++ case 2:
++ mask = 0xffff << shift;
++ break;
++ }
++
++ if (mask) {
++ v = readl(addr) & ~mask;
++ writel(v | (value << shift), addr);
++ } else
++ writel(value, addr);
++
++ return 0;
++}
++
++/*
++ * raw_pci_read/write - Platform-specific PCI config space access.
+ */
-+int __weak raw_pci_read(unsigned int domain, unsigned int bus,
-+ unsigned int devfn, int reg, int len, u32 *val)
++int raw_pci_read(unsigned int domain, unsigned int bus,
++ unsigned int devfn, int reg, int len, u32 *val)
+{
-+ return -EINVAL;
++ struct pci_mmcfg_region *cfg;
++ int ret;
++
++ if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
++err: *val = -1;
++ return -EINVAL;
++ }
++
++ rcu_read_lock();
++ cfg = pci_mmconfig_lookup(domain, bus);
++ if (!cfg || !cfg->virt) {
++ rcu_read_unlock();
++ goto err;
++ }
++
++ if (cfg->read)
++ ret = (*cfg->read)(cfg, bus, devfn, reg, len, val);
++ else
++ ret = __raw_pci_read(cfg, bus, devfn, reg, len, val);
++
++ rcu_read_unlock();
++
++ return ret;
+}
+
-+int __weak raw_pci_write(unsigned int domain, unsigned int bus,
-+ unsigned int devfn, int reg, int len, u32 val)
++int raw_pci_write(unsigned int domain, unsigned int bus,
++ unsigned int devfn, int reg, int len, u32 val)
+{
-+ return -EINVAL;
++ struct pci_mmcfg_region *cfg;
++ int ret;
++
++ if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
++ return -EINVAL;
++
++ rcu_read_lock();
++ cfg = pci_mmconfig_lookup(domain, bus);
++ if (!cfg || !cfg->virt) {
++ rcu_read_unlock();
++ return -EINVAL;
++ }
++
++ if (cfg->write)
++ ret = (*cfg->write)(cfg, bus, devfn, reg, len, val);
++ else
++ ret = __raw_pci_write(cfg, bus, devfn, reg, len, val);
++
++ rcu_read_unlock();
++
++ return ret;
++}
++
++#ifdef CONFIG_ACPI
++static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,
++ int size, u32 *value)
++{
++ return raw_pci_read(pci_domain_nr(bus), bus->number,
++ devfn, where, size, value);
++}
++
++static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
++ int size, u32 value)
++{
++ return raw_pci_write(pci_domain_nr(bus), bus->number,
++ devfn, where, size, value);
++}
++
++struct pci_ops pci_root_ops = {
++ .read = pci_read,
++ .write = pci_write,
++};
++
++static acpi_status resource_to_addr(struct acpi_resource *resource,
++ struct acpi_resource_address64 *addr)
++{
++ acpi_status status;
++
++ memset(addr, 0, sizeof(*addr));
++ switch (resource->type) {
++ case ACPI_RESOURCE_TYPE_ADDRESS16:
++ case ACPI_RESOURCE_TYPE_ADDRESS32:
++ case ACPI_RESOURCE_TYPE_ADDRESS64:
++ status = acpi_resource_to_address64(resource, addr);
++ if (ACPI_SUCCESS(status) &&
++ (addr->resource_type == ACPI_MEMORY_RANGE ||
++ addr->resource_type == ACPI_IO_RANGE) &&
++ addr->address_length > 0) {
++ return AE_OK;
++ }
++ break;
++ }
++ return AE_ERROR;
++}
++
++static acpi_status count_resource(struct acpi_resource *acpi_res, void *data)
++{
++ struct pci_root_info *info = data;
++ struct acpi_resource_address64 addr;
++ acpi_status status;
++
++ status = resource_to_addr(acpi_res, &addr);
++ if (ACPI_SUCCESS(status))
++ info->res_num++;
++ return AE_OK;
++}
++
++static acpi_status setup_resource(struct acpi_resource *acpi_res, void *data)
++{
++ struct pci_root_info *info = data;
++ struct resource *res;
++ struct acpi_resource_address64 addr;
++ acpi_status status;
++ unsigned long flags;
++ u64 start, end;
++
++ status = resource_to_addr(acpi_res, &addr);
++ if (!ACPI_SUCCESS(status))
++ return AE_OK;
++
++ if (addr.resource_type == ACPI_MEMORY_RANGE) {
++ flags = IORESOURCE_MEM;
++ if (addr.info.mem.caching == ACPI_PREFETCHABLE_MEMORY)
++ flags |= IORESOURCE_PREFETCH;
++ } else if (addr.resource_type == ACPI_IO_RANGE) {
++ flags = IORESOURCE_IO;
++ } else
++ return AE_OK;
++
++ start = addr.minimum + addr.translation_offset;
++ end = addr.maximum + addr.translation_offset;
++
++ res = &info->res[info->res_num];
++ res->name = info->name;
++ res->flags = flags;
++ res->start = start;
++ res->end = end;
++
++ if (flags & IORESOURCE_IO) {
++ unsigned long port;
++ int err;
++
++ err = pci_register_io_range(start, addr.address_length);
++ if (err)
++ return AE_OK;
++
++ port = pci_address_to_pio(start);
++ if (port == (unsigned long)-1) {
++ res->start = -1;
++ res->end = -1;
++ return AE_OK;
++ }
++
++ res->start = port;
++ res->end = res->start + addr.address_length - 1;
++
++ if (pci_remap_iospace(res, start) < 0)
++ return AE_OK;
++
++ info->res_offset[info->res_num] = 0;
++ } else
++ info->res_offset[info->res_num] = addr.translation_offset;
++
++ info->res_num++;
++
++ return AE_OK;
++}
++
++static void coalesce_windows(struct pci_root_info *info, unsigned long type)
++{
++ int i, j;
++ struct resource *res1, *res2;
++
++ for (i = 0; i < info->res_num; i++) {
++ res1 = &info->res[i];
++ if (!(res1->flags & type))
++ continue;
++
++ for (j = i + 1; j < info->res_num; j++) {
++ res2 = &info->res[j];
++ if (!(res2->flags & type))
++ continue;
++
++ /*
++ * I don't like throwing away windows because then
++ * our resources no longer match the ACPI _CRS, but
++ * the kernel resource tree doesn't allow overlaps.
++ */
++ if (resource_overlaps(res1, res2)) {
++ res2->start = min(res1->start, res2->start);
++ res2->end = max(res1->end, res2->end);
++ dev_info(&info->bridge->dev,
++ "host bridge window expanded to %pR; %pR ignored\n",
++ res2, res1);
++ res1->flags = 0;
++ }
++ }
++ }
++}
++
++static void add_resources(struct pci_root_info *info,
++ struct list_head *resources)
++{
++ int i;
++ struct resource *res, *root, *conflict;
++
++ coalesce_windows(info, IORESOURCE_MEM);
++ coalesce_windows(info, IORESOURCE_IO);
++
++ for (i = 0; i < info->res_num; i++) {
++ res = &info->res[i];
++
++ if (res->flags & IORESOURCE_MEM)
++ root = &iomem_resource;
++ else if (res->flags & IORESOURCE_IO)
++ root = &ioport_resource;
++ else
++ continue;
++
++ conflict = insert_resource_conflict(root, res);
++ if (conflict)
++ dev_info(&info->bridge->dev,
++ "ignoring host bridge window %pR (conflicts with %s %pR)\n",
++ res, conflict->name, conflict);
++ else
++ pci_add_resource_offset(resources, res,
++ info->res_offset[i]);
++ }
++}
++
++static void free_pci_root_info_res(struct pci_root_info *info)
++{
++ kfree(info->res);
++ info->res = NULL;
++ kfree(info->res_offset);
++ info->res_offset = NULL;
++ info->res_num = 0;
++}
++
++static void __release_pci_root_info(struct pci_root_info *info)
++{
++ int i;
++ struct resource *res;
++
++ for (i = 0; i < info->res_num; i++) {
++ res = &info->res[i];
++
++ if (!res->parent)
++ continue;
++
++ if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
++ continue;
++
++ release_resource(res);
++ }
++
++ free_pci_root_info_res(info);
++
++ kfree(info);
++}
++
++static void release_pci_root_info(struct pci_host_bridge *bridge)
++{
++ struct pci_root_info *info = bridge->release_data;
++
++ __release_pci_root_info(info);
++}
++
++static void probe_pci_root_info(struct pci_root_info *info,
++ struct acpi_device *device,
++ int busnum, int domain)
++{
++ size_t size;
++
++ sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum);
++ info->bridge = device;
++
++ info->res_num = 0;
++ acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
++ info);
++ if (!info->res_num)
++ return;
++
++ size = sizeof(*info->res) * info->res_num;
++ info->res = kzalloc_node(size, GFP_KERNEL, info->sd.node);
++ if (!info->res) {
++ info->res_num = 0;
++ return;
++ }
++
++ size = sizeof(*info->res_offset) * info->res_num;
++ info->res_num = 0;
++ info->res_offset = kzalloc_node(size, GFP_KERNEL, info->sd.node);
++ if (!info->res_offset) {
++ kfree(info->res);
++ info->res = NULL;
++ return;
++ }
++
++ acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,
++ info);
+}
+
+/* Root bridge scanning */
+struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
+{
-+ return NULL;
++ struct acpi_device *device = root->device;
++ struct pci_mmcfg_region *mcfg;
++ struct pci_root_info *info;
++ int domain = root->segment;
++ int busnum = root->secondary.start;
++ LIST_HEAD(resources);
++ struct pci_bus *bus;
++ struct pci_sysdata *sd;
++ int node;
++
++ /* we need mmconfig */
++ mcfg = pci_mmconfig_lookup(domain, busnum);
++ if (!mcfg) {
++ pr_err("pci_bus %04x:%02x has no MCFG table\n",
++ domain, busnum);
++ return NULL;
++ }
++
++ /* temporary hack */
++ if (mcfg->fixup)
++ (*mcfg->fixup)(root, mcfg);
++
++ if (domain && !pci_domains_supported) {
++ pr_warn("PCI %04x:%02x: multiple domains not supported.\n",
++ domain, busnum);
++ return NULL;
++ }
++
++ node = NUMA_NO_NODE;
++
++ info = kzalloc_node(sizeof(*info), GFP_KERNEL, node);
++ if (!info) {
++ pr_warn("PCI %04x:%02x: ignored (out of memory)\n",
++ domain, busnum);
++ return NULL;
++ }
++ info->segment = domain;
++ info->start_bus = busnum;
++ info->end_bus = root->secondary.end;
++
++ sd = &info->sd;
++ sd->domain = domain;
++ sd->node = node;
++ sd->companion = device;
++
++ probe_pci_root_info(info, device, busnum, domain);
++
++ /* insert busn res at first */
++ pci_add_resource(&resources, &root->secondary);
++
++ /* then _CRS resources */
++ add_resources(info, &resources);
++
++ bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, &resources);
++ if (bus) {
++ pci_scan_child_bus(bus);
++ pci_set_host_bridge_release(to_pci_host_bridge(bus->bridge),
++ release_pci_root_info, info);
++ } else {
++ pci_free_resource_list(&resources);
++ __release_pci_root_info(info);
++ }
++
++ /* After the PCI-E bus has been walked and all devices discovered,
++ * configure any settings of the fabric that might be necessary.
++ */
++ if (bus) {
++ struct pci_bus *child;
++
++ list_for_each_entry(child, &bus->children, node)
++ pcie_bus_configure_settings(child);
++ }
++
++ if (bus && node != NUMA_NO_NODE)
++ dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node);
++
++ return bus;
+}
++
++#endif /* CONFIG_ACPI */
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
-index d0f3265..3343080 100644
+index b23fe37..555e226 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -5,8 +5,7 @@
@@ -3147,7 +5589,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..252d0ff 100644
+index c3b2fcb..5a21476 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -23,7 +23,11 @@ acpi-y += nvs.o
@@ -3162,7 +5604,7 @@ index 505d4d7..252d0ff 100644
acpi-y += device_pm.o
acpi-$(CONFIG_ACPI_SLEEP) += proc.o
-@@ -39,13 +43,14 @@ acpi-y += processor_core.o
+@@ -39,7 +43,7 @@ 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
@@ -3171,13 +5613,14 @@ index 505d4d7..252d0ff 100644
acpi-y += acpi_lpss.o
acpi-y += acpi_platform.o
acpi-y += acpi_pnp.o
- acpi-y += int340x_thermal.o
+@@ -47,6 +51,7 @@ acpi-y += int340x_thermal.o
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
@@ -3193,7 +5636,7 @@ index 8b67bd0..c412fdb 100644
message = "platform specific model";
break;
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
-index 4c5cf77..926ca5c 100644
+index 447f6d6..c5ff8ba 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -26,8 +26,13 @@
@@ -3210,7 +5653,7 @@ index 4c5cf77..926ca5c 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);
+@@ -173,4 +178,10 @@ static inline void suspend_nvs_restore(void) {}
bool acpi_osi_is_win8(void);
#endif
@@ -3304,10 +5747,10 @@ index ef58f46..5c84e0d 100644
exit:
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
new file mode 100644
-index 0000000..ff53eb8
+index 0000000..0d08373
--- /dev/null
+++ b/drivers/acpi/property.c
-@@ -0,0 +1,586 @@
+@@ -0,0 +1,551 @@
+/*
+ * ACPI device specific properties support.
+ *
@@ -3391,6 +5834,7 @@ index 0000000..ff53eb8
+ const union acpi_object *of_compatible;
+ struct acpi_hardware_id *hwid;
+ bool acpi_of = false;
++ int ret;
+
+ /*
+ * Check if the special PRP0001 ACPI ID is present and in that
@@ -3407,13 +5851,17 @@ index 0000000..ff53eb8
+ if (!acpi_of)
+ return;
+
-+ if (acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING,
-+ &of_compatible)) {
-+ acpi_handle_warn(adev->handle,
-+ "PRP0001 requires compatible property\n");
-+ return;
++ ret = acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING,
++ &of_compatible);
++ if (ret) {
++ ret = acpi_dev_get_property(adev, "compatible",
++ ACPI_TYPE_STRING, &of_compatible);
++ if (ret) {
++ acpi_handle_warn(adev->handle,
++ "PRP0001 requires compatible property\n");
++ return;
++ }
+ }
-+
+ adev->data.of_compatible = of_compatible;
+}
+
@@ -3578,25 +6026,21 @@ index 0000000..ff53eb8
+ * 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
+ *
+ * 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.
++ * target object in @args->adev. If the reference includes arguments, store
++ * them in the @args->args[] array.
+ *
-+ * 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.
++ * 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.
+ */
-+int acpi_dev_get_property_reference(struct acpi_device *adev, const char *name,
-+ const char *size_prop, size_t index,
++int acpi_dev_get_property_reference(struct acpi_device *adev,
++ const char *name, size_t index,
+ struct acpi_reference_args *args)
+{
+ const union acpi_object *element, *end;
@@ -3613,7 +6057,7 @@ index 0000000..ff53eb8
+ * return that reference then.
+ */
+ if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
-+ if (size_prop || index)
++ if (index)
+ return -EINVAL;
+
+ ret = acpi_bus_get_device(obj->reference.handle, &device);
@@ -3653,42 +6097,16 @@ index 0000000..ff53eb8
+ element++;
+ nargs = 0;
+
-+ if (size_prop) {
-+ const union acpi_object *prop;
++ /* assume following integer elements are all args */
++ for (i = 0; element + i < end; i++) {
++ int type = element[i].type;
+
-+ /*
-+ * 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)
++ if (type == ACPI_TYPE_INTEGER)
++ nargs++;
++ else if (type == ACPI_TYPE_LOCAL_REFERENCE)
++ break;
++ else
+ 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) {
@@ -3714,11 +6132,11 @@ index 0000000..ff53eb8
+ (const union acpi_object **)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_single(struct acpi_device *adev, const char *propname,
++ enum dev_prop_type proptype, void *val)
+{
+ const union acpi_object *obj;
-+ int ret = -EINVAL;
++ int ret;
+
+ if (!val)
+ return -EINVAL;
@@ -3754,6 +6172,8 @@ index 0000000..ff53eb8
+ return ret;
+
+ *(char **)val = obj->string.pointer;
++ } else {
++ ret = -EINVAL;
+ }
+ return ret;
+}
@@ -3834,23 +6254,30 @@ index 0000000..ff53eb8
+ return 0;
+}
+
-+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_dev_prop_read(struct acpi_device *adev, const char *propname,
++ enum dev_prop_type proptype, void *val, size_t nval)
+{
+ const union acpi_object *obj;
+ const union acpi_object *items;
+ int ret;
+
++ if (val && nval == 1) {
++ ret = acpi_dev_prop_read_single(adev, propname, proptype, val);
++ if (!ret)
++ return ret;
++ }
++
+ ret = acpi_dev_get_property_array(adev, propname, ACPI_TYPE_ANY, &obj);
+ if (ret)
+ return ret;
+
+ if (!val)
+ return obj->package.count;
++ else if (nval <= 0)
++ return -EINVAL;
+
+ if (nval > obj->package.count)
-+ nval = obj->package.count;
++ return -EOVERFLOW;
+
+ items = obj->package.elements;
+ switch (proptype) {
@@ -3875,49 +6302,17 @@ index 0000000..ff53eb8
+ }
+ return ret;
+}
-+
-+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;
-+
-+ if (!adev)
-+ return -EINVAL;
-+
-+ 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
+index 0476e90..9cb5cca 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,
+@@ -124,17 +124,56 @@ 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)
@@ -3926,6 +6321,33 @@ index ae44d86..4da55d8 100644
- return -ENOMEM;
- len += count;
- size -= count;
++ /*
++ * If the device has PRP0001 we expose DT compatible modalias
++ * instead in form of of:NnameTCcompatible.
++ */
++ if (acpi_dev->data.of_compatible) {
++ struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
++ const union acpi_object *of_compatible, *obj;
++ int i, nval;
++ char *c;
++
++ acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf);
++ /* DT strings are all in lower case */
++ for (c = buf.pointer; *c != '\0'; c++)
++ *c = tolower(*c);
++
++ len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer);
++ ACPI_FREE(buf.pointer);
++
++ of_compatible = acpi_dev->data.of_compatible;
++ if (of_compatible->type == ACPI_TYPE_PACKAGE) {
++ nval = of_compatible->package.count;
++ obj = of_compatible->package.elements;
++ } else { /* Must be ACPI_TYPE_STRING. */
++ nval = 1;
++ obj = of_compatible;
++ }
++ for (i = 0; i < nval; i++, obj++) {
+ count = snprintf(&modalias[len], size, "C%s",
+ obj->string.pointer);
+ if (count < 0)
@@ -3952,33 +6374,36 @@ index ae44d86..4da55d8 100644
}
modalias[len] = '\0';
-@@ -864,6 +890,51 @@ int acpi_match_device_ids(struct acpi_device *device,
+@@ -902,6 +941,51 @@ int acpi_match_device_ids(struct acpi_device *device,
}
EXPORT_SYMBOL(acpi_match_device_ids);
-+/* Performs match for special "PRP0001" shoehorn ACPI ID */
++/* Performs match against 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;
++ const union acpi_object *of_compatible, *obj;
++ struct acpi_device *adev;
++ int i, nval;
++
++ adev = ACPI_COMPANION(dev);
++ if (!adev)
++ return false;
+
-+ /*
-+ * 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;
++ return false;
+
++ if (of_compatible->type == ACPI_TYPE_PACKAGE) {
++ nval = of_compatible->package.count;
++ obj = of_compatible->package.elements;
++ } else { /* Must be ACPI_TYPE_STRING. */
++ nval = 1;
++ obj = of_compatible;
++ }
+ /* Now we can look for the driver DT compatible strings */
-+ for (i = 0; i < of_compatible->package.count; i++) {
++ for (i = 0; i < nval; i++, obj++) {
+ const struct of_device_id *id;
-+ const union acpi_object *obj;
-+
-+ obj = &of_compatible->package.elements[i];
+
+ for (id = drv->of_match_table; id->compatible[0]; id++)
+ if (!strcasecmp(obj->string.pointer, id->compatible))
@@ -3991,20 +6416,17 @@ index ae44d86..4da55d8 100644
+bool acpi_driver_match_device(struct device *dev,
+ const struct device_driver *drv)
+{
-+ const struct acpi_device_id *id;
++ if (!drv->acpi_match_table)
++ return acpi_of_driver_match_device(dev, drv);
+
-+ id = acpi_match_device(drv->acpi_match_table, dev);
-+ if (!id)
-+ return false;
-+
-+ return acpi_of_driver_match_device(dev, drv);
++ return !!acpi_match_device(drv->acpi_match_table, dev);
+}
+EXPORT_SYMBOL_GPL(acpi_driver_match_device);
+
static void acpi_free_power_resources_lists(struct acpi_device *device)
{
int i;
-@@ -884,6 +955,7 @@ static void acpi_device_release(struct device *dev)
+@@ -922,6 +1006,7 @@ static void acpi_device_release(struct device *dev)
{
struct acpi_device *acpi_dev = to_acpi_device(dev);
@@ -4012,7 +6434,38 @@ index ae44d86..4da55d8 100644
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,
+@@ -1304,6 +1389,26 @@ int acpi_device_add(struct acpi_device *device,
+ return result;
+ }
+
++struct acpi_device *acpi_get_next_child(struct device *dev,
++ struct acpi_device *child)
++{
++ struct acpi_device *adev = ACPI_COMPANION(dev);
++ struct list_head *head, *next;
++
++ if (!adev)
++ return NULL;
++
++ head = &adev->children;
++ if (list_empty(head))
++ return NULL;
++
++ if (!child)
++ return list_first_entry(head, struct acpi_device, node);
++
++ next = child->node.next;
++ return next == head ? NULL : list_entry(next, struct acpi_device, node);
++}
++
+ /* --------------------------------------------------------------------------
+ Driver Management
+ -------------------------------------------------------------------------- */
+@@ -1923,9 +2028,11 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
+ device->device_type = type;
+ device->handle = handle;
+ device->parent = acpi_bus_get_parent(handle);
++ device->fwnode.type = FWNODE_ACPI;
acpi_set_device_status(device, sta);
acpi_device_get_busid(device);
acpi_set_pnp_ids(handle, &device->pnp, type);
@@ -4225,10 +6678,10 @@ index 6d5a6cd..47f36d4 100644
int __init
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
-index 834f35c..b163f73 100644
+index 371ac12..af325a7 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)
+@@ -723,3 +723,29 @@ bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs)
return false;
}
EXPORT_SYMBOL(acpi_check_dsm);
@@ -4407,10 +6860,10 @@ index 6922cd6..53c3fe1 100644
obj-y += power/
diff --git a/drivers/base/property.c b/drivers/base/property.c
new file mode 100644
-index 0000000..7bf5708
+index 0000000..c458458
--- /dev/null
+++ b/drivers/base/property.c
-@@ -0,0 +1,235 @@
+@@ -0,0 +1,431 @@
+/*
+ * property.c - Unified device property interface.
+ *
@@ -4429,210 +6882,403 @@ index 0000000..7bf5708
+#include <linux/of.h>
+
+/**
-+ * device_get_property - return a raw property of a device
-+ * @dev: Device get the property of
++ * device_property_present - check if a property of a device is present
++ * @dev: Device whose property is being checked
+ * @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.
++ * Check if property @propname is present in the device firmware description.
++ */
++bool device_property_present(struct device *dev, const char *propname)
++{
++ if (IS_ENABLED(CONFIG_OF) && dev->of_node)
++ return of_property_read_bool(dev->of_node, propname);
++
++ return !acpi_dev_prop_get(ACPI_COMPANION(dev), propname, NULL);
++}
++EXPORT_SYMBOL_GPL(device_property_present);
++
++/**
++ * fwnode_property_present - check if a property of a firmware node is present
++ * @fwnode: Firmware node whose property to check
++ * @propname: Name of the property
++ */
++bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
++{
++ if (is_of_node(fwnode))
++ return of_property_read_bool(of_node(fwnode), propname);
++ else if (is_acpi_node(fwnode))
++ return !acpi_dev_prop_get(acpi_node(fwnode), propname, NULL);
++
++ return false;
++}
++EXPORT_SYMBOL_GPL(fwnode_property_present);
++
++#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \
++ (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \
++ : of_property_count_elems_of_size((node), (propname), sizeof(type))
++
++#define DEV_PROP_READ_ARRAY(_dev_, _propname_, _type_, _proptype_, _val_, _nval_) \
++ IS_ENABLED(CONFIG_OF) && _dev_->of_node ? \
++ (OF_DEV_PROP_READ_ARRAY(_dev_->of_node, _propname_, _type_, \
++ _val_, _nval_)) : \
++ acpi_dev_prop_read(ACPI_COMPANION(_dev_), _propname_, \
++ _proptype_, _val_, _nval_)
++
++/**
++ * device_property_read_u8_array - return a u8 array property of a device
++ * @dev: Device to get the property of
++ * @propname: Name of the property
++ * @val: The values are stored here
++ * @nval: Size of the @val array
++ *
++ * Function reads an array of u8 properties with @propname from the device
++ * firmware description and stores them to @val if found.
+ *
+ * Return: %0 if the property was found (success),
+ * %-EINVAL if given arguments are not valid,
-+ * %-ENODATA if the property does not exist.
++ * %-ENODATA if the property does not have a value,
++ * %-EPROTO if the property is not an array of numbers,
++ * %-EOVERFLOW if the size of the property is not as expected.
+ */
-+int device_get_property(struct device *dev, const char *propname, void **valptr)
++int device_property_read_u8_array(struct device *dev, const char *propname,
++ u8 *val, size_t nval)
+{
-+ if (IS_ENABLED(CONFIG_OF) && dev->of_node)
-+ return of_dev_prop_get(dev->of_node, propname, valptr);
++ return DEV_PROP_READ_ARRAY(dev, propname, u8, DEV_PROP_U8, val, nval);
++}
++EXPORT_SYMBOL_GPL(device_property_read_u8_array);
+
-+ return acpi_dev_prop_get(ACPI_COMPANION(dev), propname, valptr);
++/**
++ * device_property_read_u16_array - return a u16 array property of a device
++ * @dev: Device to get the property of
++ * @propname: Name of the property
++ * @val: The values are stored here
++ * @nval: Size of the @val array
++ *
++ * Function reads an array of u16 properties with @propname from the device
++ * firmware description and stores them to @val if found.
++ *
++ * Return: %0 if the property was found (success),
++ * %-EINVAL if given arguments are not valid,
++ * %-ENODATA if the property does not have a value,
++ * %-EPROTO if the property is not an array of numbers,
++ * %-EOVERFLOW if the size of the property is not as expected.
++ */
++int device_property_read_u16_array(struct device *dev, const char *propname,
++ u16 *val, size_t nval)
++{
++ return DEV_PROP_READ_ARRAY(dev, propname, u16, DEV_PROP_U16, val, nval);
+}
-+EXPORT_SYMBOL_GPL(device_get_property);
++EXPORT_SYMBOL_GPL(device_property_read_u16_array);
+
+/**
-+ * device_get_child_property - return a raw property of a device's child
-+ * @dev: Parent device
-+ * @child: Child to get a property of
++ * device_property_read_u32_array - return a u32 array property of a device
++ * @dev: Device to get the property of
+ * @propname: Name of the property
-+ * @valptr: The raw property value is stored here
++ * @val: The values are stored here
++ * @nval: Size of the @val array
+ *
-+ * 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.
++ * Function reads an array of u32 properties with @propname from the device
++ * firmware description and stores them to @val if found.
+ *
+ * Return: %0 if the property was found (success),
+ * %-EINVAL if given arguments are not valid,
-+ * %-ENODATA if the property does not exist.
++ * %-ENODATA if the property does not have a value,
++ * %-EPROTO if the property is not an array of numbers,
++ * %-EOVERFLOW if the size of the property is not as expected.
+ */
-+int device_get_child_property(struct device *dev, void *child,
-+ const char *propname, void **valptr)
++int device_property_read_u32_array(struct device *dev, const char *propname,
++ u32 *val, size_t nval)
+{
-+ if (!child)
-+ return -EINVAL;
++ return DEV_PROP_READ_ARRAY(dev, propname, u32, DEV_PROP_U32, val, nval);
++}
++EXPORT_SYMBOL_GPL(device_property_read_u32_array);
+
-+ 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);
++/**
++ * device_property_read_u64_array - return a u64 array property of a device
++ * @dev: Device to get the property of
++ * @propname: Name of the property
++ * @val: The values are stored here
++ * @nval: Size of the @val array
++ *
++ * Function reads an array of u64 properties with @propname from the device
++ * firmware description and stores them to @val if found.
++ *
++ * Return: %0 if the property was found (success),
++ * %-EINVAL if given arguments are not valid,
++ * %-ENODATA if the property does not have a value,
++ * %-EPROTO if the property is not an array of numbers,
++ * %-EOVERFLOW if the size of the property is not as expected.
++ */
++int device_property_read_u64_array(struct device *dev, const char *propname,
++ u64 *val, size_t nval)
++{
++ return DEV_PROP_READ_ARRAY(dev, propname, u64, DEV_PROP_U64, val, nval);
++}
++EXPORT_SYMBOL_GPL(device_property_read_u64_array);
+
-+ return -ENODATA;
++/**
++ * device_property_read_string_array - return a string array property of device
++ * @dev: Device to get the property of
++ * @propname: Name of the property
++ * @val: The values are stored here
++ * @nval: Size of the @val array
++ *
++ * Function reads an array of string properties with @propname from the device
++ * firmware description and stores them to @val if found.
++ *
++ * Return: %0 if the property was found (success),
++ * %-EINVAL if given arguments are not valid,
++ * %-ENODATA if the property does not have a value,
++ * %-EPROTO or %-EILSEQ if the property is not an array of strings,
++ * %-EOVERFLOW if the size of the property is not as expected.
++ */
++int device_property_read_string_array(struct device *dev, const char *propname,
++ const char **val, size_t nval)
++{
++ return IS_ENABLED(CONFIG_OF) && dev->of_node ?
++ of_property_read_string_array(dev->of_node, propname, val, nval) :
++ acpi_dev_prop_read(ACPI_COMPANION(dev), propname,
++ DEV_PROP_STRING, val, nval);
+}
-+EXPORT_SYMBOL_GPL(device_get_child_property);
++EXPORT_SYMBOL_GPL(device_property_read_string_array);
+
+/**
-+ * device_read_property - read a typed property of a device
++ * device_property_read_string - return a string 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.
++ * stores the value into @val if found. The value is checked to be a string.
+ *
+ * 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.
++ * %-ENODATA if the property does not have a value,
++ * %-EPROTO or %-EILSEQ if the property type is not a string.
+ */
-+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);
++int device_property_read_string(struct device *dev, const char *propname,
++ const char **val)
++{
++ return IS_ENABLED(CONFIG_OF) && dev->of_node ?
++ of_property_read_string(dev->of_node, propname, val) :
++ acpi_dev_prop_read(ACPI_COMPANION(dev), propname,
++ DEV_PROP_STRING, val, 1);
++}
++EXPORT_SYMBOL_GPL(device_property_read_string);
++
++#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_) \
++({ \
++ int _ret_; \
++ if (is_of_node(_fwnode_)) \
++ _ret_ = OF_DEV_PROP_READ_ARRAY(of_node(_fwnode_), _propname_, \
++ _type_, _val_, _nval_); \
++ else if (is_acpi_node(_fwnode_)) \
++ _ret_ = acpi_dev_prop_read(acpi_node(_fwnode_), _propname_, \
++ _proptype_, _val_, _nval_); \
++ else \
++ _ret_ = -ENXIO; \
++ _ret_; \
++})
+
-+ return acpi_dev_prop_read(ACPI_COMPANION(dev), propname, proptype, val);
++/**
++ * fwnode_property_read_u8_array - return a u8 array property of firmware node
++ * @fwnode: Firmware node to get the property of
++ * @propname: Name of the property
++ * @val: The values are stored here
++ * @nval: Size of the @val array
++ *
++ * Read an array of u8 properties with @propname from @fwnode and stores them to
++ * @val if found.
++ *
++ * Return: %0 if the property was found (success),
++ * %-EINVAL if given arguments are not valid,
++ * %-ENODATA if the property does not have a value,
++ * %-EPROTO if the property is not an array of numbers,
++ * %-EOVERFLOW if the size of the property is not as expected,
++ * %-ENXIO if no suitable firmware interface is present.
++ */
++int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
++ const char *propname, u8 *val, size_t nval)
++{
++ return FWNODE_PROP_READ_ARRAY(fwnode, propname, u8, DEV_PROP_U8,
++ val, nval);
+}
-+EXPORT_SYMBOL_GPL(device_read_property);
++EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
+
+/**
-+ * device_read_child_property - read a typed property of a device's child
-+ * @dev: Parent device
-+ * @child: Child to read a property of
++ * fwnode_property_read_u16_array - return a u16 array property of firmware node
++ * @fwnode: Firmware node to get the property of
+ * @propname: Name of the property
-+ * @proptype: Type of the property
-+ * @val: The value is stored here
++ * @val: The values are stored here
++ * @nval: Size of the @val array
+ *
-+ * 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.
++ * Read an array of u16 properties with @propname from @fwnode and store them to
++ * @val if found.
+ *
+ * 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.
++ * %-ENODATA if the property does not have a value,
++ * %-EPROTO if the property is not an array of numbers,
++ * %-EOVERFLOW if the size of the property is not as expected,
++ * %-ENXIO if no suitable firmware interface is present.
+ */
-+int device_read_child_property(struct device *dev, void *child,
-+ const char *propname, enum dev_prop_type proptype,
-+ void *val)
++int fwnode_property_read_u16_array(struct fwnode_handle *fwnode,
++ const char *propname, u16 *val, size_t nval)
+{
-+ 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;
++ return FWNODE_PROP_READ_ARRAY(fwnode, propname, u16, DEV_PROP_U16,
++ val, nval);
+}
-+EXPORT_SYMBOL_GPL(device_read_child_property);
++EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
+
+/**
-+ * device_read_property_array - read an array property of a device
-+ * @dev: Device to get the property of
++ * fwnode_property_read_u32_array - return a u32 array property of firmware node
++ * @fwnode: Firmware node 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.
++ * Read an array of u32 properties with @propname from @fwnode store them to
++ * @val if found.
+ *
+ * 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.
++ * %-ENODATA if the property does not have a value,
++ * %-EPROTO if the property is not an array of numbers,
++ * %-EOVERFLOW if the size of the property is not as expected,
++ * %-ENXIO if no suitable firmware interface is present.
+ */
-+int device_read_property_array(struct device *dev, const char *propname,
-+ enum dev_prop_type proptype, void *val,
-+ size_t nval)
++int fwnode_property_read_u32_array(struct fwnode_handle *fwnode,
++ const char *propname, u32 *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 FWNODE_PROP_READ_ARRAY(fwnode, propname, u32, DEV_PROP_U32,
++ val, nval);
++}
++EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
+
-+ return acpi_dev_prop_read_array(ACPI_COMPANION(dev), propname, proptype,
-+ val, nval);
++/**
++ * fwnode_property_read_u64_array - return a u64 array property firmware node
++ * @fwnode: Firmware node to get the property of
++ * @propname: Name of the property
++ * @val: The values are stored here
++ * @nval: Size of the @val array
++ *
++ * Read an array of u64 properties with @propname from @fwnode and store them to
++ * @val if found.
++ *
++ * Return: %0 if the property was found (success),
++ * %-EINVAL if given arguments are not valid,
++ * %-ENODATA if the property does not have a value,
++ * %-EPROTO if the property is not an array of numbers,
++ * %-EOVERFLOW if the size of the property is not as expected,
++ * %-ENXIO if no suitable firmware interface is present.
++ */
++int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
++ const char *propname, u64 *val, size_t nval)
++{
++ return FWNODE_PROP_READ_ARRAY(fwnode, propname, u64, DEV_PROP_U64,
++ val, nval);
+}
-+EXPORT_SYMBOL_GPL(device_read_property_array);
++EXPORT_SYMBOL_GPL(fwnode_property_read_u64_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
++ * fwnode_property_read_string_array - return string array property of a node
++ * @fwnode: Firmware node 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.
++ * Read an string list property @propname from the given firmware node and store
++ * them to @val if found.
+ *
+ * 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.
++ * %-ENODATA if the property does not have a value,
++ * %-EPROTO if the property is not an array of strings,
++ * %-EOVERFLOW if the size of the property is not as expected,
++ * %-ENXIO if no suitable firmware interface is present.
+ */
-+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 fwnode_property_read_string_array(struct fwnode_handle *fwnode,
++ const char *propname, const char **val,
++ size_t nval)
+{
-+ if (!child)
-+ return -EINVAL;
++ if (is_of_node(fwnode))
++ return of_property_read_string_array(of_node(fwnode), propname,
++ val, nval);
++ else if (is_acpi_node(fwnode))
++ return acpi_dev_prop_read(acpi_node(fwnode), propname,
++ DEV_PROP_STRING, val, nval);
+
-+ 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 -ENXIO;
++}
++EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
+
-+ return -ENODATA;
++/**
++ * fwnode_property_read_string - return a string property of a firmware node
++ * @fwnode: Firmware node to get the property of
++ * @propname: Name of the property
++ * @val: The value is stored here
++ *
++ * Read property @propname from the given firmware node and store the value into
++ * @val if found. The value is checked to be a string.
++ *
++ * Return: %0 if the property was found (success),
++ * %-EINVAL if given arguments are not valid,
++ * %-ENODATA if the property does not have a value,
++ * %-EPROTO or %-EILSEQ if the property is not a string,
++ * %-ENXIO if no suitable firmware interface is present.
++ */
++int fwnode_property_read_string(struct fwnode_handle *fwnode,
++ const char *propname, const char **val)
++{
++ if (is_of_node(fwnode))
++ return of_property_read_string(of_node(fwnode),propname, val);
++ else if (is_acpi_node(fwnode))
++ return acpi_dev_prop_read(acpi_node(fwnode), propname,
++ DEV_PROP_STRING, val, 1);
++
++ return -ENXIO;
+}
-+EXPORT_SYMBOL_GPL(device_read_child_property_array);
++EXPORT_SYMBOL_GPL(fwnode_property_read_string);
+
+/**
-+ * 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
++ * device_get_next_child_node - Return the next child node handle for a device
++ * @dev: Device to find the next child node for.
++ * @child: Handle to one of the device's child nodes or a null handle.
+ */
-+int device_for_each_child_node(struct device *dev,
-+ int (*fn)(struct device *dev, void *child, void *data),
-+ void *data)
++struct fwnode_handle *device_get_next_child_node(struct device *dev,
++ struct fwnode_handle *child)
+{
-+ if (IS_ENABLED(CONFIG_OF) && dev->of_node)
-+ return of_for_each_child_node(dev, fn, data);
++ if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
++ struct device_node *node;
++
++ node = of_get_next_available_child(dev->of_node, of_node(child));
++ if (node)
++ return &node->fwnode;
++ } else if (IS_ENABLED(CONFIG_ACPI)) {
++ struct acpi_device *node;
+
-+ return acpi_for_each_child_node(dev, fn, data);
++ node = acpi_get_next_child(dev, acpi_node(child));
++ if (node)
++ return acpi_fwnode_handle(node);
++ }
++ return NULL;
+}
-+EXPORT_SYMBOL_GPL(device_for_each_child_node);
++EXPORT_SYMBOL_GPL(device_get_next_child_node);
+
-+static int increment_count(struct device *dev, void *child, void *data)
++/**
++ * fwnode_handle_put - Drop reference to a device node
++ * @fwnode: Pointer to the device node to drop the reference to.
++ *
++ * This has to be used when terminating device_for_each_child_node() iteration
++ * with break or return to prevent stale device node references from being left
++ * behind.
++ */
++void fwnode_handle_put(struct fwnode_handle *fwnode)
+{
-+ *((unsigned int *)data) += 1;
-+ return 0;
++ if (is_of_node(fwnode))
++ of_node_put(of_node(fwnode));
+}
++EXPORT_SYMBOL_GPL(fwnode_handle_put);
+
+/**
+ * device_get_child_node_count - return the number of child nodes for device
@@ -4640,14 +7286,17 @@ index 0000000..7bf5708
+ */
+unsigned int device_get_child_node_count(struct device *dev)
+{
++ struct fwnode_handle *child;
+ unsigned int count = 0;
+
-+ device_for_each_child_node(dev, increment_count, &count);
++ device_for_each_child_node(dev, child)
++ 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
+index 43005d4..c9411e6 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -21,6 +21,7 @@
@@ -4683,8 +7332,7 @@ index 2133f9d..b73392b 100644
if (cntbase)
arch_timer_rate = readl_relaxed(cntbase + CNTFRQ);
else
-
-@@ -687,20 +694,8 @@ static void __init arch_timer_common_init(void)
+@@ -687,20 +693,8 @@ static void __init arch_timer_common_init(void)
arch_timer_arch_init();
}
@@ -4706,7 +7354,7 @@ index 2133f9d..b73392b 100644
/*
* 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)
+@@ -719,13 +713,31 @@ static void __init arch_timer_init(struct device_node *np)
}
}
@@ -4742,7 +7390,7 @@ index 2133f9d..b73392b 100644
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)
+@@ -792,3 +804,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);
@@ -4814,25 +7462,207 @@ index 2133f9d..b73392b 100644
+ acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
+}
+#endif
+diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
+index 17afc51..c5f7b4e 100644
+--- a/drivers/firmware/dmi_scan.c
++++ b/drivers/firmware/dmi_scan.c
+@@ -93,6 +93,12 @@ static void dmi_table(u8 *buf, int len, int num,
+ const struct dmi_header *dm = (const struct dmi_header *)data;
+
+ /*
++ * 7.45 End-of-Table (Type 127) [SMBIOS reference spec v3.0.0]
++ */
++ if (dm->type == DMI_ENTRY_END_OF_TABLE)
++ break;
++
++ /*
+ * We want to know the total length (formatted area and
+ * strings) before decoding to make sure we won't run off the
+ * table in dmi_decode or dmi_string
+@@ -107,7 +113,7 @@ static void dmi_table(u8 *buf, int len, int num,
+ }
+ }
+
+-static u32 dmi_base;
++static phys_addr_t dmi_base;
+ static u16 dmi_len;
+ static u16 dmi_num;
+
+@@ -467,7 +473,7 @@ static int __init dmi_present(const u8 *buf)
+
+ if (memcmp(buf, "_SM_", 4) == 0 &&
+ buf[5] < 32 && dmi_checksum(buf, buf[5])) {
+- smbios_ver = (buf[6] << 8) + buf[7];
++ smbios_ver = get_unaligned_be16(buf + 6);
+
+ /* Some BIOS report weird SMBIOS version, fix that up */
+ switch (smbios_ver) {
+@@ -489,10 +495,9 @@ static int __init dmi_present(const u8 *buf)
+ buf += 16;
+
+ if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) {
+- dmi_num = (buf[13] << 8) | buf[12];
+- dmi_len = (buf[7] << 8) | buf[6];
+- dmi_base = (buf[11] << 24) | (buf[10] << 16) |
+- (buf[9] << 8) | buf[8];
++ dmi_num = get_unaligned_le16(buf + 12);
++ dmi_len = get_unaligned_le16(buf + 6);
++ dmi_base = get_unaligned_le32(buf + 8);
+
+ if (dmi_walk_early(dmi_decode) == 0) {
+ if (smbios_ver) {
+@@ -514,12 +519,72 @@ static int __init dmi_present(const u8 *buf)
+ return 1;
+ }
+
++/*
++ * Check for the SMBIOS 3.0 64-bit entry point signature. Unlike the legacy
++ * 32-bit entry point, there is no embedded DMI header (_DMI_) in here.
++ */
++static int __init dmi_smbios3_present(const u8 *buf)
++{
++ if (memcmp(buf, "_SM3_", 5) == 0 &&
++ buf[6] < 32 && dmi_checksum(buf, buf[6])) {
++ dmi_ver = get_unaligned_be16(buf + 7);
++ dmi_len = get_unaligned_le32(buf + 12);
++ dmi_base = get_unaligned_le64(buf + 16);
++
++ /*
++ * The 64-bit SMBIOS 3.0 entry point no longer has a field
++ * containing the number of structures present in the table.
++ * Instead, it defines the table size as a maximum size, and
++ * relies on the end-of-table structure type (#127) to be used
++ * to signal the end of the table.
++ * So let's define dmi_num as an upper bound as well: each
++ * structure has a 4 byte header, so dmi_len / 4 is an upper
++ * bound for the number of structures in the table.
++ */
++ dmi_num = dmi_len / 4;
++
++ if (dmi_walk_early(dmi_decode) == 0) {
++ pr_info("SMBIOS %d.%d present.\n",
++ dmi_ver >> 8, dmi_ver & 0xFF);
++ dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string));
++ pr_debug("DMI: %s\n", dmi_ids_string);
++ return 0;
++ }
++ }
++ return 1;
++}
++
+ void __init dmi_scan_machine(void)
+ {
+ char __iomem *p, *q;
+ char buf[32];
+
+ if (efi_enabled(EFI_CONFIG_TABLES)) {
++ /*
++ * According to the DMTF SMBIOS reference spec v3.0.0, it is
++ * allowed to define both the 64-bit entry point (smbios3) and
++ * the 32-bit entry point (smbios), in which case they should
++ * either both point to the same SMBIOS structure table, or the
++ * table pointed to by the 64-bit entry point should contain a
++ * superset of the table contents pointed to by the 32-bit entry
++ * point (section 5.2)
++ * This implies that the 64-bit entry point should have
++ * precedence if it is defined and supported by the OS. If we
++ * have the 64-bit entry point, but fail to decode it, fall
++ * back to the legacy one (if available)
++ */
++ if (efi.smbios3 != EFI_INVALID_TABLE_ADDR) {
++ p = dmi_early_remap(efi.smbios3, 32);
++ if (p == NULL)
++ goto error;
++ memcpy_fromio(buf, p, 32);
++ dmi_early_unmap(p, 32);
++
++ if (!dmi_smbios3_present(buf)) {
++ dmi_available = 1;
++ goto out;
++ }
++ }
+ if (efi.smbios == EFI_INVALID_TABLE_ADDR)
+ goto error;
+
+@@ -552,7 +617,7 @@ void __init dmi_scan_machine(void)
+ memset(buf, 0, 16);
+ for (q = p; q < p + 0x10000; q += 16) {
+ memcpy_fromio(buf + 16, q, 16);
+- if (!dmi_present(buf)) {
++ if (!dmi_smbios3_present(buf) || !dmi_present(buf)) {
+ dmi_available = 1;
+ dmi_early_unmap(p, 0x10000);
+ goto out;
+diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
+index 8590099..9035c1b 100644
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -30,6 +30,7 @@ struct efi __read_mostly efi = {
+ .acpi = EFI_INVALID_TABLE_ADDR,
+ .acpi20 = EFI_INVALID_TABLE_ADDR,
+ .smbios = EFI_INVALID_TABLE_ADDR,
++ .smbios3 = EFI_INVALID_TABLE_ADDR,
+ .sal_systab = EFI_INVALID_TABLE_ADDR,
+ .boot_info = EFI_INVALID_TABLE_ADDR,
+ .hcdp = EFI_INVALID_TABLE_ADDR,
+@@ -86,6 +87,8 @@ static ssize_t systab_show(struct kobject *kobj,
+ str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
+ if (efi.smbios != EFI_INVALID_TABLE_ADDR)
+ str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
++ if (efi.smbios3 != EFI_INVALID_TABLE_ADDR)
++ str += sprintf(str, "SMBIOS3=0x%lx\n", efi.smbios3);
+ if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
+ str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
+ if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
+@@ -260,6 +263,7 @@ static __initdata efi_config_table_type_t common_tables[] = {
+ {MPS_TABLE_GUID, "MPS", &efi.mps},
+ {SAL_SYSTEM_TABLE_GUID, "SALsystab", &efi.sal_systab},
+ {SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios},
++ {SMBIOS3_TABLE_GUID, "SMBIOS 3.0", &efi.smbios3},
+ {UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga},
+ {NULL_GUID, NULL, NULL},
+ };
+diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
+index 75ee059..eb48a1a 100644
+--- a/drivers/firmware/efi/libstub/arm-stub.c
++++ b/drivers/firmware/efi/libstub/arm-stub.c
+@@ -247,9 +247,18 @@ unsigned long __init efi_entry(void *handle, efi_system_table_t *sys_table,
+ goto fail_free_cmdline;
+ }
+ }
+- if (!fdt_addr)
++
++ if (fdt_addr) {
++ pr_efi(sys_table, "Using DTB from command line\n");
++ } else {
+ /* Look for a device tree configuration table entry. */
+ fdt_addr = (uintptr_t)get_fdt(sys_table);
++ if (fdt_addr)
++ pr_efi(sys_table, "Using DTB from configuration table\n");
++ }
++
++ if (!fdt_addr)
++ pr_efi(sys_table, "Generating empty DTB\n");
+
+ status = handle_cmdline_files(sys_table, image, cmdline_ptr,
+ "initrd=", dram_base + SZ_512M,
diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c
-index 954b9f6..a1f7e55 100644
+index 954b9f6..13dbd3d 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,
+@@ -109,6 +109,38 @@ 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()
++ * devm_get_gpiod_from_child - get a GPIO descriptor from a device's child node
+ * @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 *devm_get_gpiod_from_child(struct device *dev,
++ struct fwnode_handle *child)
+{
+ struct gpio_desc **dr;
+ struct gpio_desc *desc;
@@ -4842,7 +7672,7 @@ index 954b9f6..a1f7e55 100644
+ if (!dr)
+ return ERR_PTR(-ENOMEM);
+
-+ desc = dev_get_named_gpiod_from_child(dev, child, propname, index);
++ desc = fwnode_get_named_gpiod(child, "gpios");
+ if (IS_ERR(desc)) {
+ devres_free(dr);
+ return desc;
@@ -4853,7 +7683,7 @@ index 954b9f6..a1f7e55 100644
+
+ return desc;
+}
-+EXPORT_SYMBOL(devm_get_named_gpiod_from_child);
++EXPORT_SYMBOL(devm_get_gpiod_from_child);
+
+/**
* devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
@@ -5267,10 +8097,48 @@ index 41e91d7..99720c8 100644
}
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
-index 05c6275..8aa6ca4 100644
+index 05c6275..ba98bb5 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)
+@@ -287,9 +287,45 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
+ }
+ }
+
++int acpi_dev_add_driver_gpios(struct acpi_device *adev,
++ const struct acpi_gpio_mapping *gpios)
++{
++ if (adev && gpios) {
++ adev->driver_gpios = gpios;
++ return 0;
++ }
++ return -EINVAL;
++}
++EXPORT_SYMBOL_GPL(acpi_dev_add_driver_gpios);
++
++static bool acpi_get_driver_gpio_data(struct acpi_device *adev,
++ const char *name, int index,
++ struct acpi_reference_args *args)
++{
++ const struct acpi_gpio_mapping *gm;
++
++ if (!adev->driver_gpios)
++ return false;
++
++ for (gm = adev->driver_gpios; gm->name; gm++)
++ if (!strcmp(name, gm->name) && gm->data && index < gm->size) {
++ const struct acpi_gpio_params *par = gm->data + index;
++
++ args->adev = adev;
++ args->args[0] = par->crs_entry_index;
++ args->args[1] = par->line_index;
++ args->args[2] = par->active_low;
++ args->nargs = 3;
++ return true;
++ }
++
++ return false;
++}
++
struct acpi_gpio_lookup {
struct acpi_gpio_info info;
int index;
@@ -5278,7 +8146,7 @@ index 05c6275..8aa6ca4 100644
struct gpio_desc *desc;
int n;
};
-@@ -303,13 +304,24 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
+@@ -303,13 +339,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;
@@ -5306,7 +8174,7 @@ index 05c6275..8aa6ca4 100644
}
return 1;
-@@ -317,40 +329,75 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
+@@ -317,40 +364,79 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
/**
* acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources
@@ -5361,10 +8229,14 @@ index 05c6275..8aa6ca4 100644
+ dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname);
+
+ memset(&args, 0, sizeof(args));
-+ ret = acpi_dev_get_property_reference(adev, propname, NULL,
++ ret = acpi_dev_get_property_reference(adev, propname,
+ index, &args);
-+ if (ret)
-+ return ERR_PTR(ret);
++ if (ret) {
++ bool found = acpi_get_driver_gpio_data(adev, propname,
++ index, &args);
++ if (!found)
++ return ERR_PTR(ret);
++ }
+
+ /*
+ * The property was found and resolved so need to
@@ -5392,7 +8264,7 @@ index 05c6275..8aa6ca4 100644
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,
+@@ -359,8 +445,11 @@ struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
acpi_dev_free_resource_list(&resource_list);
@@ -5406,7 +8278,7 @@ index 05c6275..8aa6ca4 100644
return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT);
}
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
-index e8e98ca..0fa5f79 100644
+index e8e98ca..58659db 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,
@@ -5433,7 +8305,7 @@ index e8e98ca..0fa5f79 100644
+ suffixes[i]);
+ }
+
-+ desc = acpi_get_gpiod_by_index(adev, propname, 0, &info);
++ desc = acpi_get_gpiod_by_index(adev, propname, idx, &info);
+ if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER))
+ break;
+ }
@@ -5450,19 +8322,16 @@ index e8e98ca..0fa5f79 100644
*flags |= GPIO_ACTIVE_LOW;
return desc;
-@@ -1713,6 +1735,62 @@ struct gpio_desc *__must_check __gpiod_get_index(struct device *dev,
+@@ -1713,6 +1735,61 @@ 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
++ * fwnode_get_named_gpiod - obtain a GPIO from firmware node
++ * @fwnode: handle of the firmware node
++ * @propname: name of the firmware property representing the GPIO
+ *
+ * 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.
++ * from firmware.
+ *
+ * Function properly finds the corresponding GPIO using whatever is the
+ * underlying firmware interface and then makes sure that the GPIO
@@ -5470,26 +8339,28 @@ index e8e98ca..0fa5f79 100644
+ *
+ * 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 *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
++ const char *propname)
+{
+ struct gpio_desc *desc = ERR_PTR(-ENODEV);
+ bool active_low = false;
+ int ret;
+
-+ if (!child)
++ if (!fwnode)
+ return ERR_PTR(-EINVAL);
+
-+ if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
++ if (is_of_node(fwnode)) {
+ enum of_gpio_flags flags;
+
-+ desc = of_get_named_gpiod_flags(child, propname, index, &flags);
++ desc = of_get_named_gpiod_flags(of_node(fwnode), propname, 0,
++ &flags);
+ if (!IS_ERR(desc))
+ active_low = flags & OF_GPIO_ACTIVE_LOW;
-+ } else if (ACPI_COMPANION(dev)) {
++ } else if (is_acpi_node(fwnode)) {
+ struct acpi_gpio_info info;
+
-+ desc = acpi_get_gpiod_by_index(child, propname, index, &info);
++ desc = acpi_get_gpiod_by_index(acpi_node(fwnode), propname, 0,
++ &info);
+ if (!IS_ERR(desc))
+ active_low = info.active_low;
+ }
@@ -5507,7 +8378,7 @@ index e8e98ca..0fa5f79 100644
+
+ return desc;
+}
-+EXPORT_SYMBOL_GPL(dev_get_named_gpiod_from_child);
++EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod);
+
+/**
* gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO
@@ -5539,7 +8410,7 @@ index 9db2b6a..e3a5211 100644
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
+index 432d363..c9c1c8c 100644
--- a/drivers/input/keyboard/gpio_keys_polled.c
+++ b/drivers/input/keyboard/gpio_keys_polled.c
@@ -23,10 +23,9 @@
@@ -5574,59 +8445,17 @@ index 432d363..3563850 100644
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)
+@@ -102,21 +100,15 @@ 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;
++ struct fwnode_handle *child;
int error;
int nbuttons;
- int i;
@@ -5640,7 +8469,7 @@ index 432d363..3563850 100644
if (nbuttons == 0)
return NULL;
-@@ -126,54 +160,14 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct
+@@ -126,52 +118,44 @@ 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);
@@ -5648,14 +8477,16 @@ index 432d363..3563850 100644
- 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);
++ pdata->rep = device_property_present(dev, "autorepeat");
+ 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;
--
++ device_for_each_child_node(dev, child) {
++ struct gpio_desc *desc;
+
- if (!of_find_property(pp, "gpios", NULL)) {
- pdata->nbuttons--;
- dev_warn(dev, "Found button without gpios\n");
@@ -5665,43 +8496,53 @@ index 432d363..3563850 100644
- 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);
-- }
--
++ desc = devm_get_gpiod_from_child(dev, child);
++ if (IS_ERR(desc)) {
++ error = PTR_ERR(desc);
+ if (error != -EPROBE_DEFER)
+ dev_err(dev,
+ "Failed to get gpio flags, error: %d\n",
+ error);
++ fwnode_handle_put(child);
+ return ERR_PTR(error);
+ }
+
- button = &pdata->buttons[i++];
-
- button->gpio = gpio;
- button->active_low = flags & OF_GPIO_ACTIVE_LOW;
--
++ button = &pdata->buttons[pdata->nbuttons++];
++ button->gpiod = desc;
+
- 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);
-- }
--
++ if (fwnode_property_read_u32(child, "linux,code", &button->code)) {
++ dev_err(dev, "Button without keycode: %d\n",
++ pdata->nbuttons - 1);
++ fwnode_handle_put(child);
+ return ERR_PTR(-EINVAL);
+ }
+
- button->desc = of_get_property(pp, "label", NULL);
--
++ fwnode_property_read_string(child, "label", &button->desc);
+
- if (of_property_read_u32(pp, "linux,input-type", &button->type))
-- button->type = EV_KEY;
--
++ if (fwnode_property_read_u32(child, "linux,input-type",
++ &button->type))
+ button->type = EV_KEY;
+
- button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);
--
++ button->wakeup = fwnode_property_present(child, "gpio-key,wakeup");
+
- 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[] = {
++ if (fwnode_property_read_u32(child, "debounce-interval",
++ &button->debounce_interval))
+ button->debounce_interval = 5;
+ }
+
+@@ -187,15 +171,6 @@ static const struct of_device_id gpio_keys_polled_of_match[] = {
};
MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match);
@@ -5713,15 +8554,11 @@ index 432d363..3563850 100644
- 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)
+ struct device *dev = &pdev->dev;
+@@ -259,7 +234,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];
@@ -5729,7 +8566,7 @@ index 432d363..3563850 100644
unsigned int type = button->type ?: EV_KEY;
if (button->wakeup) {
-@@ -267,15 +257,31 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
+@@ -267,15 +241,31 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
return -EINVAL;
}
@@ -5768,16 +8605,41 @@ index 432d363..3563850 100644
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 = {
+@@ -308,7 +298,7 @@ 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/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
+index 60558f7..3b92862 100644
+--- a/drivers/iommu/arm-smmu.c
++++ b/drivers/iommu/arm-smmu.c
+@@ -444,7 +444,10 @@ static struct device_node *dev_get_dev_node(struct device *dev)
+
+ while (!pci_is_root_bus(bus))
+ bus = bus->parent;
+- return bus->bridge->parent->of_node;
++ if (bus->bridge->parent)
++ return bus->bridge->parent->of_node;
++ else
++ return NULL;
+ }
+
+ return dev->of_node;
+@@ -560,6 +563,9 @@ static struct arm_smmu_device *find_smmu_for_device(struct device *dev)
+ struct arm_smmu_master *master = NULL;
+ struct device_node *dev_node = dev_get_dev_node(dev);
+
++ if (!dev_node)
++ return NULL;
++
+ spin_lock(&arm_smmu_devices_lock);
+ list_for_each_entry(smmu, &arm_smmu_devices, list) {
+ master = find_smmu_master(smmu, dev_node);
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
@@ -5973,10 +8835,11 @@ index 0fe2f71..9106c6d 100644
+ acpi_gic_init();
}
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
-index 57ff20f..681efd5 100644
+index b4518c8..b3c5d9d 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
-@@ -13,22 +13,20 @@
+@@ -12,25 +12,23 @@
+ */
#include <linux/err.h>
#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
@@ -6000,22 +8863,20 @@ index 57ff20f..681efd5 100644
u8 can_sleep;
- u8 active_low;
u8 blinking;
- int (*platform_gpio_blink_set)(unsigned gpio, int state,
+- int (*platform_gpio_blink_set)(unsigned gpio, int state,
++ int (*platform_gpio_blink_set)(struct gpio_desc *desc, int state,
unsigned long *delay_on, unsigned long *delay_off);
-@@ -40,12 +38,16 @@ static void gpio_led_work(struct work_struct *work)
+ };
+
+@@ -40,12 +38,11 @@ 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->platform_gpio_blink_set(led_dat->gpiod,
++ led_dat->new_level, NULL, NULL);
led_dat->blinking = 0;
} else
- gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level);
@@ -6023,7 +8884,7 @@ index 57ff20f..681efd5 100644
}
static void gpio_led_set(struct led_classdev *led_cdev,
-@@ -60,9 +62,6 @@ static void gpio_led_set(struct led_classdev *led_cdev,
+@@ -60,9 +57,6 @@ static void gpio_led_set(struct led_classdev *led_cdev,
else
level = 1;
@@ -6033,19 +8894,13 @@ index 57ff20f..681efd5 100644
/* 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,
+@@ -72,11 +66,11 @@ 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->platform_gpio_blink_set(led_dat->gpiod, level,
+ NULL, NULL);
led_dat->blinking = 0;
} else
- gpio_set_value(led_dat->gpio, level);
@@ -6053,25 +8908,39 @@ index 57ff20f..681efd5 100644
}
}
-@@ -85,9 +89,10 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
- {
- struct gpio_led_data *led_dat =
+@@ -87,34 +81,49 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
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,
++ return led_dat->platform_gpio_blink_set(led_dat->gpiod, GPIO_LED_BLINK,
delay_on, delay_off);
}
-@@ -97,24 +102,33 @@ static int create_gpio_led(const struct gpio_led *template,
+ static int create_gpio_led(const struct gpio_led *template,
+ struct gpio_led_data *led_dat, struct device *parent,
+- int (*blink_set)(unsigned, int, unsigned long *, unsigned long *))
++ int (*blink_set)(struct gpio_desc *, int, unsigned long *,
++ unsigned long *))
{
int ret, state;
- led_dat->gpio = -1;
-+ if (!template->gpiod) {
++ led_dat->gpiod = template->gpiod;
++ if (!led_dat->gpiod) {
++ /*
++ * This is the legacy code path for platform code that
++ * still uses GPIO numbers. Ultimately we would like to get
++ * rid of this block completely.
++ */
+ unsigned long flags = 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;
++ }
- /* skip leds that aren't available */
- if (!gpio_is_valid(template->gpio)) {
@@ -6079,19 +8948,12 @@ index 57ff20f..681efd5 100644
- 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;
-+ }
++ if (template->active_low)
++ flags |= GPIOF_ACTIVE_LOW;
- ret = devm_gpio_request(parent, template->gpio, template->name);
- if (ret < 0)
- return ret;
-+ if (template->active_low)
-+ flags |= GPIOF_ACTIVE_LOW;
-+
+ ret = devm_gpio_request_one(parent, template->gpio, flags,
+ template->name);
+ if (ret < 0)
@@ -6107,12 +8969,11 @@ index 57ff20f..681efd5 100644
- 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->can_sleep = gpiod_cansleep(led_dat->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,
+@@ -122,30 +131,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)
@@ -6146,54 +9007,24 @@ index 57ff20f..681efd5 100644
led_classdev_unregister(&led->cdev);
cancel_work_sync(&led->work);
}
-@@ -161,65 +169,59 @@ static inline int sizeof_gpio_leds_priv(int num_leds)
+@@ -161,40 +164,37 @@ static inline int sizeof_gpio_leds_priv(int num_leds)
(sizeof(struct gpio_led_data) * num_leds);
}
-/* 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;
-+ }
-+
-+ if (!device_get_child_property(dev, child, "retain-state-suspended", NULL))
-+ led.retain_state_suspended = 1;
-+
-+ 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 device *dev = &pdev->dev;
++ struct fwnode_handle *child;
struct gpio_leds_priv *priv;
-- int count, ret;
-+ int ret, count;
+ int count, ret;
- /* 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);
++ count = device_get_child_node_count(dev);
if (!count)
return ERR_PTR(-ENODEV);
@@ -6201,13 +9032,15 @@ index 57ff20f..681efd5 100644
- 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);
+- priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count),
+- GFP_KERNEL);
++ priv = devm_kzalloc(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 = {};
++ device_for_each_child_node(dev, child) {
+ struct gpio_led led = {};
- enum of_gpio_flags flags;
- const char *state;
-
@@ -6218,40 +9051,41 @@ index 57ff20f..681efd5 100644
- 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;
-- }
--
++ const char *state = NULL;
++
++ led.gpiod = devm_get_gpiod_from_child(dev, child);
++ if (IS_ERR(led.gpiod)) {
++ fwnode_handle_put(child);
++ goto err;
++ }
++
++ fwnode_property_read_string(child, "label", &led.name);
++ fwnode_property_read_string(child, "linux,default-trigger",
++ &led.default_trigger);
++
++ if (!fwnode_property_read_string(child, "linux,default_state",
++ &state)) {
+ if (!strcmp(state, "keep"))
+ led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
+ else if (!strcmp(state, "on"))
+@@ -203,13 +203,13 @@ static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
+ 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++],
++ if (fwnode_property_present(child, "retain-state-suspended"))
+ led.retain_state_suspended = 1;
+
+ ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
- &pdev->dev, NULL);
-- if (ret < 0) {
++ 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);
++ fwnode_handle_put(child);
+ goto err;
+ }
}
-
- return priv;
--
--err:
-- for (count = priv->num_leds - 2; count >= 0; count--)
-- delete_gpio_led(&priv->leds[count]);
-- return ERR_PTR(-ENODEV);
- }
-
- static const struct of_device_id of_gpio_leds_match[] = {
-@@ -228,12 +228,13 @@ static const struct of_device_id of_gpio_leds_match[] = {
+@@ -228,12 +228,6 @@ static const struct of_device_id of_gpio_leds_match[] = {
};
MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
@@ -6261,17 +9095,10 @@ index 57ff20f..681efd5 100644
- return ERR_PTR(-ENODEV);
-}
-#endif /* CONFIG_OF_GPIO */
-+
-+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 int gpio_led_probe(struct platform_device *pdev)
{
-@@ -263,7 +265,7 @@ static int gpio_led_probe(struct platform_device *pdev)
+@@ -261,7 +255,7 @@ static int gpio_led_probe(struct platform_device *pdev)
}
}
} else {
@@ -6280,18 +9107,17 @@ index 57ff20f..681efd5 100644
if (IS_ERR(priv))
return PTR_ERR(priv);
}
-@@ -290,7 +292,8 @@ static struct platform_driver gpio_led_driver = {
+@@ -288,7 +282,7 @@ 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
+index 634f729..0a1af93 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -18,7 +18,7 @@
@@ -6352,7 +9178,7 @@ index 634f729..1a760cd 100644
return -ENODEV;
}
- if (of_find_property(np, "read-only", NULL))
-+ if (!device_get_property(dev, "read-only", NULL))
++ if (device_property_present(dev, "read-only"))
chip->flags |= EE_READONLY;
}
return 0;
@@ -6381,25 +9207,6 @@ index 634f729..1a760cd 100644
} else
chip = *(struct spi_eeprom *)spi->dev.platform_data;
-@@ -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
@@ -6455,7 +9262,7 @@ index 9da3a03..a34cad2 100644
* 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
+index 2349ea9..a04b18b 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)
@@ -6469,7 +9276,7 @@ index 2955499..423ae3d 100644
}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
-index f5a8fa0..db29dec 100644
+index f5a8fa0..338c0ed 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
@@ -124,6 +124,7 @@
@@ -6480,7 +9287,7 @@ index f5a8fa0..db29dec 100644
#include "xgbe.h"
#include "xgbe-common.h"
-@@ -215,6 +216,210 @@ static void xgbe_init_all_fptrs(struct xgbe_prv_data *pdata)
+@@ -215,6 +216,205 @@ static void xgbe_init_all_fptrs(struct xgbe_prv_data *pdata)
xgbe_init_function_ptrs_desc(&pdata->desc_if);
}
@@ -6567,12 +9374,7 @@ index f5a8fa0..db29dec 100644
+ 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" */
@@ -6691,7 +9493,7 @@ index f5a8fa0..db29dec 100644
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)
+@@ -222,8 +422,6 @@ static int xgbe_probe(struct platform_device *pdev)
struct xgbe_desc_if *desc_if;
struct net_device *netdev;
struct device *dev = &pdev->dev;
@@ -6700,7 +9502,7 @@ index f5a8fa0..db29dec 100644
int ret;
DBGPR("--> xgbe_probe\n");
-@@ -239,6 +442,7 @@ static int xgbe_probe(struct platform_device *pdev)
+@@ -239,6 +437,7 @@ static int xgbe_probe(struct platform_device *pdev)
pdata = netdev_priv(netdev);
pdata->netdev = netdev;
pdata->pdev = pdev;
@@ -6708,7 +9510,7 @@ index f5a8fa0..db29dec 100644
pdata->dev = dev;
platform_set_drvdata(pdev, netdev);
-@@ -264,40 +468,13 @@ static int xgbe_probe(struct platform_device *pdev)
+@@ -264,40 +463,13 @@ static int xgbe_probe(struct platform_device *pdev)
goto err_io;
}
@@ -6755,7 +9557,7 @@ index f5a8fa0..db29dec 100644
/* Set the DMA mask */
if (!dev->dma_mask)
-@@ -308,23 +485,16 @@ static int xgbe_probe(struct platform_device *pdev)
+@@ -308,23 +480,16 @@ static int xgbe_probe(struct platform_device *pdev)
goto err_io;
}
@@ -6782,7 +9584,7 @@ index f5a8fa0..db29dec 100644
/* Set all the function pointers */
xgbe_init_all_fptrs(pdata);
-@@ -337,23 +507,6 @@ static int xgbe_probe(struct platform_device *pdev)
+@@ -337,23 +502,6 @@ static int xgbe_probe(struct platform_device *pdev)
/* Populate the hardware features */
xgbe_get_all_hw_features(pdata);
@@ -6806,7 +9608,7 @@ index f5a8fa0..db29dec 100644
/* Set default configuration data */
xgbe_default_config(pdata);
-@@ -531,10 +684,22 @@ static int xgbe_resume(struct device *dev)
+@@ -531,10 +679,22 @@ static int xgbe_resume(struct device *dev)
}
#endif /* CONFIG_PM */
@@ -6829,7 +9631,7 @@ index f5a8fa0..db29dec 100644
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);
+@@ -542,7 +702,12 @@ static SIMPLE_DEV_PM_OPS(xgbe_pm_ops, xgbe_suspend, xgbe_resume);
static struct platform_driver xgbe_driver = {
.driver = {
.name = "amd-xgbe",
@@ -7272,10 +10074,10 @@ index 874e5a0..8b7e2cf 100644
#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
+index 2c62208..98e22544 100644
--- a/drivers/net/ethernet/smsc/smc91x.c
+++ b/drivers/net/ethernet/smsc/smc91x.c
-@@ -81,6 +81,7 @@ static const char version[] =
+@@ -82,6 +82,7 @@ static const char version[] =
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
@@ -7283,7 +10085,7 @@ index 5e94d00..a6131a9 100644
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
-@@ -2405,6 +2406,14 @@ static struct dev_pm_ops smc_drv_pm_ops = {
+@@ -2463,6 +2464,14 @@ static struct dev_pm_ops smc_drv_pm_ops = {
.resume = smc_drv_resume,
};
@@ -7298,7 +10100,7 @@ index 5e94d00..a6131a9 100644
static struct platform_driver smc_driver = {
.probe = smc_drv_probe,
.remove = smc_drv_remove,
-@@ -2413,6 +2422,7 @@ static struct platform_driver smc_driver = {
+@@ -2471,6 +2480,7 @@ static struct platform_driver smc_driver = {
.owner = THIS_MODULE,
.pm = &smc_drv_pm_ops,
.of_match_table = of_match_ptr(smc91x_match),
@@ -8472,7 +11274,7 @@ index c456559..d852c6e 100644
devm_kfree(dev, priv);
}
diff --git a/drivers/of/base.c b/drivers/of/base.c
-index 2305dc0..43999a8 100644
+index 3823edf..4c2ccde 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,
@@ -8515,170 +11317,215 @@ index 2305dc0..43999a8 100644
* 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)
+diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
+index 9ecabfa..9029d59c 100644
+--- a/drivers/pci/host/pci-xgene.c
++++ b/drivers/pci/host/pci-xgene.c
+@@ -29,6 +29,7 @@
+ #include <linux/pci.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
++#include <linux/acpi.h>
+
+ #define PCIECORE_CTLANDSTATUS 0x50
+ #define PIM1_1L 0x80
+@@ -235,6 +236,13 @@ static int xgene_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
+ break;
+ case 2:
+ xgene_pcie_cfg_in16(addr, offset, val);
++ /* FIXME.
++ * Something wrong with Configuration Request Retry Status
++ * on this hw. Pretend it isn't supported until the problem
++ * gets sorted out properly.
++ */
++ if (pci_is_root_bus(bus) && offset == (0x40 + PCI_EXP_RTCAP))
++ *val &= ~PCI_EXP_RTCAP_CRSVIS;
+ break;
+ default:
+ xgene_pcie_cfg_in32(addr, offset, val);
+@@ -600,6 +608,165 @@ static int xgene_pcie_setup(struct xgene_pcie_port *port,
+ return 0;
}
- 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.
++#ifdef CONFIG_ACPI
++struct xgene_mcfg_info {
++ void __iomem *csr_base;
++};
++
++/*
++ * 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.
+ */
-+int of_property_read_string_array(struct device_node *np, const char *propname,
-+ char **output, size_t sz)
++static void __iomem *__get_cfg_base(struct pci_mmcfg_region *cfg,
++ unsigned int bus)
+{
-+ struct property *prop = of_find_property(np, propname, NULL);
-+ int i = 0;
-+ size_t l = 0, total = 0;
-+ char *p;
++ if (bus > cfg->start_bus)
++ return cfg->virt + AXI_EP_CFG_ACCESS;
+
-+ if (!prop)
-+ return -EINVAL;
-+
-+ if (!prop->value)
-+ return -ENODATA;
-+
-+ if (strnlen(prop->value, prop->length) >= prop->length)
-+ return -EOVERFLOW;
-+
-+ p = prop->value;
-+
-+ for (i = 0; total < prop->length; total += l, p += l) {
-+ output[i++] = p;
-+ l = strlen(p) + 1;
-+ }
-+ return 0;
++ return cfg->virt;
+}
+
- 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);
-+
-+int of_dev_prop_get(struct device_node *dn, const char *propname, void **valptr)
++/*
++ * For Configuration request, RTDID register is used as Bus Number,
++ * Device Number and Function number of the header fields.
++ */
++static void __set_rtdid_reg(struct pci_mmcfg_region *cfg,
++ unsigned int bus, unsigned int devfn)
+{
-+ struct property *pp = of_find_property(dn, propname, NULL);
++ struct xgene_mcfg_info *info = cfg->data;
++ unsigned int b, d, f;
++ u32 rtdid_val = 0;
+
-+ if (!pp)
-+ return -ENODATA;
++ b = bus;
++ d = PCI_SLOT(devfn);
++ f = PCI_FUNC(devfn);
+
-+ if (valptr)
-+ *valptr = pp->value;
-+ return 0;
++ if (bus != cfg->start_bus)
++ rtdid_val = (b << 8) | (d << 3) | f;
++
++ writel(rtdid_val, info->csr_base + RTDID);
++ /* read the register back to ensure flush */
++ readl(info->csr_base + RTDID);
+}
+
-+int of_dev_prop_read(struct device_node *dn, const char *propname,
-+ enum dev_prop_type proptype, void *val)
++static int xgene_raw_pci_read(struct pci_mmcfg_region *cfg, unsigned int bus,
++ unsigned int devfn, int offset, int len, u32 *val)
+{
-+ void *value;
-+ int ret = of_dev_prop_get(dn, propname, &value);
-+
-+ if (ret)
-+ return ret;
++ void __iomem *addr;
+
-+ if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
-+ switch (proptype) {
-+ case DEV_PROP_U8: {
-+ *(u8 *)val = *(u8 *)value;
-+ break;
++ if (bus == cfg->start_bus) {
++ if (devfn != 0) {
++ *val = 0xffffffff;
++ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
-+ case DEV_PROP_U16:
-+ *(u16 *)val = *(u16 *)value;
-+ break;
-+ case DEV_PROP_U32:
-+ *(u32 *)val = *(u32 *)value;
-+ break;
-+ default:
-+ *(u64 *)val = *(u64 *)value;
-+ break;
++
++ /* see xgene_pcie_hide_rc_bars() above */
++ if (offset == PCI_BASE_ADDRESS_0 ||
++ offset == PCI_BASE_ADDRESS_1) {
++ *val = 0;
++ return PCIBIOS_SUCCESSFUL;
+ }
-+ } else if (proptype == DEV_PROP_STRING) {
-+ *(char **)val = value;
+ }
-+ return ret;
+
++ __set_rtdid_reg(cfg, bus, devfn);
++ addr = __get_cfg_base(cfg, bus);
++ switch (len) {
++ case 1:
++ xgene_pcie_cfg_in8(addr, offset, val);
++ break;
++ case 2:
++ xgene_pcie_cfg_in16(addr, offset, val);
++ /* FIXME.
++ * Something wrong with Configuration Request Retry Status
++ * on this hw. Pretend it isn't supported until the problem
++ * gets sorted out properly.
++ */
++ if (bus == cfg->start_bus && offset == (0x40 + PCI_EXP_RTCAP))
++ *val &= ~PCI_EXP_RTCAP_CRSVIS;
++ break;
++ default:
++ xgene_pcie_cfg_in32(addr, offset, val);
++ break;
++ }
++ return PCIBIOS_SUCCESSFUL;
+}
+
-+int of_dev_prop_read_array(struct device_node *dn, const char *propname,
-+ enum dev_prop_type proptype, void *val, size_t nval)
++static int xgene_raw_pci_write(struct pci_mmcfg_region *cfg, unsigned int bus,
++ unsigned int devfn, int offset, int len, u32 val)
+{
-+ int ret, elem_size;
++ void __iomem *addr;
+
-+ 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);
-+ }
++ if (bus == cfg->start_bus && devfn != 0)
++ return PCIBIOS_DEVICE_NOT_FOUND;
+
-+ switch (proptype) {
-+ case DEV_PROP_U8:
-+ ret = of_property_read_u8_array(dn, propname, (u8 *)val, nval);
++ __set_rtdid_reg(cfg, bus, devfn);
++ addr = __get_cfg_base(cfg, bus);
++ switch (len) {
++ case 1:
++ xgene_pcie_cfg_out8(addr, offset, (u8)val);
+ 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);
++ case 2:
++ xgene_pcie_cfg_out16(addr, offset, (u16)val);
+ break;
+ default:
-+ ret = -EINVAL;
++ xgene_pcie_cfg_out32(addr, offset, val);
+ break;
+ }
-+ return ret;
++ return PCIBIOS_SUCCESSFUL;
+}
+
-+int of_for_each_child_node(struct device *dev,
-+ int (*fn)(struct device *dev, void *child, void *data),
-+ void *data)
++static acpi_status find_csr_base(struct acpi_resource *acpi_res, void *data)
+{
-+ struct device_node *child;
-+ int ret = 0;
++ struct pci_mmcfg_region *cfg = data;
++ struct xgene_mcfg_info *info = cfg->data;
++ struct acpi_resource_fixed_memory32 *fixed32;
+
-+ for_each_child_of_node(dev->of_node, child) {
-+ ret = fn(dev, child, data);
-+ if (ret)
-+ break;
++ if (acpi_res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) {
++ fixed32 = &acpi_res->data.fixed_memory32;
++ info->csr_base = ioremap(fixed32->address,
++ fixed32->address_length);
++ return AE_CTRL_TERMINATE;
+ }
-+ return ret;
++ return AE_OK;
+}
++
++static int xgene_mcfg_fixup(struct acpi_pci_root *root,
++ struct pci_mmcfg_region *cfg)
++{
++ struct acpi_device *device = root->device;
++ struct xgene_mcfg_info *info;
++
++ info = kzalloc(sizeof(*info), GFP_KERNEL);
++ if (info == NULL)
++ return -ENOMEM;
++
++ cfg->data = info;
++
++ acpi_walk_resources(device->handle, METHOD_NAME__CRS,
++ find_csr_base, cfg);
++
++ if (!info->csr_base) {
++ kfree(info);
++ cfg->data = NULL;
++ return -ENODEV;
++ }
++
++ cfg->read = xgene_raw_pci_read;
++ cfg->write = xgene_raw_pci_write;
++
++ /* actual last bus reachable through this mmconfig */
++ cfg->end_bus = root->secondary.end;
++
++ /* firmware should have done this */
++ xgene_raw_pci_write(cfg, cfg->start_bus, 0, PCI_PRIMARY_BUS, 4,
++ cfg->start_bus | ((cfg->start_bus + 1) << 8) |
++ (cfg->end_bus << 16));
++
++ return 0;
++}
++DECLARE_ACPI_MCFG_FIXUP("APM ", "XGENE ", xgene_mcfg_fixup);
++#endif /* CONFIG_ACPI */
++
+ static int xgene_pcie_probe_bridge(struct platform_device *pdev)
+ {
+ struct device_node *dn = pdev->dev.of_node;
+@@ -631,10 +798,15 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev)
+ if (ret)
+ return ret;
+
+- bus = pci_scan_root_bus(&pdev->dev, 0, &xgene_pcie_ops, port, &res);
++ bus = pci_create_root_bus(&pdev->dev, 0,
++ &xgene_pcie_ops, port, &res);
+ if (!bus)
+ return -ENOMEM;
+
++ pci_scan_child_bus(bus);
++ pci_assign_unassigned_bus_resources(bus);
++ pci_bus_add_devices(bus);
++
+ platform_set_drvdata(pdev, port);
+ return 0;
+ }
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 782e822..d952462 100644
--- a/drivers/pnp/resource.c
@@ -9154,11 +12001,31 @@ index ef9a165..9f1939c 100644
},
};
+diff --git a/drivers/xen/efi.c b/drivers/xen/efi.c
+index 1f850c9..f745db2 100644
+--- a/drivers/xen/efi.c
++++ b/drivers/xen/efi.c
+@@ -294,6 +294,7 @@ static const struct efi efi_xen __initconst = {
+ .acpi = EFI_INVALID_TABLE_ADDR,
+ .acpi20 = EFI_INVALID_TABLE_ADDR,
+ .smbios = EFI_INVALID_TABLE_ADDR,
++ .smbios3 = EFI_INVALID_TABLE_ADDR,
+ .sal_systab = EFI_INVALID_TABLE_ADDR,
+ .boot_info = EFI_INVALID_TABLE_ADDR,
+ .hcdp = EFI_INVALID_TABLE_ADDR,
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
-index 57ee052..a1ef42f 100644
+index f34a083..04d02fc 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);
+@@ -27,6 +27,7 @@
+ #define __ACPI_BUS_H__
+
+ #include <linux/device.h>
++#include <linux/property.h>
+
+ /* TBD: Make dynamic */
+ #define ACPI_MAX_HANDLES 10
+@@ -68,6 +69,8 @@ bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs);
union acpi_object *acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid,
int rev, int func, union acpi_object *argv4);
@@ -9167,7 +12034,7 @@ index 57ee052..a1ef42f 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 {
+@@ -337,10 +340,20 @@ struct acpi_device_physical_node {
bool put_online:1;
};
@@ -9178,10 +12045,17 @@ index 57ee052..a1ef42f 100644
+ const union acpi_object *of_compatible;
+};
+
++struct acpi_gpio_mapping;
++
/* Device */
struct acpi_device {
int device_type;
-@@ -353,6 +362,7 @@ struct acpi_device {
+ acpi_handle handle; /* no handle for fixed hardware */
++ struct fwnode_handle fwnode;
+ struct acpi_device *parent;
+ struct list_head children;
+ struct list_head node;
+@@ -353,9 +366,11 @@ struct acpi_device {
struct acpi_device_wakeup wakeup;
struct acpi_device_perf performance;
struct acpi_device_dir dir;
@@ -9189,6 +12063,32 @@ index 57ee052..a1ef42f 100644
struct acpi_scan_handler *handler;
struct acpi_hotplug_context *hp;
struct acpi_driver *driver;
++ const struct acpi_gpio_mapping *driver_gpios;
+ void *driver_data;
+ struct device dev;
+ unsigned int physical_node_count;
+@@ -364,6 +379,21 @@ struct acpi_device {
+ void (*remove)(struct acpi_device *);
+ };
+
++static inline bool is_acpi_node(struct fwnode_handle *fwnode)
++{
++ return fwnode && fwnode->type == FWNODE_ACPI;
++}
++
++static inline struct acpi_device *acpi_node(struct fwnode_handle *fwnode)
++{
++ return fwnode ? container_of(fwnode, struct acpi_device, fwnode) : NULL;
++}
++
++static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
++{
++ return &adev->fwnode;
++}
++
+ static inline void *acpi_driver_data(struct acpi_device *d)
+ {
+ return d->driver_data;
diff --git a/include/acpi/acpi_io.h b/include/acpi/acpi_io.h
index 444671e..9d573db 100644
--- a/include/acpi/acpi_io.h
@@ -9211,6 +12111,24 @@ index 444671e..9d573db 100644
return ioremap_cache(phys, size);
}
+diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
+index aa70cbd..1261fef 100644
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -275,6 +275,13 @@
+ VMLINUX_SYMBOL(__end_pci_fixups_suspend_late) = .; \
+ } \
+ \
++ /* ACPI quirks */ \
++ .acpi_fixup : AT(ADDR(.acpi_fixup) - LOAD_OFFSET) { \
++ VMLINUX_SYMBOL(__start_acpi_mcfg_fixups) = .; \
++ *(.acpi_fixup_mcfg) \
++ VMLINUX_SYMBOL(__end_acpi_mcfg_fixups) = .; \
++ } \
++ \
+ /* Built-in firmware blobs */ \
+ .builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start_builtin_fw) = .; \
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 206dcc3..660dbfc 100644
--- a/include/kvm/arm_vgic.h
@@ -9245,7 +12163,7 @@ index 206dcc3..660dbfc 100644
return -ENODEV;
}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
-index b7926bb..6c22abf 100644
+index 407a12f..de81de3 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -28,6 +28,7 @@
@@ -9290,10 +12208,64 @@ index b7926bb..6c22abf 100644
int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
int acpi_device_modalias(struct device *, char *, int);
-@@ -658,4 +660,85 @@ do { \
+@@ -443,6 +445,23 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *);
+ #define ACPI_COMPANION_SET(dev, adev) do { } while (0)
+ #define ACPI_HANDLE(dev) (NULL)
+
++struct fwnode_handle;
++
++static inline bool is_acpi_node(struct fwnode_handle *fwnode)
++{
++ return false;
++}
++
++static inline struct acpi_device *acpi_node(struct fwnode_handle *fwnode)
++{
++ return NULL;
++}
++
++static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
++{
++ return NULL;
++}
++
+ static inline const char *acpi_dev_name(struct acpi_device *adev)
+ {
+ return NULL;
+@@ -659,4 +678,114 @@ do { \
#endif
#endif
++struct acpi_gpio_params {
++ unsigned int crs_entry_index;
++ unsigned int line_index;
++ bool active_low;
++};
++
++struct acpi_gpio_mapping {
++ const char *name;
++ const struct acpi_gpio_params *data;
++ unsigned int size;
++};
++
++#if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB)
++int acpi_dev_add_driver_gpios(struct acpi_device *adev,
++ const struct acpi_gpio_mapping *gpios);
++
++static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev)
++{
++ if (adev)
++ adev->driver_gpios = NULL;
++}
++#else
++static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev,
++ const struct acpi_gpio_mapping *gpios)
++{
++ return -ENXIO;
++}
++static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev) {}
++#endif
++
+/* Device properties */
+
+#define MAX_ACPI_REFERENCE_ARGS 8
@@ -9309,20 +12281,19 @@ index b7926bb..6c22abf 100644
+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,
++int acpi_dev_get_property_reference(struct acpi_device *adev,
++ const char *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_single(struct acpi_device *adev, const char *propname,
++ enum dev_prop_type proptype, void *val);
+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);
++ enum dev_prop_type proptype, void *val, size_t nval);
++
++struct acpi_device *acpi_get_next_child(struct device *dev,
++ struct acpi_device *child);
+#else
+static inline int acpi_dev_get_property(struct acpi_device *adev,
+ const char *name, acpi_object_type type,
@@ -9351,33 +12322,33 @@ index b7926bb..6c22abf 100644
+ return -ENXIO;
+}
+
-+static inline int acpi_dev_prop_read(struct acpi_device *adev,
-+ const char *propname,
-+ enum dev_prop_type proptype, void *val)
++static inline int acpi_dev_prop_read_single(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)
++static inline int acpi_dev_prop_read(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)
++static inline struct acpi_device *acpi_get_next_child(struct device *dev,
++ struct acpi_device *child)
+{
-+ return -ENXIO;
++ return NULL;
+}
+
+#endif
+
#endif /*_LINUX_ACPI_H*/
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
-index 653f0e2..5839f98 100644
+index abcafaa..4f5caa1 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -346,4 +346,10 @@ extern void clocksource_of_init(void);
@@ -9391,19 +12362,45 @@ index 653f0e2..5839f98 100644
+#endif
+
#endif /* _LINUX_CLOCKSOURCE_H */
+diff --git a/include/linux/efi.h b/include/linux/efi.h
+index 0949f9c..0238d61 100644
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -547,6 +547,9 @@ void efi_native_runtime_setup(void);
+ #define SMBIOS_TABLE_GUID \
+ EFI_GUID( 0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+
++#define SMBIOS3_TABLE_GUID \
++ EFI_GUID( 0xf2fd1544, 0x9794, 0x4a2c, 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 )
++
+ #define SAL_SYSTEM_TABLE_GUID \
+ EFI_GUID( 0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+
+@@ -810,7 +813,8 @@ extern struct efi {
+ unsigned long mps; /* MPS table */
+ unsigned long acpi; /* ACPI table (IA64 ext 0.71) */
+ unsigned long acpi20; /* ACPI table (ACPI 2.0) */
+- unsigned long smbios; /* SM BIOS table */
++ unsigned long smbios; /* SMBIOS table (32 bit entry point) */
++ unsigned long smbios3; /* SMBIOS table (64 bit entry point) */
+ unsigned long sal_systab; /* SAL system table */
+ unsigned long boot_info; /* boot info table */
+ unsigned long hcdp; /* HCDP table */
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
-index 12f146f..033d2fd 100644
+index 12f146f..00b1b70 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);
+@@ -94,6 +94,13 @@ 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);
++struct fwnode_handle;
++
++struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
++ const char *propname);
++struct gpio_desc *devm_get_gpiod_from_child(struct device *dev,
++ struct fwnode_handle *child);
#else /* CONFIG_GPIOLIB */
static inline struct gpio_desc *__must_check __gpiod_get(struct device *dev,
@@ -9486,19 +12483,28 @@ index 13eed92..dc9cb5f 100644
#define GICH_VTR 0x4
#define GICH_VMCR 0x8
diff --git a/include/linux/leds.h b/include/linux/leds.h
-index e436864..879a113 100644
+index a57611d..361101f 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;
+@@ -261,6 +261,7 @@ struct gpio_led {
unsigned retain_state_suspended : 1;
+ unsigned default_state : 2;
+ /* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */
++ struct gpio_desc *gpiod;
+ };
+ #define LEDS_GPIO_DEFSTATE_OFF 0
+ #define LEDS_GPIO_DEFSTATE_ON 1
+@@ -273,7 +274,7 @@ struct gpio_led_platform_data {
+ #define GPIO_LED_NO_BLINK_LOW 0 /* No blink GPIO state low */
+ #define GPIO_LED_NO_BLINK_HIGH 1 /* No blink GPIO state high */
+ #define GPIO_LED_BLINK 2 /* Please, blink */
+- int (*gpio_blink_set)(unsigned gpio, int state,
++ int (*gpio_blink_set)(struct gpio_desc *desc, int state,
+ unsigned long *delay_on,
+ unsigned long *delay_off);
+ };
diff --git a/include/linux/of.h b/include/linux/of.h
-index 6545e7a..9962b70 100644
+index 29f0adc..cf79be1 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -23,6 +23,7 @@
@@ -9509,56 +12515,81 @@ index 6545e7a..9962b70 100644
#include <asm/byteorder.h>
#include <asm/errno.h>
-@@ -355,6 +356,15 @@ const char *of_prop_next_string(struct property *prop, const char *cur);
+@@ -49,6 +50,7 @@ struct device_node {
+ const char *type;
+ phandle phandle;
+ const char *full_name;
++ struct fwnode_handle fwnode;
+
+ struct property *properties;
+ struct property *deadprops; /* removed properties */
+@@ -79,6 +81,7 @@ extern struct kobj_type of_node_ktype;
+ static inline void of_node_init(struct device_node *node)
+ {
+ kobject_init(&node->kobj, &of_node_ktype);
++ node->fwnode.type = FWNODE_OF;
+ }
- bool of_console_check(struct device_node *dn, char *name, int index);
+ /* true when node is initialized */
+@@ -114,6 +117,16 @@ extern struct device_node *of_aliases;
+ extern struct device_node *of_stdout;
+ extern raw_spinlock_t devtree_lock;
-+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);
++static inline bool is_of_node(struct fwnode_handle *fwnode)
++{
++ return fwnode && fwnode->type == FWNODE_OF;
++}
+
- #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)
++static inline struct device_node *of_node(struct fwnode_handle *fwnode)
+{
-+ return -ENXIO;
++ return fwnode ? container_of(fwnode, struct device_node, fwnode) : NULL;
+}
+
-+static inline int of_dev_prop_read(struct device_node *dn, const char *propname,
-+ enum dev_prop_type proptype, void *val)
+ static inline bool of_have_populated_dt(void)
+ {
+ return of_allnodes != NULL;
+@@ -263,6 +276,10 @@ extern int of_property_read_u32_array(const struct device_node *np,
+ size_t sz);
+ extern int of_property_read_u64(const struct device_node *np,
+ const char *propname, u64 *out_value);
++extern int of_property_read_u64_array(const struct device_node *np,
++ const char *propname,
++ u64 *out_values,
++ size_t sz);
+
+ extern int of_property_read_string(struct device_node *np,
+ const char *propname,
+@@ -355,6 +372,16 @@ bool of_console_check(struct device_node *dn, char *name, int index);
+
+ #else /* CONFIG_OF */
+
++static inline bool is_of_node(struct fwnode_handle *fwnode)
+{
-+ return -ENXIO;
++ return false;
+}
+
-+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)
++static inline struct device_node *of_node(struct fwnode_handle *fwnode)
+{
-+ return -ENXIO;
++ return NULL;
+}
+
-+static inline int of_for_each_child_node(struct device *dev,
-+ int (*fn)(struct device *dev, void *child, void *data),
-+ void *data)
+ static inline const char* of_node_full_name(const struct device_node *np)
+ {
+ return "<no-node>";
+@@ -477,6 +504,13 @@ static inline int of_property_read_u32_array(const struct device_node *np,
+ return -ENOSYS;
+ }
+
++static inline int of_property_read_u64_array(const struct device_node *np,
++ const char *propname,
++ u64 *out_values, size_t sz)
+{
-+ return -ENXIO;
++ return -ENOSYS;
+}
+
- #define of_match_ptr(_ptr) NULL
- #define of_match_node(_matches, _node) NULL
- #endif /* CONFIG_OF */
+ static inline int of_property_read_string(struct device_node *np,
+ const char *propname,
+ const char **out_string)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 5be8db4..6afba72 100644
--- a/include/linux/pci.h
@@ -9630,10 +12661,10 @@ index 5be8db4..6afba72 100644
extern struct dev_pm_ops pcibios_pm_ops;
diff --git a/include/linux/property.h b/include/linux/property.h
new file mode 100644
-index 0000000..1a42878
+index 0000000..a6a3d98
--- /dev/null
+++ b/include/linux/property.h
-@@ -0,0 +1,207 @@
+@@ -0,0 +1,143 @@
+/*
+ * property.h - Unified device property interface.
+ *
@@ -9649,7 +12680,9 @@ index 0000000..1a42878
+#ifndef _LINUX_PROPERTY_H_
+#define _LINUX_PROPERTY_H_
+
-+#include <linux/device.h>
++#include <linux/types.h>
++
++struct device;
+
+enum dev_prop_type {
+ DEV_PROP_U8,
@@ -9660,187 +12693,190 @@ index 0000000..1a42878
+ 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);
-+}
++bool device_property_present(struct device *dev, const char *propname);
++int device_property_read_u8_array(struct device *dev, const char *propname,
++ u8 *val, size_t nval);
++int device_property_read_u16_array(struct device *dev, const char *propname,
++ u16 *val, size_t nval);
++int device_property_read_u32_array(struct device *dev, const char *propname,
++ u32 *val, size_t nval);
++int device_property_read_u64_array(struct device *dev, const char *propname,
++ u64 *val, size_t nval);
++int device_property_read_string_array(struct device *dev, const char *propname,
++ const char **val, size_t nval);
++int device_property_read_string(struct device *dev, const char *propname,
++ const char **val);
++
++enum fwnode_type {
++ FWNODE_INVALID = 0,
++ FWNODE_OF,
++ FWNODE_ACPI,
++};
+
-+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);
-+}
++struct fwnode_handle {
++ enum fwnode_type type;
++};
+
-+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);
-+}
++bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname);
++int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
++ const char *propname, u8 *val,
++ size_t nval);
++int fwnode_property_read_u16_array(struct fwnode_handle *fwnode,
++ const char *propname, u16 *val,
++ size_t nval);
++int fwnode_property_read_u32_array(struct fwnode_handle *fwnode,
++ const char *propname, u32 *val,
++ size_t nval);
++int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
++ const char *propname, u64 *val,
++ size_t nval);
++int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
++ const char *propname, const char **val,
++ size_t nval);
++int fwnode_property_read_string(struct fwnode_handle *fwnode,
++ const char *propname, const char **val);
++
++struct fwnode_handle *device_get_next_child_node(struct device *dev,
++ struct fwnode_handle *child);
++
++#define device_for_each_child_node(dev, child) \
++ for (child = device_get_next_child_node(dev, NULL); child; \
++ child = device_get_next_child_node(dev, child))
++
++void fwnode_handle_put(struct fwnode_handle *fwnode);
+
-+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);
-+}
++unsigned int device_get_child_node_count(struct device *dev);
+
-+static inline int device_property_read_u32_array(struct device *dev,
-+ const char *propname,
-+ u32 *val, size_t nval)
++static inline bool device_property_read_bool(struct device *dev,
++ const char *propname)
+{
-+ return device_read_property_array(dev, propname, DEV_PROP_U32, val,
-+ nval);
++ return device_property_present(dev, propname);
+}
+
-+static inline int device_property_read_u64_array(struct device *dev,
-+ const char *propname,
-+ u64 *val, size_t nval)
++static inline int device_property_read_u8(struct device *dev,
++ const char *propname, u8 *val)
+{
-+ return device_read_property_array(dev, propname, DEV_PROP_U64, val,
-+ nval);
++ return device_property_read_u8_array(dev, propname, val, 1);
+}
+
-+static inline int device_property_read_string(struct device *dev,
-+ const char *propname,
-+ const char **out_string)
++static inline int device_property_read_u16(struct device *dev,
++ const char *propname, u16 *val)
+{
-+ return device_read_property(dev, propname, DEV_PROP_STRING, out_string);
++ return device_property_read_u16_array(dev, propname, val, 1);
+}
+
-+static inline int device_property_read_string_array(struct device *dev,
-+ const char *propname,
-+ const char **out_strings,
-+ size_t nstrings)
++static inline int device_property_read_u32(struct device *dev,
++ const char *propname, u32 *val)
+{
-+ return device_read_property_array(dev, propname, DEV_PROP_STRING,
-+ out_strings, nstrings);
++ return device_property_read_u32_array(dev, propname, val, 1);
+}
+
-+static inline int device_child_property_read_u8(struct device *dev, void *child,
-+ const char *propname,
-+ u8 *out_value)
++static inline int device_property_read_u64(struct device *dev,
++ const char *propname, u64 *val)
+{
-+ return device_read_child_property(dev, child, propname, DEV_PROP_U8,
-+ out_value);
++ return device_property_read_u64_array(dev, propname, val, 1);
+}
+
-+static inline int device_child_property_read_u16(struct device *dev, void *child,
-+ const char *propname,
-+ u16 *out_value)
++static inline bool fwnode_property_read_bool(struct fwnode_handle *fwnode,
++ const char *propname)
+{
-+ return device_read_child_property(dev, child, propname, DEV_PROP_U16,
-+ out_value);
++ return fwnode_property_present(fwnode, propname);
+}
+
-+static inline int device_child_property_read_u32(struct device *dev, void *child,
-+ const char *propname,
-+ u32 *out_value)
++static inline int fwnode_property_read_u8(struct fwnode_handle *fwnode,
++ const char *propname, u8 *val)
+{
-+ return device_read_child_property(dev, child, propname, DEV_PROP_U32,
-+ out_value);
++ return fwnode_property_read_u8_array(fwnode, propname, val, 1);
+}
+
-+static inline int device_child_property_read_u64(struct device *dev, void *child,
-+ const char *propname,
-+ u64 *out_value)
++static inline int fwnode_property_read_u16(struct fwnode_handle *fwnode,
++ const char *propname, u16 *val)
+{
-+ return device_read_child_property(dev, child, propname, DEV_PROP_U64,
-+ out_value);
++ return fwnode_property_read_u16_array(fwnode, propname, val, 1);
+}
+
-+static inline int device_child_property_read_u8_array(struct device *dev,
-+ void *child,
-+ const char *propname,
-+ u8 *val, size_t nval)
++static inline int fwnode_property_read_u32(struct fwnode_handle *fwnode,
++ const char *propname, u32 *val)
+{
-+ return device_read_child_property_array(dev, child, propname,
-+ DEV_PROP_U8, val, nval);
++ return fwnode_property_read_u32_array(fwnode, propname, val, 1);
+}
+
-+static inline int device_child_property_read_u16_array(struct device *dev,
-+ void *child,
-+ const char *propname,
-+ u16 *val, size_t nval)
++static inline int fwnode_property_read_u64(struct fwnode_handle *fwnode,
++ const char *propname, u64 *val)
+{
-+ return device_read_child_property_array(dev, child, propname,
-+ DEV_PROP_U16, val, nval);
++ return fwnode_property_read_u64_array(fwnode, propname, val, 1);
+}
+
-+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);
-+}
++#endif /* _LINUX_PROPERTY_H_ */
+diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c
+index 654c901..48da2c5 100644
+--- a/net/bridge/netfilter/nft_reject_bridge.c
++++ b/net/bridge/netfilter/nft_reject_bridge.c
+@@ -18,6 +18,7 @@
+ #include <net/netfilter/ipv6/nf_reject.h>
+ #include <linux/ip.h>
+ #include <net/ip.h>
++#include <net/ip6_checksum.h>
+ #include <linux/netfilter_bridge.h>
+ #include "../br_private.h"
+
+diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
+index 0f62326..2a47179 100644
+--- a/net/rfkill/rfkill-gpio.c
++++ b/net/rfkill/rfkill-gpio.c
+@@ -63,6 +63,15 @@ static const struct rfkill_ops rfkill_gpio_ops = {
+ .set_block = rfkill_gpio_set_power,
+ };
+
++static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
++static const struct acpi_gpio_params shutdown_gpios = { 1, 0, false };
+
-+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 const struct acpi_gpio_mapping acpi_rfkill_default_gpios[] = {
++ { "reset-gpios", &reset_gpios, 1 },
++ { "shutdown-gpios", &shutdown_gpios, 1 },
++ { },
++};
+
-+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 int rfkill_gpio_acpi_probe(struct device *dev,
+ struct rfkill_gpio_data *rfkill)
+ {
+@@ -75,7 +84,8 @@ static int rfkill_gpio_acpi_probe(struct device *dev,
+ rfkill->name = dev_name(dev);
+ rfkill->type = (unsigned)id->driver_data;
+
+- return 0;
++ return acpi_dev_add_driver_gpios(ACPI_COMPANION(dev),
++ acpi_rfkill_default_gpios);
+ }
+
+ static int rfkill_gpio_probe(struct platform_device *pdev)
+@@ -102,7 +112,7 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
+
+ rfkill->clk = devm_clk_get(&pdev->dev, NULL);
+
+- gpio = devm_gpiod_get_index(&pdev->dev, "reset", 0);
++ gpio = devm_gpiod_get(&pdev->dev, "reset");
+ if (!IS_ERR(gpio)) {
+ ret = gpiod_direction_output(gpio, 0);
+ if (ret)
+@@ -110,7 +120,7 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
+ rfkill->reset_gpio = gpio;
+ }
+
+- gpio = devm_gpiod_get_index(&pdev->dev, "shutdown", 1);
++ gpio = devm_gpiod_get(&pdev->dev, "shutdown");
+ if (!IS_ERR(gpio)) {
+ ret = gpiod_direction_output(gpio, 0);
+ if (ret)
+@@ -150,6 +160,8 @@ static int rfkill_gpio_remove(struct platform_device *pdev)
+ rfkill_unregister(rfkill->rfkill_dev);
+ rfkill_destroy(rfkill->rfkill_dev);
+
++ acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev));
+
-+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_ */
+ return 0;
+ }
+
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