Commit 86845e37 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/resource'

  - Use ioremap(), not phys_to_virt() for platform ROM, to fix video ROM
    mapping with CONFIG_HIGHMEM (Mikel Rychliski)

  - Add support for root bus sizing so we don't have to assume host bridge
    windows are known a priori (Ivan Kokshaysky)

  - Fix alpha Nautilus PCI setup, which has been broken since we started
    enforcing window limits in resource allocation (Ivan Kokshaysky)

* pci/resource:
  alpha: Fix nautilus PCI setup
  PCI: Add support for root bus sizing
  PCI: Use ioremap(), not phys_to_virt() for platform ROM
parents de71a000 5799dac9
Loading
Loading
Loading
Loading
+20 −32
Original line number Diff line number Diff line
@@ -187,10 +187,6 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr)

extern void pcibios_claim_one_bus(struct pci_bus *);

static struct resource irongate_io = {
	.name	= "Irongate PCI IO",
	.flags	= IORESOURCE_IO,
};
static struct resource irongate_mem = {
	.name	= "Irongate PCI MEM",
	.flags	= IORESOURCE_MEM,
@@ -208,17 +204,19 @@ nautilus_init_pci(void)
	struct pci_controller *hose = hose_head;
	struct pci_host_bridge *bridge;
	struct pci_bus *bus;
	struct pci_dev *irongate;
	unsigned long bus_align, bus_size, pci_mem;
	unsigned long memtop = max_low_pfn << PAGE_SHIFT;
	int ret;

	bridge = pci_alloc_host_bridge(0);
	if (!bridge)
		return;

	/* Use default IO. */
	pci_add_resource(&bridge->windows, &ioport_resource);
	pci_add_resource(&bridge->windows, &iomem_resource);
	/* Irongate PCI memory aperture, calculate requred size before
	   setting it up. */
	pci_add_resource(&bridge->windows, &irongate_mem);

	pci_add_resource(&bridge->windows, &busn_resource);
	bridge->dev.parent = NULL;
	bridge->sysdata = hose;
@@ -226,59 +224,49 @@ nautilus_init_pci(void)
	bridge->ops = alpha_mv.pci_ops;
	bridge->swizzle_irq = alpha_mv.pci_swizzle;
	bridge->map_irq = alpha_mv.pci_map_irq;
	bridge->size_windows = 1;

	/* Scan our single hose.  */
	ret = pci_scan_root_bus_bridge(bridge);
	if (ret) {
	if (pci_scan_root_bus_bridge(bridge)) {
		pci_free_host_bridge(bridge);
		return;
	}

	bus = hose->bus = bridge->bus;
	pcibios_claim_one_bus(bus);

	irongate = pci_get_domain_bus_and_slot(pci_domain_nr(bus), 0, 0);
	bus->self = irongate;
	bus->resource[0] = &irongate_io;
	bus->resource[1] = &irongate_mem;

	pci_bus_size_bridges(bus);

	/* IO port range. */
	bus->resource[0]->start = 0;
	bus->resource[0]->end = 0xffff;

	/* Set up PCI memory range - limit is hardwired to 0xffffffff,
	   base must be at aligned to 16Mb. */
	bus_align = bus->resource[1]->start;
	bus_size = bus->resource[1]->end + 1 - bus_align;
	/* Now we've got the size and alignment of PCI memory resources
	   stored in irongate_mem. Set up the PCI memory range: limit is
	   hardwired to 0xffffffff, base must be aligned to 16Mb. */
	bus_align = irongate_mem.start;
	bus_size = irongate_mem.end + 1 - bus_align;
	if (bus_align < 0x1000000UL)
		bus_align = 0x1000000UL;

	pci_mem = (0x100000000UL - bus_size) & -bus_align;
	irongate_mem.start = pci_mem;
	irongate_mem.end = 0xffffffffUL;

	bus->resource[1]->start = pci_mem;
	bus->resource[1]->end = 0xffffffffUL;
	if (request_resource(&iomem_resource, bus->resource[1]) < 0)
	/* Register our newly calculated PCI memory window in the resource
	   tree. */
	if (request_resource(&iomem_resource, &irongate_mem) < 0)
		printk(KERN_ERR "Failed to request MEM on hose 0\n");

	printk(KERN_INFO "Irongate pci_mem %pR\n", &irongate_mem);

	if (pci_mem < memtop)
		memtop = pci_mem;
	if (memtop > alpha_mv.min_mem_address) {
		free_reserved_area(__va(alpha_mv.min_mem_address),
				   __va(memtop), -1, NULL);
		printk("nautilus_init_pci: %ldk freed\n",
		printk(KERN_INFO "nautilus_init_pci: %ldk freed\n",
			(memtop - alpha_mv.min_mem_address) >> 10);
	}

	if ((IRONGATE0->dev_vendor >> 16) > 0x7006)	/* Albacore? */
		IRONGATE0->pci_mem = pci_mem;

	pci_bus_assign_resources(bus);

	/* pci_common_swizzle() relies on bus->self being NULL
	   for the root bus, so just clear it. */
	bus->self = NULL;
	pci_bus_add_devices(bus);
}

+18 −13
Original line number Diff line number Diff line
@@ -192,30 +192,35 @@ static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev)

static bool amdgpu_read_platform_bios(struct amdgpu_device *adev)
{
	uint8_t __iomem *bios;
	size_t size;
	phys_addr_t rom = adev->pdev->rom;
	size_t romlen = adev->pdev->romlen;
	void __iomem *bios;

	adev->bios = NULL;

	bios = pci_platform_rom(adev->pdev, &size);
	if (!bios) {
	if (!rom || romlen == 0)
		return false;
	}

	adev->bios = kzalloc(size, GFP_KERNEL);
	if (adev->bios == NULL)
	adev->bios = kzalloc(romlen, GFP_KERNEL);
	if (!adev->bios)
		return false;

	memcpy_fromio(adev->bios, bios, size);
	bios = ioremap(rom, romlen);
	if (!bios)
		goto free_bios;

	if (!check_atom_bios(adev->bios, size)) {
		kfree(adev->bios);
		return false;
	}
	memcpy_fromio(adev->bios, bios, romlen);
	iounmap(bios);

	adev->bios_size = size;
	if (!check_atom_bios(adev->bios, romlen))
		goto free_bios;

	adev->bios_size = romlen;

	return true;
free_bios:
	kfree(adev->bios);
	return false;
}

#ifdef CONFIG_ACPI
+15 −2
Original line number Diff line number Diff line
@@ -101,9 +101,13 @@ platform_init(struct nvkm_bios *bios, const char *name)
	else
		return ERR_PTR(-ENODEV);

