PCI updates for v3.9:
ASPM Revert "PCI/ACPI: Request _OSC control before scanning PCI root bus" kexec PCI: Don't try to disable Bus Master on disconnected PCI devices Platform ROM images PCI: Add PCI ROM helper for platform-provided ROM images nouveau: Attempt to use platform-provided ROM image radeon: Attempt to use platform-provided ROM image Hotplug PCI/ACPI: Always resume devices on ACPI wakeup notifications PCI/PM: Disable runtime PM of PCIe ports EISA EISA/PCI: Fix bus res reference EISA/PCI: Init EISA early, before PNP -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJRXzmPAAoJEFmIoMA60/r8svoQAIb1Z11DAdPfTaXThwEIURZb KC4wzfLMAZCRvfY6j6qZw6Qi3NT6ZqgrZxSXgV0myB6Luwcv80+D2BHmDnRoxRYD ywAm2m8vwoUq5s7MsaGHRLViBafL5TDs1KQLVEPkJ+B1gCzo61UWXPVDu+z9u+Fx t9fNV5Xc/uaxciXZYVnPGTCFjCVTqa95x16bF6NgmG1j1DHYuX7fBVSsJc2CS77m P2oyrfLmsKUA7jKHD4ntbIslYcqUC5NF8wcRad324Pzi93IwdktUSn8tqqNFCX9T EE8hxCp24CPm6ngyCFIIkqYM/MMDM8YVqBwuZjngm3+tjaS3hBIrr1jBDenUgncY 2WRomgRzBwaa8nTr5xhin3kYGRkQAEf3M8RWG70YBppTidvvoUt0bfxSfSlN9R/t g/7Eu4u35+lJ9F+Gg4unc0JrydkSJG1tfE+0LaEOhqXgCwloPR3kk08qcHPA2NHQ dlEMJ3FSUHvINoRE7pm6+E2lcbGvZjCa9Cvd9IbdJ6r4wVYI7pHl8Zlp/sf3HZdV sKRAw7fSazoFCX73lHR0f1zx7l1OdTmDSxEHv/pQA+xVt7K0DcOq+Mj0B84pVYcl WSRUcr6jAi91syuKX+8TRpbfACb25PkPrEFEsjsGcBq+I/a15e8a+sIW31Z66PNu ICejTqh/2/aOlgFg9OBs =gIGr -----END PGP SIGNATURE----- Merge tag 'pci-v3.9-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci Pull PCI fixes from Bjorn Helgaas: "PCI updates for v3.9: ASPM Revert "PCI/ACPI: Request _OSC control before scanning PCI root bus" kexec PCI: Don't try to disable Bus Master on disconnected PCI devices Platform ROM images PCI: Add PCI ROM helper for platform-provided ROM images nouveau: Attempt to use platform-provided ROM image radeon: Attempt to use platform-provided ROM image Hotplug PCI/ACPI: Always resume devices on ACPI wakeup notifications PCI/PM: Disable runtime PM of PCIe ports EISA EISA/PCI: Fix bus res reference EISA/PCI: Init EISA early, before PNP" * tag 'pci-v3.9-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: PCI/PM: Disable runtime PM of PCIe ports PCI/ACPI: Always resume devices on ACPI wakeup notifications PCI: Don't try to disable Bus Master on disconnected PCI devices Revert "PCI/ACPI: Request _OSC control before scanning PCI root bus" radeon: Attempt to use platform-provided ROM image nouveau: Attempt to use platform-provided ROM image EISA/PCI: Init EISA early, before PNP EISA/PCI: Fix bus res reference PCI: Add PCI ROM helper for platform-provided ROM images
This commit is contained in:
commit
b196553a7f
9 changed files with 170 additions and 119 deletions
|
@ -415,7 +415,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
|
||||||
struct acpi_pci_root *root;
|
struct acpi_pci_root *root;
|
||||||
struct acpi_pci_driver *driver;
|
struct acpi_pci_driver *driver;
|
||||||
u32 flags, base_flags;
|
u32 flags, base_flags;
|
||||||
bool is_osc_granted = false;
|
|
||||||
|
|
||||||
root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
|
root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
|
||||||
if (!root)
|
if (!root)
|
||||||
|
@ -476,6 +475,30 @@ static int acpi_pci_root_add(struct acpi_device *device,
|
||||||
flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
|
flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
|
||||||
acpi_pci_osc_support(root, flags);
|
acpi_pci_osc_support(root, flags);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TBD: Need PCI interface for enumeration/configuration of roots.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mutex_lock(&acpi_pci_root_lock);
|
||||||
|
list_add_tail(&root->node, &acpi_pci_roots);
|
||||||
|
mutex_unlock(&acpi_pci_root_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scan the Root Bridge
|
||||||
|
* --------------------
|
||||||
|
* Must do this prior to any attempt to bind the root device, as the
|
||||||
|
* PCI namespace does not get created until this call is made (and
|
||||||
|
* thus the root bridge's pci_dev does not exist).
|
||||||
|
*/
|
||||||
|
root->bus = pci_acpi_scan_root(root);
|
||||||
|
if (!root->bus) {
|
||||||
|
printk(KERN_ERR PREFIX
|
||||||
|
"Bus %04x:%02x not present in PCI namespace\n",
|
||||||
|
root->segment, (unsigned int)root->secondary.start);
|
||||||
|
result = -ENODEV;
|
||||||
|
goto out_del_root;
|
||||||
|
}
|
||||||
|
|
||||||
/* Indicate support for various _OSC capabilities. */
|
/* Indicate support for various _OSC capabilities. */
|
||||||
if (pci_ext_cfg_avail())
|
if (pci_ext_cfg_avail())
|
||||||
flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
|
flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
|
||||||
|
@ -494,6 +517,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
|
||||||
flags = base_flags;
|
flags = base_flags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pcie_ports_disabled
|
if (!pcie_ports_disabled
|
||||||
&& (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) {
|
&& (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) {
|
||||||
flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
|
flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
|
||||||
|
@ -514,54 +538,28 @@ static int acpi_pci_root_add(struct acpi_device *device,
|
||||||
status = acpi_pci_osc_control_set(device->handle, &flags,
|
status = acpi_pci_osc_control_set(device->handle, &flags,
|
||||||
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
|
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
|
||||||
if (ACPI_SUCCESS(status)) {
|
if (ACPI_SUCCESS(status)) {
|
||||||
is_osc_granted = true;
|
|
||||||
dev_info(&device->dev,
|
dev_info(&device->dev,
|
||||||
"ACPI _OSC control (0x%02x) granted\n", flags);
|
"ACPI _OSC control (0x%02x) granted\n", flags);
|
||||||
|
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
|
||||||
|
/*
|
||||||
|
* We have ASPM control, but the FADT indicates
|
||||||
|
* that it's unsupported. Clear it.
|
||||||
|
*/
|
||||||
|
pcie_clear_aspm(root->bus);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
is_osc_granted = false;
|
|
||||||
dev_info(&device->dev,
|
dev_info(&device->dev,
|
||||||
"ACPI _OSC request failed (%s), "
|
"ACPI _OSC request failed (%s), "
|
||||||
"returned control mask: 0x%02x\n",
|
"returned control mask: 0x%02x\n",
|
||||||
acpi_format_exception(status), flags);
|
acpi_format_exception(status), flags);
|
||||||
|
pr_info("ACPI _OSC control for PCIe not granted, "
|
||||||
|
"disabling ASPM\n");
|
||||||
|
pcie_no_aspm();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dev_info(&device->dev,
|
dev_info(&device->dev,
|
||||||
"Unable to request _OSC control "
|
"Unable to request _OSC control "
|
||||||
"(_OSC support mask: 0x%02x)\n", flags);
|
"(_OSC support mask: 0x%02x)\n", flags);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TBD: Need PCI interface for enumeration/configuration of roots.
|
|
||||||
*/
|
|
||||||
|
|
||||||
mutex_lock(&acpi_pci_root_lock);
|
|
||||||
list_add_tail(&root->node, &acpi_pci_roots);
|
|
||||||
mutex_unlock(&acpi_pci_root_lock);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Scan the Root Bridge
|
|
||||||
* --------------------
|
|
||||||
* Must do this prior to any attempt to bind the root device, as the
|
|
||||||
* PCI namespace does not get created until this call is made (and
|
|
||||||
* thus the root bridge's pci_dev does not exist).
|
|
||||||
*/
|
|
||||||
root->bus = pci_acpi_scan_root(root);
|
|
||||||
if (!root->bus) {
|
|
||||||
printk(KERN_ERR PREFIX
|
|
||||||
"Bus %04x:%02x not present in PCI namespace\n",
|
|
||||||
root->segment, (unsigned int)root->secondary.start);
|
|
||||||
result = -ENODEV;
|
|
||||||
goto out_del_root;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ASPM setting */
|
|
||||||
if (is_osc_granted) {
|
|
||||||
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM)
|
|
||||||
pcie_clear_aspm(root->bus);
|
|
||||||
} else {
|
|
||||||
pr_info("ACPI _OSC control for PCIe not granted, "
|
|
||||||
"disabling ASPM\n");
|
|
||||||
pcie_no_aspm();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pci_acpi_add_bus_pm_notifier(device, root->bus);
|
pci_acpi_add_bus_pm_notifier(device, root->bus);
|
||||||
|
|
|
@ -19,10 +19,10 @@
|
||||||
/* There is only *one* pci_eisa device per machine, right ? */
|
/* There is only *one* pci_eisa device per machine, right ? */
|
||||||
static struct eisa_root_device pci_eisa_root;
|
static struct eisa_root_device pci_eisa_root;
|
||||||
|
|
||||||
static int __init pci_eisa_init(struct pci_dev *pdev,
|
static int __init pci_eisa_init(struct pci_dev *pdev)
|
||||||
const struct pci_device_id *ent)
|
|
||||||
{
|
{
|
||||||
int rc;
|
int rc, i;
|
||||||
|
struct resource *res, *bus_res = NULL;
|
||||||
|
|
||||||
if ((rc = pci_enable_device (pdev))) {
|
if ((rc = pci_enable_device (pdev))) {
|
||||||
printk (KERN_ERR "pci_eisa : Could not enable device %s\n",
|
printk (KERN_ERR "pci_eisa : Could not enable device %s\n",
|
||||||
|
@ -30,9 +30,30 @@ static int __init pci_eisa_init(struct pci_dev *pdev,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Intel 82375 PCI-EISA bridge is a subtractive-decode PCI
|
||||||
|
* device, so the resources available on EISA are the same as those
|
||||||
|
* available on the 82375 bus. This works the same as a PCI-PCI
|
||||||
|
* bridge in subtractive-decode mode (see pci_read_bridge_bases()).
|
||||||
|
* We assume other PCI-EISA bridges are similar.
|
||||||
|
*
|
||||||
|
* eisa_root_register() can only deal with a single io port resource,
|
||||||
|
* so we use the first valid io port resource.
|
||||||
|
*/
|
||||||
|
pci_bus_for_each_resource(pdev->bus, res, i)
|
||||||
|
if (res && (res->flags & IORESOURCE_IO)) {
|
||||||
|
bus_res = res;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bus_res) {
|
||||||
|
dev_err(&pdev->dev, "No resources available\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
pci_eisa_root.dev = &pdev->dev;
|
pci_eisa_root.dev = &pdev->dev;
|
||||||
pci_eisa_root.res = pdev->bus->resource[0];
|
pci_eisa_root.res = bus_res;
|
||||||
pci_eisa_root.bus_base_addr = pdev->bus->resource[0]->start;
|
pci_eisa_root.bus_base_addr = bus_res->start;
|
||||||
pci_eisa_root.slots = EISA_MAX_SLOTS;
|
pci_eisa_root.slots = EISA_MAX_SLOTS;
|
||||||
pci_eisa_root.dma_mask = pdev->dma_mask;
|
pci_eisa_root.dma_mask = pdev->dma_mask;
|
||||||
dev_set_drvdata(pci_eisa_root.dev, &pci_eisa_root);
|
dev_set_drvdata(pci_eisa_root.dev, &pci_eisa_root);
|
||||||
|
@ -45,22 +66,26 @@ static int __init pci_eisa_init(struct pci_dev *pdev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pci_device_id pci_eisa_pci_tbl[] = {
|
/*
|
||||||
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
* We have to call pci_eisa_init_early() before pnpacpi_init()/isapnp_init().
|
||||||
PCI_CLASS_BRIDGE_EISA << 8, 0xffff00, 0 },
|
* Otherwise pnp resource will get enabled early and could prevent eisa
|
||||||
{ 0, }
|
* to be initialized.
|
||||||
};
|
* Also need to make sure pci_eisa_init_early() is called after
|
||||||
|
* x86/pci_subsys_init().
|
||||||
static struct pci_driver __refdata pci_eisa_driver = {
|
* So need to use subsys_initcall_sync with it.
|
||||||
.name = "pci_eisa",
|
*/
|
||||||
.id_table = pci_eisa_pci_tbl,
|
static int __init pci_eisa_init_early(void)
|
||||||
.probe = pci_eisa_init,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init pci_eisa_init_module (void)
|
|
||||||
{
|
{
|
||||||
return pci_register_driver (&pci_eisa_driver);
|
struct pci_dev *dev = NULL;
|
||||||
}
|
int ret;
|
||||||
|
|
||||||
device_initcall(pci_eisa_init_module);
|
for_each_pci_dev(dev)
|
||||||
MODULE_DEVICE_TABLE(pci, pci_eisa_pci_tbl);
|
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_EISA) {
|
||||||
|
ret = pci_eisa_init(dev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
subsys_initcall_sync(pci_eisa_init_early);
|
||||||
|
|
|
@ -248,6 +248,22 @@ nouveau_bios_shadow_pci(struct nouveau_bios *bios)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_bios_shadow_platform(struct nouveau_bios *bios)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev = nv_device(bios)->pdev;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
void __iomem *rom = pci_platform_rom(pdev, &size);
|
||||||
|
if (rom && size) {
|
||||||
|
bios->data = kmalloc(size, GFP_KERNEL);
|
||||||
|
if (bios->data) {
|
||||||
|
memcpy_fromio(bios->data, rom, size);
|
||||||
|
bios->size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nouveau_bios_score(struct nouveau_bios *bios, const bool writeable)
|
nouveau_bios_score(struct nouveau_bios *bios, const bool writeable)
|
||||||
{
|
{
|
||||||
|
@ -288,6 +304,7 @@ nouveau_bios_shadow(struct nouveau_bios *bios)
|
||||||
{ "PROM", nouveau_bios_shadow_prom, false, 0, 0, NULL },
|
{ "PROM", nouveau_bios_shadow_prom, false, 0, 0, NULL },
|
||||||
{ "ACPI", nouveau_bios_shadow_acpi, true, 0, 0, NULL },
|
{ "ACPI", nouveau_bios_shadow_acpi, true, 0, 0, NULL },
|
||||||
{ "PCIROM", nouveau_bios_shadow_pci, true, 0, 0, NULL },
|
{ "PCIROM", nouveau_bios_shadow_pci, true, 0, 0, NULL },
|
||||||
|
{ "PLATFORM", nouveau_bios_shadow_platform, true, 0, 0, NULL },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
struct methods *mthd, *best;
|
struct methods *mthd, *best;
|
||||||
|
|
|
@ -99,6 +99,29 @@ static bool radeon_read_bios(struct radeon_device *rdev)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool radeon_read_platform_bios(struct radeon_device *rdev)
|
||||||
|
{
|
||||||
|
uint8_t __iomem *bios;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
rdev->bios = NULL;
|
||||||
|
|
||||||
|
bios = pci_platform_rom(rdev->pdev, &size);
|
||||||
|
if (!bios) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
rdev->bios = kmemdup(bios, size, GFP_KERNEL);
|
||||||
|
if (rdev->bios == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
/* ATRM is used to get the BIOS on the discrete cards in
|
/* ATRM is used to get the BIOS on the discrete cards in
|
||||||
* dual-gpu systems.
|
* dual-gpu systems.
|
||||||
|
@ -620,6 +643,9 @@ bool radeon_get_bios(struct radeon_device *rdev)
|
||||||
if (r == false) {
|
if (r == false) {
|
||||||
r = radeon_read_disabled_bios(rdev);
|
r = radeon_read_disabled_bios(rdev);
|
||||||
}
|
}
|
||||||
|
if (r == false) {
|
||||||
|
r = radeon_read_platform_bios(rdev);
|
||||||
|
}
|
||||||
if (r == false || rdev->bios == NULL) {
|
if (r == false || rdev->bios == NULL) {
|
||||||
DRM_ERROR("Unable to locate a BIOS ROM\n");
|
DRM_ERROR("Unable to locate a BIOS ROM\n");
|
||||||
rdev->bios = NULL;
|
rdev->bios = NULL;
|
||||||
|
|
|
@ -53,14 +53,15 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pci_dev->pm_cap || !pci_dev->pme_support
|
/* Clear PME Status if set. */
|
||||||
|| pci_check_pme_status(pci_dev)) {
|
if (pci_dev->pme_support)
|
||||||
if (pci_dev->pme_poll)
|
pci_check_pme_status(pci_dev);
|
||||||
pci_dev->pme_poll = false;
|
|
||||||
|
|
||||||
pci_wakeup_event(pci_dev);
|
if (pci_dev->pme_poll)
|
||||||
pm_runtime_resume(&pci_dev->dev);
|
pci_dev->pme_poll = false;
|
||||||
}
|
|
||||||
|
pci_wakeup_event(pci_dev);
|
||||||
|
pm_runtime_resume(&pci_dev->dev);
|
||||||
|
|
||||||
if (pci_dev->subordinate)
|
if (pci_dev->subordinate)
|
||||||
pci_pme_wakeup_bus(pci_dev->subordinate);
|
pci_pme_wakeup_bus(pci_dev->subordinate);
|
||||||
|
|
|
@ -390,9 +390,10 @@ static void pci_device_shutdown(struct device *dev)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Turn off Bus Master bit on the device to tell it to not
|
* Turn off Bus Master bit on the device to tell it to not
|
||||||
* continue to do DMA
|
* continue to do DMA. Don't touch devices in D3cold or unknown states.
|
||||||
*/
|
*/
|
||||||
pci_clear_master(pci_dev);
|
if (pci_dev->current_state <= PCI_D3hot)
|
||||||
|
pci_clear_master(pci_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
|
@ -184,14 +184,6 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {
|
||||||
#define PCIE_PORTDRV_PM_OPS NULL
|
#define PCIE_PORTDRV_PM_OPS NULL
|
||||||
#endif /* !PM */
|
#endif /* !PM */
|
||||||
|
|
||||||
/*
|
|
||||||
* PCIe port runtime suspend is broken for some chipsets, so use a
|
|
||||||
* black list to disable runtime PM for these chipsets.
|
|
||||||
*/
|
|
||||||
static const struct pci_device_id port_runtime_pm_black_list[] = {
|
|
||||||
{ /* end: all zeroes */ }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pcie_portdrv_probe - Probe PCI-Express port devices
|
* pcie_portdrv_probe - Probe PCI-Express port devices
|
||||||
* @dev: PCI-Express port device being probed
|
* @dev: PCI-Express port device being probed
|
||||||
|
@ -225,16 +217,11 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
|
||||||
* it by default.
|
* it by default.
|
||||||
*/
|
*/
|
||||||
dev->d3cold_allowed = false;
|
dev->d3cold_allowed = false;
|
||||||
if (!pci_match_id(port_runtime_pm_black_list, dev))
|
|
||||||
pm_runtime_put_noidle(&dev->dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcie_portdrv_remove(struct pci_dev *dev)
|
static void pcie_portdrv_remove(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
if (!pci_match_id(port_runtime_pm_black_list, dev))
|
|
||||||
pm_runtime_get_noresume(&dev->dev);
|
|
||||||
pcie_port_device_remove(dev);
|
pcie_port_device_remove(dev);
|
||||||
pci_disable_device(dev);
|
pci_disable_device(dev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,27 +100,6 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
|
||||||
return min((size_t)(image - rom), size);
|
return min((size_t)(image - rom), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static loff_t pci_find_rom(struct pci_dev *pdev, size_t *size)
|
|
||||||
{
|
|
||||||
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
|
||||||
loff_t start;
|
|
||||||
|
|
||||||
/* assign the ROM an address if it doesn't have one */
|
|
||||||
if (res->parent == NULL && pci_assign_resource(pdev, PCI_ROM_RESOURCE))
|
|
||||||
return 0;
|
|
||||||
start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
|
||||||
*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
|
||||||
|
|
||||||
if (*size == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Enable ROM space decodes */
|
|
||||||
if (pci_enable_rom(pdev))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pci_map_rom - map a PCI ROM to kernel space
|
* pci_map_rom - map a PCI ROM to kernel space
|
||||||
* @pdev: pointer to pci device struct
|
* @pdev: pointer to pci device struct
|
||||||
|
@ -135,7 +114,7 @@ static loff_t pci_find_rom(struct pci_dev *pdev, size_t *size)
|
||||||
void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
|
void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
|
||||||
{
|
{
|
||||||
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
||||||
loff_t start = 0;
|
loff_t start;
|
||||||
void __iomem *rom;
|
void __iomem *rom;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -154,21 +133,21 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
|
||||||
return (void __iomem *)(unsigned long)
|
return (void __iomem *)(unsigned long)
|
||||||
pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
||||||
} else {
|
} else {
|
||||||
start = pci_find_rom(pdev, size);
|
/* assign the ROM an address if it doesn't have one */
|
||||||
|
if (res->parent == NULL &&
|
||||||
|
pci_assign_resource(pdev,PCI_ROM_RESOURCE))
|
||||||
|
return NULL;
|
||||||
|
start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
||||||
|
*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
||||||
|
if (*size == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Enable ROM space decodes */
|
||||||
|
if (pci_enable_rom(pdev))
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Some devices may provide ROMs via a source other than the BAR
|
|
||||||
*/
|
|
||||||
if (!start && pdev->rom && pdev->romlen) {
|
|
||||||
*size = pdev->romlen;
|
|
||||||
return phys_to_virt(pdev->rom);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!start)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
rom = ioremap(start, *size);
|
rom = ioremap(start, *size);
|
||||||
if (!rom) {
|
if (!rom) {
|
||||||
/* restore enable if ioremap fails */
|
/* restore enable if ioremap fails */
|
||||||
|
@ -202,8 +181,7 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
|
||||||
if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY))
|
if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!pdev->rom || !pdev->romlen)
|
iounmap(rom);
|
||||||
iounmap(rom);
|
|
||||||
|
|
||||||
/* Disable again before continuing, leave enabled if pci=rom */
|
/* Disable again before continuing, leave enabled if pci=rom */
|
||||||
if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW)))
|
if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW)))
|
||||||
|
@ -227,7 +205,24 @@ void pci_cleanup_rom(struct pci_dev *pdev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pci_platform_rom - provides a pointer to any ROM image provided by the
|
||||||
|
* platform
|
||||||
|
* @pdev: pointer to pci device struct
|
||||||
|
* @size: pointer to receive size of pci window over ROM
|
||||||
|
*/
|
||||||
|
void __iomem *pci_platform_rom(struct pci_dev *pdev, size_t *size)
|
||||||
|
{
|
||||||
|
if (pdev->rom && pdev->romlen) {
|
||||||
|
*size = pdev->romlen;
|
||||||
|
return phys_to_virt((phys_addr_t)pdev->rom);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(pci_map_rom);
|
EXPORT_SYMBOL(pci_map_rom);
|
||||||
EXPORT_SYMBOL(pci_unmap_rom);
|
EXPORT_SYMBOL(pci_unmap_rom);
|
||||||
EXPORT_SYMBOL_GPL(pci_enable_rom);
|
EXPORT_SYMBOL_GPL(pci_enable_rom);
|
||||||
EXPORT_SYMBOL_GPL(pci_disable_rom);
|
EXPORT_SYMBOL_GPL(pci_disable_rom);
|
||||||
|
EXPORT_SYMBOL(pci_platform_rom);
|
||||||
|
|
|
@ -916,6 +916,7 @@ void pci_disable_rom(struct pci_dev *pdev);
|
||||||
void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
|
void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
|
||||||
void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom);
|
void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom);
|
||||||
size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size);
|
size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size);
|
||||||
|
void __iomem __must_check *pci_platform_rom(struct pci_dev *pdev, size_t *size);
|
||||||
|
|
||||||
/* Power management related routines */
|
/* Power management related routines */
|
||||||
int pci_save_state(struct pci_dev *dev);
|
int pci_save_state(struct pci_dev *dev);
|
||||||
|
|
Loading…
Add table
Reference in a new issue