aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.14/202-core-linux-support-layerscape.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.14/202-core-linux-support-layerscape.patch')
-rw-r--r--target/linux/layerscape/patches-4.14/202-core-linux-support-layerscape.patch681
1 files changed, 498 insertions, 183 deletions
diff --git a/target/linux/layerscape/patches-4.14/202-core-linux-support-layerscape.patch b/target/linux/layerscape/patches-4.14/202-core-linux-support-layerscape.patch
index e8de78413b..46650d17fa 100644
--- a/target/linux/layerscape/patches-4.14/202-core-linux-support-layerscape.patch
+++ b/target/linux/layerscape/patches-4.14/202-core-linux-support-layerscape.patch
@@ -1,54 +1,301 @@
-From 74243154052af635ee9ce9d07aab273ce219c855 Mon Sep 17 00:00:00 2001
-From: Biwen Li <biwen.li@nxp.com>
-Date: Thu, 13 Dec 2018 13:23:52 +0800
+From d2ef9f2f6d16d34d7eee74cb8efd269341fec5a1 Mon Sep 17 00:00:00 2001
+From: Yangbo Lu <yangbo.lu@nxp.com>
+Date: Mon, 6 May 2019 16:54:17 +0800
Subject: [PATCH] core-linux: support layerscape
-This is an integrated patch of core-linux for layerscape.
+This is an integrated patch of core-linux for layerscape
+Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Abhijit Ayarekar <abhijit.ayarekar@caviumnetworks.com>
Signed-off-by: Amrita Kumari <amrita.kumari@nxp.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ashish Kumar <Ashish.Kumar@nxp.com>
+Signed-off-by: Biwen Li <biwen.li@nxp.com>
Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Guanhua Gao <guanhua.gao@nxp.com>
+Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Joel Fernandes <joelaf@google.com>
+Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Li Yang <leoyang.li@nxp.com>
-Signed-off-by: Madalin Bucur <madalin.bucur@freescale.com>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Nikhil Badola <nikhil.badola@freescale.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
+Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
+Signed-off-by: pascal paillet <p.paillet@st.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Ramneek Mehresh <ramneek.mehresh@freescale.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Suresh Gupta <suresh.gupta@freescale.com>
+Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
-Signed-off-by: yinbo.zhu <yinbo.zhu@nxp.com>
-Signed-off-by: Biwen Li <biwen.li@nxp.com>
---
- drivers/base/dma-mapping.c | 7 ++
- drivers/net/bonding/bond_main.c | 5 +-
- drivers/net/bonding/bond_options.c | 2 +-
- drivers/net/team/team.c | 3 +-
- drivers/net/vrf.c | 3 +-
- drivers/of/device.c | 13 +++-
- drivers/soc/fsl/guts.c | 3 +
- include/linux/fsl_devices.h | 2 +
- include/linux/netdevice.h | 13 +++-
- include/linux/skbuff.h | 2 +
- include/net/bonding.h | 3 +-
- net/batman-adv/soft-interface.c | 3 +-
- net/bridge/br_device.c | 3 +-
- net/core/dev.c | 81 ++++++++++++++---------
- net/core/rtnetlink.c | 10 +--
- net/core/skbuff.c | 29 +++++++-
- samples/bpf/Makefile | 12 +++-
- samples/bpf/map_perf_test_kern.c | 2 +-
- samples/bpf/map_perf_test_user.c | 2 +-
- tools/testing/selftests/bpf/bpf_helpers.h | 56 ++++++++++++++--
- 20 files changed, 193 insertions(+), 61 deletions(-)
+ drivers/base/core.c | 122 ++++++++++++++++++++++++++----
+ drivers/base/dma-mapping.c | 7 ++
+ drivers/gpu/ipu-v3/ipu-pre.c | 3 +-
+ drivers/gpu/ipu-v3/ipu-prg.c | 3 +-
+ drivers/iommu/dma-iommu.c | 3 +
+ drivers/mux/Kconfig | 12 +--
+ drivers/mux/mmio.c | 6 +-
+ drivers/of/device.c | 14 +++-
+ drivers/soc/imx/gpc.c | 2 +-
+ include/linux/device.h | 20 +++--
+ include/linux/fsl_devices.h | 2 +
+ include/linux/netdevice.h | 10 ++-
+ include/linux/skbuff.h | 2 +
+ lib/dma-noop.c | 19 +++++
+ mm/page_alloc.c | 10 ++-
+ net/core/dev.c | 81 ++++++++++++--------
+ net/core/skbuff.c | 29 ++++++-
+ samples/bpf/Makefile | 12 ++-
+ samples/bpf/map_perf_test_kern.c | 2 +-
+ samples/bpf/map_perf_test_user.c | 2 +-
+ tools/testing/selftests/bpf/bpf_helpers.h | 56 ++++++++++++--
+ 21 files changed, 337 insertions(+), 80 deletions(-)
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -161,10 +161,10 @@ static int device_reorder_to_tail(struct
+ * of the link. If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will be
+ * ignored.
+ *
+- * If the DL_FLAG_AUTOREMOVE is set, the link will be removed automatically
+- * when the consumer device driver unbinds from it. The combination of both
+- * DL_FLAG_AUTOREMOVE and DL_FLAG_STATELESS set is invalid and will cause NULL
+- * to be returned.
++ * If the DL_FLAG_AUTOREMOVE_CONSUMER is set, the link will be removed
++ * automatically when the consumer device driver unbinds from it.
++ * The combination of both DL_FLAG_AUTOREMOVE_CONSUMER and DL_FLAG_STATELESS
++ * set is invalid and will cause NULL to be returned.
+ *
+ * A side effect of the link creation is re-ordering of dpm_list and the
+ * devices_kset list by moving the consumer device and all devices depending
+@@ -181,7 +181,8 @@ struct device_link *device_link_add(stru
+ struct device_link *link;
+
+ if (!consumer || !supplier ||
+- ((flags & DL_FLAG_STATELESS) && (flags & DL_FLAG_AUTOREMOVE)))
++ ((flags & DL_FLAG_STATELESS) &&
++ (flags & DL_FLAG_AUTOREMOVE_CONSUMER)))
+ return NULL;
+
+ device_links_write_lock();
+@@ -199,8 +200,10 @@ struct device_link *device_link_add(stru
+ }
+
+ list_for_each_entry(link, &supplier->links.consumers, s_node)
+- if (link->consumer == consumer)
++ if (link->consumer == consumer) {
++ kref_get(&link->kref);
+ goto out;
++ }
+
+ link = kzalloc(sizeof(*link), GFP_KERNEL);
+ if (!link)
+@@ -232,6 +235,7 @@ struct device_link *device_link_add(stru
+ link->consumer = consumer;
+ INIT_LIST_HEAD(&link->c_node);
+ link->flags = flags;
++ kref_init(&link->kref);
+
+ /* Determine the initial link state. */
+ if (flags & DL_FLAG_STATELESS) {
+@@ -302,8 +306,10 @@ static void __device_link_free_srcu(stru
+ device_link_free(container_of(rhead, struct device_link, rcu_head));
+ }
+
+-static void __device_link_del(struct device_link *link)
++static void __device_link_del(struct kref *kref)
+ {
++ struct device_link *link = container_of(kref, struct device_link, kref);
++
+ dev_info(link->consumer, "Dropping the link to %s\n",
+ dev_name(link->supplier));
+
+@@ -315,8 +321,10 @@ static void __device_link_del(struct dev
+ call_srcu(&device_links_srcu, &link->rcu_head, __device_link_free_srcu);
+ }
+ #else /* !CONFIG_SRCU */
+-static void __device_link_del(struct device_link *link)
++static void __device_link_del(struct kref *kref)
+ {
++ struct device_link *link = container_of(kref, struct device_link, kref);
++
+ dev_info(link->consumer, "Dropping the link to %s\n",
+ dev_name(link->supplier));
+
+@@ -334,18 +342,50 @@ static void __device_link_del(struct dev
+ * @link: Device link to delete.
+ *
+ * The caller must ensure proper synchronization of this function with runtime
+- * PM.
++ * PM. If the link was added multiple times, it needs to be deleted as often.
++ * Care is required for hotplugged devices: Their links are purged on removal
++ * and calling device_link_del() is then no longer allowed.
+ */
+ void device_link_del(struct device_link *link)
+ {
+ device_links_write_lock();
+ device_pm_lock();
+- __device_link_del(link);
++ kref_put(&link->kref, __device_link_del);
+ device_pm_unlock();
+ device_links_write_unlock();
+ }
+ EXPORT_SYMBOL_GPL(device_link_del);
+
++/**
++ * device_link_remove - remove a link between two devices.
++ * @consumer: Consumer end of the link.
++ * @supplier: Supplier end of the link.
++ *
++ * The caller must ensure proper synchronization of this function with runtime
++ * PM.
++ */
++void device_link_remove(void *consumer, struct device *supplier)
++{
++ struct device_link *link;
++
++ if (WARN_ON(consumer == supplier))
++ return;
++
++ device_links_write_lock();
++ device_pm_lock();
++
++ list_for_each_entry(link, &supplier->links.consumers, s_node) {
++ if (link->consumer == consumer) {
++ kref_put(&link->kref, __device_link_del);
++ break;
++ }
++ }
++
++ device_pm_unlock();
++ device_links_write_unlock();
++}
++EXPORT_SYMBOL_GPL(device_link_remove);
++
+ static void device_links_missing_supplier(struct device *dev)
+ {
+ struct device_link *link;
+@@ -453,8 +493,8 @@ static void __device_links_no_driver(str
+ if (link->flags & DL_FLAG_STATELESS)
+ continue;
+
+- if (link->flags & DL_FLAG_AUTOREMOVE)
+- __device_link_del(link);
++ if (link->flags & DL_FLAG_AUTOREMOVE_CONSUMER)
++ kref_put(&link->kref, __device_link_del);
+ else if (link->status != DL_STATE_SUPPLIER_UNBIND)
+ WRITE_ONCE(link->status, DL_STATE_AVAILABLE);
+ }
+@@ -489,8 +529,18 @@ void device_links_driver_cleanup(struct
+ if (link->flags & DL_FLAG_STATELESS)
+ continue;
+
+- WARN_ON(link->flags & DL_FLAG_AUTOREMOVE);
++ WARN_ON(link->flags & DL_FLAG_AUTOREMOVE_CONSUMER);
+ WARN_ON(link->status != DL_STATE_SUPPLIER_UNBIND);
++
++ /*
++ * autoremove the links between this @dev and its consumer
++ * devices that are not active, i.e. where the link state
++ * has moved to DL_STATE_SUPPLIER_UNBIND.
++ */
++ if (link->status == DL_STATE_SUPPLIER_UNBIND &&
++ link->flags & DL_FLAG_AUTOREMOVE_SUPPLIER)
++ kref_put(&link->kref, __device_link_del);
++
+ WRITE_ONCE(link->status, DL_STATE_DORMANT);
+ }
+
+@@ -607,13 +657,13 @@ static void device_links_purge(struct de
+
+ list_for_each_entry_safe_reverse(link, ln, &dev->links.suppliers, c_node) {
+ WARN_ON(link->status == DL_STATE_ACTIVE);
+- __device_link_del(link);
++ __device_link_del(&link->kref);
+ }
+
+ list_for_each_entry_safe_reverse(link, ln, &dev->links.consumers, s_node) {
+ WARN_ON(link->status != DL_STATE_DORMANT &&
+ link->status != DL_STATE_NONE);
+- __device_link_del(link);
++ __device_link_del(&link->kref);
+ }
+
+ device_links_write_unlock();
+@@ -1035,6 +1085,34 @@ static ssize_t online_store(struct devic
+ }
+ static DEVICE_ATTR_RW(online);
+
++static ssize_t suppliers_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct device_link *link;
++ size_t count = 0;
++
++ list_for_each_entry(link, &dev->links.suppliers, c_node)
++ count += scnprintf(buf + count, PAGE_SIZE - count, "%s\n",
++ dev_name(link->supplier));
++
++ return count;
++}
++static DEVICE_ATTR_RO(suppliers);
++
++static ssize_t consumers_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct device_link *link;
++ size_t count = 0;
++
++ list_for_each_entry(link, &dev->links.consumers, s_node)
++ count += scnprintf(buf + count, PAGE_SIZE - count, "%s\n",
++ dev_name(link->consumer));
++
++ return count;
++}
++static DEVICE_ATTR_RO(consumers);
++
+ int device_add_groups(struct device *dev, const struct attribute_group **groups)
+ {
+ return sysfs_create_groups(&dev->kobj, groups);
+@@ -1206,8 +1284,20 @@ static int device_add_attrs(struct devic
+ goto err_remove_dev_groups;
+ }
+
++ error = device_create_file(dev, &dev_attr_suppliers);
++ if (error)
++ goto err_remove_online;
++
++ error = device_create_file(dev, &dev_attr_consumers);
++ if (error)
++ goto err_remove_suppliers;
++
+ return 0;
+
++ err_remove_suppliers:
++ device_remove_file(dev, &dev_attr_suppliers);
++ err_remove_online:
++ device_remove_file(dev, &dev_attr_online);
+ err_remove_dev_groups:
+ device_remove_groups(dev, dev->groups);
+ err_remove_type_groups:
+@@ -1225,6 +1315,8 @@ static void device_remove_attrs(struct d
+ struct class *class = dev->class;
+ const struct device_type *type = dev->type;
+
++ device_remove_file(dev, &dev_attr_consumers);
++ device_remove_file(dev, &dev_attr_suppliers);
+ device_remove_file(dev, &dev_attr_online);
+ device_remove_groups(dev, dev->groups);
+
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -335,6 +335,7 @@ void dma_common_free_remap(void *cpu_add
@@ -72,62 +319,87 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
if (dma_dev->of_node) {
ret = of_dma_configure(dev, dma_dev->of_node);
} else if (has_acpi_companion(dma_dev)) {
---- a/drivers/net/bonding/bond_main.c
-+++ b/drivers/net/bonding/bond_main.c
-@@ -1330,7 +1330,8 @@ void bond_lower_state_changed(struct sla
- }
-
- /* enslave device <slave> to bond device <master> */
--int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
-+int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
-+ struct netlink_ext_ack *extack)
- {
- struct bonding *bond = netdev_priv(bond_dev);
- const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
-@@ -3506,7 +3507,7 @@ static int bond_do_ioctl(struct net_devi
- switch (cmd) {
- case BOND_ENSLAVE_OLD:
- case SIOCBONDENSLAVE:
-- res = bond_enslave(bond_dev, slave_dev);
-+ res = bond_enslave(bond_dev, slave_dev, NULL);
- break;
- case BOND_RELEASE_OLD:
- case SIOCBONDRELEASE:
---- a/drivers/net/bonding/bond_options.c
-+++ b/drivers/net/bonding/bond_options.c
-@@ -1382,7 +1382,7 @@ static int bond_option_slaves_set(struct
- switch (command[0]) {
- case '+':
- netdev_dbg(bond->dev, "Adding slave %s\n", dev->name);
-- ret = bond_enslave(bond->dev, dev);
-+ ret = bond_enslave(bond->dev, dev, NULL);
- break;
-
- case '-':
---- a/drivers/net/team/team.c
-+++ b/drivers/net/team/team.c
-@@ -1953,7 +1953,8 @@ static int team_netpoll_setup(struct net
- }
- #endif
-
--static int team_add_slave(struct net_device *dev, struct net_device *port_dev)
-+static int team_add_slave(struct net_device *dev, struct net_device *port_dev,
-+ struct netlink_ext_ack *extack)
- {
- struct team *team = netdev_priv(dev);
- int err;
---- a/drivers/net/vrf.c
-+++ b/drivers/net/vrf.c
-@@ -791,7 +791,8 @@ err:
- return ret;
- }
-
--static int vrf_add_slave(struct net_device *dev, struct net_device *port_dev)
-+static int vrf_add_slave(struct net_device *dev, struct net_device *port_dev,
-+ struct netlink_ext_ack *extack)
- {
- if (netif_is_l3_master(port_dev) || netif_is_l3_slave(port_dev))
- return -EINVAL;
+--- a/drivers/gpu/ipu-v3/ipu-pre.c
++++ b/drivers/gpu/ipu-v3/ipu-pre.c
+@@ -124,7 +124,8 @@ ipu_pre_lookup_by_phandle(struct device
+ list_for_each_entry(pre, &ipu_pre_list, list) {
+ if (pre_node == pre->dev->of_node) {
+ mutex_unlock(&ipu_pre_list_mutex);
+- device_link_add(dev, pre->dev, DL_FLAG_AUTOREMOVE);
++ device_link_add(dev, pre->dev,
++ DL_FLAG_AUTOREMOVE_CONSUMER);
+ of_node_put(pre_node);
+ return pre;
+ }
+--- a/drivers/gpu/ipu-v3/ipu-prg.c
++++ b/drivers/gpu/ipu-v3/ipu-prg.c
+@@ -99,7 +99,8 @@ ipu_prg_lookup_by_phandle(struct device
+ list_for_each_entry(prg, &ipu_prg_list, list) {
+ if (prg_node == prg->dev->of_node) {
+ mutex_unlock(&ipu_prg_list_mutex);
+- device_link_add(dev, prg->dev, DL_FLAG_AUTOREMOVE);
++ device_link_add(dev, prg->dev,
++ DL_FLAG_AUTOREMOVE_CONSUMER);
+ prg->id = ipu_id;
+ of_node_put(prg_node);
+ return prg;
+--- a/drivers/iommu/dma-iommu.c
++++ b/drivers/iommu/dma-iommu.c
+@@ -381,6 +381,9 @@ static dma_addr_t iommu_dma_alloc_iova(s
+ if (iova_len < (1 << (IOVA_RANGE_CACHE_MAX_SIZE - 1)))
+ iova_len = roundup_pow_of_two(iova_len);
+
++ if (dev->bus_dma_mask)
++ dma_limit &= dev->bus_dma_mask;
++
+ if (domain->geometry.force_aperture)
+ dma_limit = min(dma_limit, domain->geometry.aperture_end);
+
+--- a/drivers/mux/Kconfig
++++ b/drivers/mux/Kconfig
+@@ -35,14 +35,14 @@ config MUX_GPIO
+ be called mux-gpio.
+
+ config MUX_MMIO
+- tristate "MMIO register bitfield-controlled Multiplexer"
+- depends on (OF && MFD_SYSCON) || COMPILE_TEST
++ tristate "MMIO/Regmap register bitfield-controlled Multiplexer"
++ depends on OF || COMPILE_TEST
+ help
+- MMIO register bitfield-controlled Multiplexer controller.
++ MMIO/Regmap register bitfield-controlled Multiplexer controller.
+
+- The driver builds multiplexer controllers for bitfields in a syscon
+- register. For N bit wide bitfields, there will be 2^N possible
+- multiplexer states.
++ The driver builds multiplexer controllers for bitfields in either
++ a syscon register or a driver regmap register. For N bit wide
++ bitfields, there will be 2^N possible multiplexer states.
+
+ To compile the driver as a module, choose M here: the module will
+ be called mux-mmio.
+--- a/drivers/mux/mmio.c
++++ b/drivers/mux/mmio.c
+@@ -31,6 +31,7 @@ static const struct mux_control_ops mux_
+
+ static const struct of_device_id mux_mmio_dt_ids[] = {
+ { .compatible = "mmio-mux", },
++ { .compatible = "reg-mux", },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, mux_mmio_dt_ids);
+@@ -46,7 +47,10 @@ static int mux_mmio_probe(struct platfor
+ int ret;
+ int i;
+
+- regmap = syscon_node_to_regmap(np->parent);
++ if (of_device_is_compatible(np, "mmio-mux"))
++ regmap = syscon_node_to_regmap(np->parent);
++ else
++ regmap = dev_get_regmap(dev->parent, NULL) ?: ERR_PTR(-ENODEV);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ dev_err(dev, "failed to get regmap: %d\n", ret);
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -15,6 +15,9 @@
@@ -150,7 +422,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
dev->bus != &platform_bus_type)
return ret == -ENODEV ? 0 : ret;
-@@ -155,7 +161,12 @@ int of_dma_configure(struct device *dev,
+@@ -152,10 +158,16 @@ int of_dma_configure(struct device *dev,
+ * set by the driver.
+ */
+ mask = DMA_BIT_MASK(ilog2(dma_addr + size - 1) + 1);
++ dev->bus_dma_mask = mask;
dev->coherent_dma_mask &= mask;
*dev->dma_mask &= mask;
@@ -164,18 +440,91 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
dev_dbg(dev, "device is%sdma coherent\n",
coherent ? " " : " not ");
---- a/drivers/soc/fsl/guts.c
-+++ b/drivers/soc/fsl/guts.c
-@@ -213,6 +213,9 @@ static const struct of_device_id fsl_gut
- { .compatible = "fsl,ls1021a-dcfg", },
- { .compatible = "fsl,ls1043a-dcfg", },
- { .compatible = "fsl,ls2080a-dcfg", },
-+ { .compatible = "fsl,ls1088a-dcfg", },
-+ { .compatible = "fsl,ls1012a-dcfg", },
-+ { .compatible = "fsl,ls1046a-dcfg", },
- {}
- };
- MODULE_DEVICE_TABLE(of, fsl_guts_of_match);
+--- a/drivers/soc/imx/gpc.c
++++ b/drivers/soc/imx/gpc.c
+@@ -209,7 +209,7 @@ static int imx_pgc_power_domain_probe(st
+ goto genpd_err;
+ }
+
+- device_link_add(dev, dev->parent, DL_FLAG_AUTOREMOVE);
++ device_link_add(dev, dev->parent, DL_FLAG_AUTOREMOVE_CONSUMER);
+
+ return 0;
+
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -55,6 +55,8 @@ struct bus_attribute {
+ struct bus_attribute bus_attr_##_name = __ATTR_RW(_name)
+ #define BUS_ATTR_RO(_name) \
+ struct bus_attribute bus_attr_##_name = __ATTR_RO(_name)
++#define BUS_ATTR_WO(_name) \
++ struct bus_attribute bus_attr_##_name = __ATTR_WO(_name)
+
+ extern int __must_check bus_create_file(struct bus_type *,
+ struct bus_attribute *);
+@@ -750,14 +752,16 @@ enum device_link_state {
+ * Device link flags.
+ *
+ * STATELESS: The core won't track the presence of supplier/consumer drivers.
+- * AUTOREMOVE: Remove this link automatically on consumer driver unbind.
++ * AUTOREMOVE_CONSUMER: Remove the link automatically on consumer driver unbind.
+ * PM_RUNTIME: If set, the runtime PM framework will use this link.
+ * RPM_ACTIVE: Run pm_runtime_get_sync() on the supplier during link creation.
++ * AUTOREMOVE_SUPPLIER: Remove the link automatically on supplier driver unbind.
+ */
+-#define DL_FLAG_STATELESS BIT(0)
+-#define DL_FLAG_AUTOREMOVE BIT(1)
+-#define DL_FLAG_PM_RUNTIME BIT(2)
+-#define DL_FLAG_RPM_ACTIVE BIT(3)
++#define DL_FLAG_STATELESS BIT(0)
++#define DL_FLAG_AUTOREMOVE_CONSUMER BIT(1)
++#define DL_FLAG_PM_RUNTIME BIT(2)
++#define DL_FLAG_RPM_ACTIVE BIT(3)
++#define DL_FLAG_AUTOREMOVE_SUPPLIER BIT(4)
+
+ /**
+ * struct device_link - Device link representation.
+@@ -768,6 +772,7 @@ enum device_link_state {
+ * @status: The state of the link (with respect to the presence of drivers).
+ * @flags: Link flags.
+ * @rpm_active: Whether or not the consumer device is runtime-PM-active.
++ * @kref: Count repeated addition of the same link.
+ * @rcu_head: An RCU head to use for deferred execution of SRCU callbacks.
+ */
+ struct device_link {
+@@ -778,6 +783,7 @@ struct device_link {
+ enum device_link_state status;
+ u32 flags;
+ bool rpm_active;
++ struct kref kref;
+ #ifdef CONFIG_SRCU
+ struct rcu_head rcu_head;
+ #endif
+@@ -850,6 +856,8 @@ struct dev_links_info {
+ * @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all
+ * hardware supports 64-bit addresses for consistent allocations
+ * such descriptors.
++ * @bus_dma_mask: Mask of an upstream bridge or bus which imposes a smaller DMA
++ * limit than the device itself supports.
+ * @dma_pfn_offset: offset of DMA memory range relatively of RAM
+ * @dma_parms: A low level driver may set these to teach IOMMU code about
+ * segment limitations.
+@@ -929,6 +937,7 @@ struct device {
+ not all hardware supports
+ 64 bit addresses for consistent
+ allocations such descriptors. */
++ u64 bus_dma_mask; /* upstream dma_mask constraint */
+ unsigned long dma_pfn_offset;
+
+ struct device_dma_parameters *dma_parms;
+@@ -1267,6 +1276,7 @@ extern const char *dev_driver_string(con
+ struct device_link *device_link_add(struct device *consumer,
+ struct device *supplier, u32 flags);
+ void device_link_del(struct device_link *link);
++void device_link_remove(void *consumer, struct device *supplier);
+
+ #ifdef CONFIG_PRINTK
+
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -99,7 +99,9 @@ struct fsl_usb2_platform_data {
@@ -190,17 +539,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
-@@ -1260,7 +1260,8 @@ struct net_device_ops {
- u32 flow_id);
- #endif
- int (*ndo_add_slave)(struct net_device *dev,
-- struct net_device *slave_dev);
-+ struct net_device *slave_dev,
-+ struct netlink_ext_ack *extack);
- int (*ndo_del_slave)(struct net_device *dev,
- struct net_device *slave_dev);
- netdev_features_t (*ndo_fix_features)(struct net_device *dev,
-@@ -2344,7 +2345,8 @@ int register_netdevice_notifier(struct n
+@@ -2344,7 +2344,8 @@ int register_netdevice_notifier(struct n
int unregister_netdevice_notifier(struct notifier_block *nb);
struct netdev_notifier_info {
@@ -210,7 +549,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
};
struct netdev_notifier_info_ext {
-@@ -2376,6 +2378,7 @@ static inline void netdev_notifier_info_
+@@ -2376,6 +2377,7 @@ static inline void netdev_notifier_info_
struct net_device *dev)
{
info->dev = dev;
@@ -218,7 +557,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
}
static inline struct net_device *
-@@ -2384,6 +2387,12 @@ netdev_notifier_info_to_dev(const struct
+@@ -2384,6 +2386,12 @@ netdev_notifier_info_to_dev(const struct
return info->dev;
}
@@ -249,42 +588,58 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len);
__wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to,
int len, __wsum csum);
---- a/include/net/bonding.h
-+++ b/include/net/bonding.h
-@@ -592,7 +592,8 @@ void bond_destroy_sysfs(struct bond_net
- void bond_prepare_sysfs_group(struct bonding *bond);
- int bond_sysfs_slave_add(struct slave *slave);
- void bond_sysfs_slave_del(struct slave *slave);
--int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
-+int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
-+ struct netlink_ext_ack *extack);
- int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
- u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb);
- int bond_set_carrier(struct bonding *bond);
---- a/net/batman-adv/soft-interface.c
-+++ b/net/batman-adv/soft-interface.c
-@@ -876,7 +876,8 @@ free_bat_counters:
- * Return: 0 if successful or error otherwise.
- */
- static int batadv_softif_slave_add(struct net_device *dev,
-- struct net_device *slave_dev)
-+ struct net_device *slave_dev,
-+ struct netlink_ext_ack *extack)
- {
- struct batadv_hard_iface *hard_iface;
- struct net *net = dev_net(dev);
---- a/net/bridge/br_device.c
-+++ b/net/bridge/br_device.c
-@@ -324,7 +324,8 @@ void br_netpoll_disable(struct net_bridg
-
- #endif
+--- a/lib/dma-noop.c
++++ b/lib/dma-noop.c
+@@ -58,11 +58,30 @@ static int dma_noop_map_sg(struct device
+ return nents;
+ }
--static int br_add_slave(struct net_device *dev, struct net_device *slave_dev)
-+static int br_add_slave(struct net_device *dev, struct net_device *slave_dev,
-+ struct netlink_ext_ack *extack)
++static int dma_noop_supported(struct device *dev, u64 mask)
++{
++#ifdef CONFIG_ZONE_DMA
++ if (mask < DMA_BIT_MASK(ARCH_ZONE_DMA_BITS))
++ return 0;
++#else
++ /*
++ * Because 32-bit DMA masks are so common we expect every architecture
++ * to be able to satisfy them - either by not supporting more physical
++ * memory, or by providing a ZONE_DMA32. If neither is the case, the
++ * architecture needs to use an IOMMU instead of the direct mapping.
++ */
++ if (dev->bus_dma_mask && mask > dev->bus_dma_mask)
++ return 0;
++#endif
++ return 1;
++}
++
+ const struct dma_map_ops dma_noop_ops = {
+ .alloc = dma_noop_alloc,
+ .free = dma_noop_free,
+ .map_page = dma_noop_map_page,
+ .map_sg = dma_noop_map_sg,
++ dma_supported = dma_noop_supported
+ };
+ EXPORT_SYMBOL(dma_noop_ops);
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -4366,8 +4366,14 @@ void page_frag_free(void *addr)
{
- struct net_bridge *br = netdev_priv(dev);
+ struct page *page = virt_to_head_page(addr);
+
+- if (unlikely(put_page_testzero(page)))
+- __free_pages_ok(page, compound_order(page));
++ if (unlikely(put_page_testzero(page))) {
++ unsigned int order = compound_order(page);
++
++ if (order == 0) /* Via pcp? */
++ free_hot_cold_page(page, false);
++ else
++ __free_pages_ok(page, order);
++ }
+ }
+ EXPORT_SYMBOL(page_frag_free);
+
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -162,7 +162,6 @@ static struct list_head offload_base __r
@@ -480,46 +835,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
}
}
---- a/net/core/rtnetlink.c
-+++ b/net/core/rtnetlink.c
-@@ -1912,7 +1912,8 @@ static int do_setvfinfo(struct net_devic
- return err;
- }
-
--static int do_set_master(struct net_device *dev, int ifindex)
-+static int do_set_master(struct net_device *dev, int ifindex,
-+ struct netlink_ext_ack *extack)
- {
- struct net_device *upper_dev = netdev_master_upper_dev_get(dev);
- const struct net_device_ops *ops;
-@@ -1937,7 +1938,7 @@ static int do_set_master(struct net_devi
- return -EINVAL;
- ops = upper_dev->netdev_ops;
- if (ops->ndo_add_slave) {
-- err = ops->ndo_add_slave(upper_dev, dev);
-+ err = ops->ndo_add_slave(upper_dev, dev, extack);
- if (err)
- return err;
- } else {
-@@ -2074,7 +2075,7 @@ static int do_setlink(const struct sk_bu
- }
-
- if (tb[IFLA_MASTER]) {
-- err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]));
-+ err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]), extack);
- if (err)
- goto errout;
- status |= DO_SETLINK_MODIFIED;
-@@ -2723,7 +2724,8 @@ replay:
- goto out_unregister;
- }
- if (tb[IFLA_MASTER]) {
-- err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]));
-+ err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]),
-+ extack);
- if (err)
- goto out_unregister;
- }
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -803,6 +803,32 @@ void napi_consume_skb(struct sk_buff *sk