	if (!pdev->rom || pdev->romlen == 0)
		return ERR_PTR(-ENODEV);

	if ((priv = kmalloc(sizeof(*priv), GFP_KERNEL))) {
		priv->size = pdev->romlen;
		if (ret = -ENODEV,
		    (priv->rom = pci_platform_rom(pdev, &priv->size)))
		    (priv->rom = ioremap(pdev->rom, pdev->romlen)))
			return priv;
		kfree(priv);
	}
@@ -111,11 +115,20 @@ platform_init(struct nvkm_bios *bios, const char *name)
	return ERR_PTR(ret);
}

static void
platform_fini(void *data)
{
	struct priv *priv = data;

	iounmap(priv->rom);
	kfree(priv);
}

const struct nvbios_source
nvbios_platform = {
	.name = "PLATFORM",
	.init = platform_init,
	.fini = (void(*)(void *))kfree,
	.fini = platform_fini,
	.read = pcirom_read,
	.rw = true,
};
+19 −11
Original line number Diff line number Diff line
@@ -108,25 +108,33 @@ static bool radeon_read_bios(struct radeon_device *rdev)

static bool radeon_read_platform_bios(struct radeon_device *rdev)
{
	uint8_t __iomem *bios;
	size_t size;
	phys_addr_t rom = rdev->pdev->rom;
	size_t romlen = rdev->pdev->romlen;
	void __iomem *bios;

	rdev->bios = NULL;

	bios = pci_platform_rom(rdev->pdev, &size);
	if (!bios) {
	if (!rom || romlen == 0)
		return false;
	}

	if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
		return false;
	}
	rdev->bios = kmemdup(bios, size, GFP_KERNEL);
	if (rdev->bios == NULL) {
	rdev->bios = kzalloc(romlen, GFP_KERNEL);
	if (!rdev->bios)
		return false;
	}

	bios = ioremap(rom, romlen);
	if (!bios)
		goto free_bios;

	memcpy_fromio(rdev->bios, bios, romlen);
	iounmap(bios);

	if (rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa)
		goto free_bios;

	return true;
free_bios:
	kfree(rdev->bios);
	return false;
}

#ifdef CONFIG_ACPI
+0 −17
Original line number Diff line number Diff line
@@ -195,20 +195,3 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
		pci_disable_rom(pdev);
}
EXPORT_SYMBOL(pci_unmap_rom);

/**
 * 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_platform_rom);
Loading