diff options
author | Biwen Li <biwen.li@nxp.com> | 2019-05-06 12:13:14 +0800 |
---|---|---|
committer | Petr Štetiar <ynezz@true.cz> | 2019-06-06 15:40:09 +0200 |
commit | 5159d71983e649a89568e46d9ff02731beedd571 (patch) | |
tree | 2c669f4d9651c1fe26955778e5fee119543a85ce /target/linux/layerscape/patches-4.14/202-core-linux-support-layerscape.patch | |
parent | 639d127b831a2af29a03ab07b262abf46ada3b4e (diff) | |
download | upstream-5159d71983e649a89568e46d9ff02731beedd571.tar.gz upstream-5159d71983e649a89568e46d9ff02731beedd571.tar.bz2 upstream-5159d71983e649a89568e46d9ff02731beedd571.zip |
layerscape: update patches-4.14 to LSDK 19.03
All patches of LSDK 19.03 were ported to Openwrt kernel.
We still used an all-in-one patch for each IP/feature for
OpenWrt.
Below are the changes this patch introduced.
- Updated original IP/feature patches to LSDK 19.03.
- Added new IP/feature patches for eTSEC/PTP/TMU.
- Squashed scattered patches into IP/feature patches.
- Updated config-4.14 correspondingly.
- Refreshed all patches.
More info about LSDK and the kernel:
- https://lsdk.github.io/components.html
- https://source.codeaurora.org/external/qoriq/qoriq-components/linux
Signed-off-by: Biwen Li <biwen.li@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
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.patch | 681 |
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 |