From 95099d4622f8cb224d94e314c7a8e0df60b13f87 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 08:38:01 +0000
Subject: [PATCH] enable docker ppp
---
kernel/drivers/of/device.c | 87 +++++++++++++++++++++++--------------------
1 files changed, 47 insertions(+), 40 deletions(-)
diff --git a/kernel/drivers/of/device.c b/kernel/drivers/of/device.c
index 2587428..1122daa 100644
--- a/kernel/drivers/of/device.c
+++ b/kernel/drivers/of/device.c
@@ -5,7 +5,8 @@
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/of_iommu.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direct.h> /* for bus_dma_region */
+#include <linux/dma-map-ops.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
@@ -17,7 +18,7 @@
/**
* of_match_device - Tell if a struct device matches an of_device_id list
- * @ids: array of of device match structures to search in
+ * @matches: array of of device match structures to search in
* @dev: the of device structure to match against
*
* Used by a driver to check whether an platform_device present in the
@@ -78,6 +79,7 @@
* @np: Pointer to OF node having DMA configuration
* @force_dma: Whether device is to be set up by of_dma_configure() even if
* DMA capability is not explicitly described by firmware.
+ * @id: Optional const pointer value input id
*
* Try to get devices's DMA configuration from DT and update it
* accordingly.
@@ -86,16 +88,17 @@
* can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events
* to fix up DMA configuration.
*/
-int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma)
+int of_dma_configure_id(struct device *dev, struct device_node *np,
+ bool force_dma, const u32 *id)
{
- u64 dma_addr, paddr, size = 0;
- int ret;
- bool coherent;
- unsigned long offset;
const struct iommu_ops *iommu;
- u64 mask;
+ const struct bus_dma_region *map = NULL;
+ u64 dma_start = 0;
+ u64 mask, end, size = 0;
+ bool coherent;
+ int ret;
- ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
+ ret = of_dma_get_range(np, &map);
if (ret < 0) {
/*
* For legacy reasons, we have to assume some devices need
@@ -104,26 +107,35 @@
*/
if (!force_dma)
return ret == -ENODEV ? 0 : ret;
-
- dma_addr = offset = 0;
} else {
- offset = PFN_DOWN(paddr - dma_addr);
+ const struct bus_dma_region *r = map;
+ u64 dma_end = 0;
+
+ /* Determine the overall bounds of all DMA regions */
+ for (dma_start = ~0; r->size; r++) {
+ /* Take lower and upper limits */
+ if (r->dma_start < dma_start)
+ dma_start = r->dma_start;
+ if (r->dma_start + r->size > dma_end)
+ dma_end = r->dma_start + r->size;
+ }
+ size = dma_end - dma_start;
/*
* Add a work around to treat the size as mask + 1 in case
* it is defined in DT as a mask.
*/
if (size & 1) {
- dev_warn(dev, "Invalid size 0x%llx for dma-range\n",
+ dev_warn(dev, "Invalid size 0x%llx for dma-range(s)\n",
size);
size = size + 1;
}
if (!size) {
dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
+ kfree(map);
return -EINVAL;
}
- dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
}
/*
@@ -142,47 +154,41 @@
else if (!size)
size = 1ULL << 32;
- dev->dma_pfn_offset = offset;
-
/*
* Limit coherent and dma mask based on size and default mask
* set by the driver.
*/
- mask = DMA_BIT_MASK(ilog2(dma_addr + size - 1) + 1);
+ end = dma_start + size - 1;
+ mask = DMA_BIT_MASK(ilog2(end) + 1);
dev->coherent_dma_mask &= mask;
*dev->dma_mask &= mask;
- /* ...but only set bus mask if we found valid dma-ranges earlier */
- if (!ret)
- dev->bus_dma_mask = mask;
+ /* ...but only set bus limit and range map if we found valid dma-ranges earlier */
+ if (!ret) {
+ dev->bus_dma_limit = end;
+ dev->dma_range_map = map;
+ }
coherent = of_dma_is_coherent(np);
dev_dbg(dev, "device is%sdma coherent\n",
coherent ? " " : " not ");
- iommu = of_iommu_configure(dev, np);
- if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
+ iommu = of_iommu_configure(dev, np, id);
+ if (PTR_ERR(iommu) == -EPROBE_DEFER) {
+ /* Don't touch range map if it wasn't set from a valid dma-ranges */
+ if (!ret)
+ dev->dma_range_map = NULL;
+ kfree(map);
return -EPROBE_DEFER;
+ }
dev_dbg(dev, "device is%sbehind an iommu\n",
iommu ? " " : " not ");
- arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
+ arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
return 0;
}
-EXPORT_SYMBOL_GPL(of_dma_configure);
-
-/**
- * of_dma_deconfigure - Clean up DMA configuration
- * @dev: Device for which to clean up DMA configuration
- *
- * Clean up all configuration performed by of_dma_configure_ops() and free all
- * resources that have been allocated.
- */
-void of_dma_deconfigure(struct device *dev)
-{
- arch_teardown_dma_ops(dev);
-}
+EXPORT_SYMBOL_GPL(of_dma_configure_id);
int of_device_register(struct platform_device *pdev)
{
@@ -223,7 +229,7 @@
/* Name & Type */
/* %p eats all alphanum characters, so %c must be used here */
csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T',
- dev->of_node->type);
+ of_node_get_device_type(dev->of_node));
tsize = csize;
len -= csize;
if (str)
@@ -293,7 +299,7 @@
*/
void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
{
- const char *compat;
+ const char *compat, *type;
struct alias_prop *app;
struct property *p;
int seen = 0;
@@ -303,8 +309,9 @@
add_uevent_var(env, "OF_NAME=%pOFn", dev->of_node);
add_uevent_var(env, "OF_FULLNAME=%pOF", dev->of_node);
- if (dev->of_node->type && strcmp("<NULL>", dev->of_node->type) != 0)
- add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type);
+ type = of_node_get_device_type(dev->of_node);
+ if (type)
+ add_uevent_var(env, "OF_TYPE=%s", type);
/* Since the compatible field can contain pretty much anything
* it's not really legal to split it out with commas. We split it
--
Gitblit v1.6.2