aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2013-05-06 16:19:19 -0400
committerStephen Warren <swarren@nvidia.com>2013-08-13 14:07:56 -0400
commitb4f173752a56187bd55752b0474429202f2ab1d3 (patch)
tree64b5936abc2c238f5114b42915ba3958c32890af /drivers/pci
parent0447cfd75a6bad561ebf2b393dcb2263c261b6c5 (diff)
ARM: tegra: disable LP2 cpuidle state if PCIe is enabled
Tegra20 HW appears to have a bug such that PCIe device interrupts, whether they are legacy IRQs or MSI, are lost when LP2 is enabled. To work around this, simply disable LP2 if any PCIe devices with interrupts are present. Detect this via the IRQ domain map operation. This is slightly over-conservative; if a device with an interrupt is present but the driver does not actually use them, LP2 will still be disabled. However, this is a reasonable trade-off which enables a simpler workaround. Signed-off-by: Stephen Warren <swarren@nvidia.com> Tested-by: Thierry Reding <treding@nvidia.com> Acked-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/host/pci-tegra.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index ad95c406a6d0..7356741de36b 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -41,6 +41,7 @@
41#include <linux/platform_device.h> 41#include <linux/platform_device.h>
42#include <linux/sizes.h> 42#include <linux/sizes.h>
43#include <linux/slab.h> 43#include <linux/slab.h>
44#include <linux/tegra-cpuidle.h>
44#include <linux/tegra-powergate.h> 45#include <linux/tegra-powergate.h>
45#include <linux/vmalloc.h> 46#include <linux/vmalloc.h>
46#include <linux/regulator/consumer.h> 47#include <linux/regulator/consumer.h>
@@ -636,6 +637,8 @@ static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
636{ 637{
637 struct tegra_pcie *pcie = sys_to_pcie(pdev->bus->sysdata); 638 struct tegra_pcie *pcie = sys_to_pcie(pdev->bus->sysdata);
638 639
640 tegra_cpuidle_pcie_irqs_in_use();
641
639 return pcie->irq; 642 return pcie->irq;
640} 643}
641 644
@@ -1221,6 +1224,8 @@ static int tegra_msi_map(struct irq_domain *domain, unsigned int irq,
1221 irq_set_chip_data(irq, domain->host_data); 1224 irq_set_chip_data(irq, domain->host_data);
1222 set_irq_flags(irq, IRQF_VALID); 1225 set_irq_flags(irq, IRQF_VALID);
1223 1226
1227 tegra_cpuidle_pcie_irqs_in_use();
1228
1224 return 0; 1229 return 0;
1225} 1230}
1226 1231