diff options
author | Krishna Kishore <kthota@nvidia.com> | 2011-10-10 10:12:55 +0530 |
---|---|---|
committer | Rohan Somvanshi <rsomvanshi@nvidia.com> | 2012-02-15 00:48:43 -0800 |
commit | 91b077f8cf2498602efe975c629e0b4efce206b5 (patch) | |
tree | ae7d8429f63388cef4951b6c0907159ca5c8d888 /arch/arm/mach-tegra/pcie.c | |
parent | f0f11b070e50ec083b308c167cc53782f4f88749 (diff) |
tegra: pcie: Fix multiple ports detection
This patch fixes multiple port detection issue
in tegra pcie driver.
The issue is fixed by reserving IO resource
from ioport_resource memory and PCI MEM and
PCI PREFETCH MEM from iomem_resource. These
memory resources are common to all root
ports. The resource allocation is done in
preinit function.
MMIO space should be reserved for T30 as well.
fixes bug 637871
Signed-off-by: Manoj Chourasia<mchourasia@nvidia.com>
Change-Id: I555b90bd1e0033965c78772dbdc75ea8efd039dd
Reviewed-on: http://git-master/r/79800
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Manoj Chourasia <mchourasia@nvidia.com>
Reviewed-by: Jeremy Alves <jalves@nvidia.com>
Reviewed-by: Kaushik Sen <ksen@nvidia.com>
Tested-by: Krishna Thota <kthota@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Reviewed-by: Varun Wadekar <vwadekar@nvidia.com>
Tested-by: Mike Thompson <mikthompson@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/pcie.c')
-rw-r--r-- | arch/arm/mach-tegra/pcie.c | 95 |
1 files changed, 36 insertions, 59 deletions
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c index 780fe2a5ac70..f9f82a65c6cd 100644 --- a/arch/arm/mach-tegra/pcie.c +++ b/arch/arm/mach-tegra/pcie.c @@ -7,7 +7,7 @@ * Author: Mike Rapoport <mike@compulab.co.il> * * Based on NVIDIA PCIe driver - * Copyright (c) 2008-2011, NVIDIA Corporation. + * Copyright (c) 2008-2012, NVIDIA Corporation. * * Bits taken from arch/arm/mach-dove/pcie.c * @@ -346,6 +346,10 @@ static struct tegra_pcie_info tegra_pcie = { }, }; +static struct resource pcie_io_space; +static struct resource pcie_mem_space; +static struct resource pcie_prefetch_mem_space; + void __iomem *tegra_pcie_io_base; EXPORT_SYMBOL(tegra_pcie_io_base); @@ -514,6 +518,32 @@ static void __devinit tegra_pcie_relax_enable(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable); +static void __init tegra_pcie_preinit(void) +{ + pcie_io_space.name = "PCIe I/O Space"; + pcie_io_space.start = PCIBIOS_MIN_IO; + pcie_io_space.end = IO_SPACE_LIMIT; + pcie_io_space.flags = IORESOURCE_IO; + if (request_resource(&ioport_resource, &pcie_io_space)) + panic("can't allocate PCIe I/O space"); + + pcie_mem_space.name = "PCIe MEM Space"; + pcie_mem_space.start = MEM_BASE_0; + pcie_mem_space.end = MEM_BASE_0 + MEM_SIZE - 1; + pcie_mem_space.flags = IORESOURCE_MEM; + if (request_resource(&iomem_resource, &pcie_mem_space)) + panic("can't allocate PCIe MEM space"); + + pcie_prefetch_mem_space.name = "PCIe PREFETCH MEM Space"; + pcie_prefetch_mem_space.start = PREFETCH_MEM_BASE_0; + pcie_prefetch_mem_space.end = PREFETCH_MEM_BASE_0 + PREFETCH_MEM_SIZE + - 1; + pcie_prefetch_mem_space.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; + if (request_resource(&iomem_resource, &pcie_prefetch_mem_space)) + panic("can't allocate PCIe PREFETCH MEM space"); + +} + static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) { struct tegra_pcie_port *pp; @@ -524,61 +554,10 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) pp = tegra_pcie.port + nr; pp->root_bus_nr = sys->busnr; - /* - * IORESOURCE_IO - */ - snprintf(pp->io_space_name, sizeof(pp->io_space_name), - "PCIe %d I/O", pp->index); - pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0; - pp->res[0].name = pp->io_space_name; - if (pp->index == 0) { - pp->res[0].start = PCIBIOS_MIN_IO; - pp->res[0].end = pp->res[0].start + SZ_32K - 1; - } else { - pp->res[0].start = PCIBIOS_MIN_IO + SZ_32K; - pp->res[0].end = IO_SPACE_LIMIT; - } - pp->res[0].flags = IORESOURCE_IO; - if (request_resource(&ioport_resource, &pp->res[0])) { - pr_err("Request PCIe IO resource failed\n"); - /* return failure */ - return -EBUSY; - } - sys->resource[0] = &pp->res[0]; - - /* - * IORESOURCE_MEM - */ - snprintf(pp->mem_space_name, sizeof(pp->mem_space_name), - "PCIe %d MEM", pp->index); - pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0; - pp->res[1].name = pp->mem_space_name; - pp->res[1].start = MEM_BASE_0; - pp->res[1].end = pp->res[1].start + MEM_SIZE - 1; - pp->res[1].flags = IORESOURCE_MEM; - if (request_resource(&iomem_resource, &pp->res[1])) { - pr_err("Request PCIe Memory resource failed\n"); - /* return failure */ - return -EBUSY; - } - sys->resource[1] = &pp->res[1]; + sys->resource[0] = &pcie_io_space; + sys->resource[1] = &pcie_mem_space; + sys->resource[2] = &pcie_prefetch_mem_space; - /* - * IORESOURCE_MEM | IORESOURCE_PREFETCH - */ - snprintf(pp->prefetch_space_name, sizeof(pp->prefetch_space_name), - "PCIe %d PREFETCH MEM", pp->index); - pp->prefetch_space_name[sizeof(pp->prefetch_space_name) - 1] = 0; - pp->res[2].name = pp->prefetch_space_name; - pp->res[2].start = PREFETCH_MEM_BASE_0; - pp->res[2].end = pp->res[2].start + PREFETCH_MEM_SIZE - 1; - pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; - if (request_resource(&iomem_resource, &pp->res[2])) { - pr_err("Request PCIe Prefetch Memory resource failed\n"); - /* return failure */ - return -EBUSY; - } - sys->resource[2] = &pp->res[2]; return 1; } @@ -603,6 +582,7 @@ static struct pci_bus *tegra_pcie_scan_bus(int nr, static struct hw_pci tegra_pcie_hw = { .nr_controllers = MAX_PCIE_SUPPORTED_PORTS, + .preinit = tegra_pcie_preinit, .setup = tegra_pcie_setup, .scan = tegra_pcie_scan_bus, .swizzle = pci_std_swizzle, @@ -1057,7 +1037,6 @@ static int __init tegra_pcie_get_resources(void) goto err_map_reg; } res_mmio = &tegra_pcie.res_mmio; -#ifdef CONFIG_ARCH_TEGRA_2x_SOC err = request_resource(&iomem_resource, res_mmio); if (err) { pr_err("PCIE: Failed to request resources: %d\n", err); @@ -1071,7 +1050,7 @@ static int __init tegra_pcie_get_resources(void) err = -ENOMEM; goto err_map_io; } -#endif + err = request_irq(INT_PCIE_INTR, tegra_pcie_isr, IRQF_SHARED, "PCIE", &tegra_pcie); if (err) { @@ -1083,12 +1062,10 @@ static int __init tegra_pcie_get_resources(void) return 0; err_irq: -#ifdef CONFIG_ARCH_TEGRA_2x_SOC iounmap(tegra_pcie_io_base); err_map_io: release_resource(&tegra_pcie.res_mmio); err_req_io: -#endif iounmap(tegra_pcie.regs); err_map_reg: tegra_pcie_power_off(); |