Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b196553a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 53f63189 de7d5f72
Loading
Loading
Loading
Loading
+37 −39
Original line number Diff line number Diff line
@@ -415,7 +415,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
	struct acpi_pci_root *root;
	struct acpi_pci_driver *driver;
	u32 flags, base_flags;
	bool is_osc_granted = false;

	root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
	if (!root)
@@ -476,6 +475,30 @@ static int acpi_pci_root_add(struct acpi_device *device,
	flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
	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. */
	if (pci_ext_cfg_avail())
		flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
@@ -494,6 +517,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
			flags = base_flags;
		}
	}

	if (!pcie_ports_disabled
	    && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) {
		flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
@@ -514,15 +538,23 @@ static int acpi_pci_root_add(struct acpi_device *device,
		status = acpi_pci_osc_control_set(device->handle, &flags,
				       OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
		if (ACPI_SUCCESS(status)) {
			is_osc_granted = true;
			dev_info(&device->dev,
				"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 {
			is_osc_granted = false;
			dev_info(&device->dev,
				"ACPI _OSC request failed (%s), "
				"returned control mask: 0x%02x\n",
				acpi_format_exception(status), flags);
			pr_info("ACPI _OSC control for PCIe not granted, "
				"disabling ASPM\n");
			pcie_no_aspm();
		}
	} else {
		dev_info(&device->dev,
@@ -530,40 +562,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
			 "(_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);
	if (device->wakeup.flags.run_wake)
		device_set_run_wake(root->bus->bridge, true);
+46 −21
Original line number Diff line number Diff line
@@ -19,10 +19,10 @@
/* There is only *one* pci_eisa device per machine, right ? */
static struct eisa_root_device pci_eisa_root;

static int __init pci_eisa_init(struct pci_dev *pdev,
				const struct pci_device_id *ent)
static int __init pci_eisa_init(struct pci_dev *pdev)
{
	int rc;
	int rc, i;
	struct resource *res, *bus_res = NULL;

	if ((rc = pci_enable_device (pdev))) {
		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;
	}

	/*
	 * 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.res	       = pdev->bus->resource[0];
	pci_eisa_root.bus_base_addr    = pdev->bus->resource[0]->start;
	pci_eisa_root.res	       = bus_res;
	pci_eisa_root.bus_base_addr    = bus_res->start;
	pci_eisa_root.slots	       = EISA_MAX_SLOTS;
	pci_eisa_root.dma_mask         = pdev->dma_mask;
	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;
}

static struct pci_device_id pci_eisa_pci_tbl[] = {
	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
	  PCI_CLASS_BRIDGE_EISA << 8, 0xffff00, 0 },
	{ 0, }
};

static struct pci_driver __refdata pci_eisa_driver = {
	.name		= "pci_eisa",
	.id_table	= pci_eisa_pci_tbl,
	.probe		= pci_eisa_init,
};

static int __init pci_eisa_init_module (void)
/*
 * We have to call pci_eisa_init_early() before pnpacpi_init()/isapnp_init().
 *   Otherwise pnp resource will get enabled early and could prevent eisa
 *   to be initialized.
 * Also need to make sure pci_eisa_init_early() is called after
 * x86/pci_subsys_init().
 * So need to use subsys_initcall_sync with it.
 */
static int __init pci_eisa_init_early(void)
{
	return pci_register_driver (&pci_eisa_driver);
	struct pci_dev *dev = NULL;
	int ret;

	for_each_pci_dev(dev)
		if ((dev->class >> 8) == PCI_CLASS_BRIDGE_EISA) {
			ret = pci_eisa_init(dev);
			if (ret)
				return ret;
		}

device_initcall(pci_eisa_init_module);
MODULE_DEVICE_TABLE(pci, pci_eisa_pci_tbl);
	return 0;
}
subsys_initcall_sync(pci_eisa_init_early);
+17 −0
Original line number Diff line number Diff line
@@ -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
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 },
		{ "ACPI", nouveau_bios_shadow_acpi, 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;
+26 −0
Original line number Diff line number Diff line
@@ -99,6 +99,29 @@ static bool radeon_read_bios(struct radeon_device *rdev)
	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
/* ATRM is used to get the BIOS on the discrete cards in
 * dual-gpu systems.
@@ -620,6 +643,9 @@ bool radeon_get_bios(struct radeon_device *rdev)
	if (r == false) {
		r = radeon_read_disabled_bios(rdev);
	}
	if (r == false) {
		r = radeon_read_platform_bios(rdev);
	}
	if (r == false || rdev->bios == NULL) {
		DRM_ERROR("Unable to locate a BIOS ROM\n");
		rdev->bios = NULL;
+8 −7
Original line number Diff line number Diff line
@@ -53,14 +53,15 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
		return;
	}

	if (!pci_dev->pm_cap || !pci_dev->pme_support
	     || pci_check_pme_status(pci_dev)) {
	/* Clear PME Status if set. */
	if (pci_dev->pme_support)
		pci_check_pme_status(pci_dev);

	if (pci_dev->pme_poll)
		pci_dev->pme_poll = false;

	pci_wakeup_event(pci_dev);
	pm_runtime_resume(&pci_dev->dev);
	}

	if (pci_dev->subordinate)
		pci_pme_wakeup_bus(pci_dev->subordinate);
Loading