Re: ACPI device using sub-resource of PCI device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Aug 12, 2016 at 11:45:30AM -0500, Aaron Durbin wrote:
> Was anyone able to take a look into a solution for the current
> problem?  Again, please feel free to ask if anyone would like help
> testing potential solutions.

Below is one proposal for fixing the issue. It is just a prototype and
I'm not sure if it takes everything needed into account. Would you be
able to try it out and let us know if it works for you?

diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 159f7f19abce..72068415f806 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
+#include <linux/pci.h>
 
 #include "internal.h"
 
@@ -30,6 +31,35 @@ static const struct acpi_device_id forbidden_id_list[] = {
 	{"", 0},
 };
 
+static struct resource *acpi_find_parent_resource(struct acpi_device *adev,
+						  struct resource *res)
+{
+	struct device *parent;
+
+	parent = acpi_get_first_physical_node(adev->parent);
+	if (!parent)
+		return NULL;
+
+#if IS_ENABLED(CONFIG_PCI)
+	if (dev_is_pci(parent)) {
+		struct pci_dev *pdev = to_pci_dev(parent);
+
+		if (!pci_is_bridge(pdev)) {
+			int i;
+
+			for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+				struct resource *r = &pdev->resource[i];
+
+				if (r->start && resource_contains(r, res))
+					return r;
+			}
+		}
+	}
+#endif
+
+	return NULL;
+}
+
 /**
  * acpi_create_platform_device - Create platform device for ACPI device node
  * @adev: ACPI device node to create a platform device for.
@@ -69,8 +99,17 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
 			return ERR_PTR(-ENOMEM);
 		}
 		count = 0;
-		list_for_each_entry(rentry, &resource_list, node)
-			resources[count++] = *rentry->res;
+		list_for_each_entry(rentry, &resource_list, node) {
+			struct resource *res = &resources[count++];
+
+			*res = *rentry->res;
+			/*
+			 * If the device has parent we need to take its
+			 * resources into account as well because this
+			 * device might consume part of those.
+			 */
+			res->parent = acpi_find_parent_resource(adev, res);
+		}
 
 		acpi_dev_free_resource_list(&resource_list);
 	}
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux