|
@@ -295,6 +295,45 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_AMD_NB
|
|
|
+
|
|
|
+#include <asm/amd_nb.h>
|
|
|
+
|
|
|
+static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
|
|
|
+{
|
|
|
+ resource_size_t start, end;
|
|
|
+ struct pnp_resource *pnp_res;
|
|
|
+ struct resource *res;
|
|
|
+ struct resource mmconfig_res, *mmconfig;
|
|
|
+
|
|
|
+ mmconfig = amd_get_mmconfig_range(&mmconfig_res);
|
|
|
+ if (!mmconfig)
|
|
|
+ return;
|
|
|
+
|
|
|
+ list_for_each_entry(pnp_res, &dev->resources, list) {
|
|
|
+ res = &pnp_res->res;
|
|
|
+ if (res->end < mmconfig->start || res->start > mmconfig->end ||
|
|
|
+ (res->start == mmconfig->start && res->end == mmconfig->end))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ dev_info(&dev->dev, FW_BUG
|
|
|
+ "%pR covers only part of AMD MMCONFIG area %pR; adding more reservations\n",
|
|
|
+ res, mmconfig);
|
|
|
+ if (mmconfig->start < res->start) {
|
|
|
+ start = mmconfig->start;
|
|
|
+ end = res->start - 1;
|
|
|
+ pnp_add_mem_resource(dev, start, end, 0);
|
|
|
+ }
|
|
|
+ if (mmconfig->end > res->end) {
|
|
|
+ start = res->end + 1;
|
|
|
+ end = mmconfig->end;
|
|
|
+ pnp_add_mem_resource(dev, start, end, 0);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
/*
|
|
|
* PnP Quirks
|
|
|
* Cards or devices that need some tweaking due to incomplete resource info
|
|
@@ -322,6 +361,9 @@ static struct pnp_fixup pnp_fixups[] = {
|
|
|
/* PnP resources that might overlap PCI BARs */
|
|
|
{"PNP0c01", quirk_system_pci_resources},
|
|
|
{"PNP0c02", quirk_system_pci_resources},
|
|
|
+#ifdef CONFIG_AMD_NB
|
|
|
+ {"PNP0c01", quirk_amd_mmconfig_area},
|
|
|
+#endif
|
|
|
{""}
|
|
|
};
|
|
|
|