msm: pcie: mpq8064: Add system wakeup support to PCIe controller
Update the PCIe controller to register for wakeup interrupt enabling
the PCIe devices to wakeup the system if suspended.
Change-Id: I49960702c0abc1e1406dff622843456e0f0547c6
Signed-off-by: Niranjana Vishwanathapura <nvishwan@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 678eb9e..879434d 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -127,6 +127,7 @@
/* TABLA CODEC RESET */
PM8921_GPIO_OUTPUT(34, 1, MED),
PM8921_GPIO_OUTPUT(13, 0, HIGH), /* PCIE_CLK_PWR_EN */
+ PM8921_GPIO_INPUT(12, PM_GPIO_PULL_UP_30), /* PCIE_WAKE_N */
};
static struct pm8xxx_gpio_init pm8921_mtp_kp_gpios[] __initdata = {
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 6317685..90563ad 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -128,7 +128,8 @@
#define PCIE_AXI_BAR_PHYS 0x08000000
#define PCIE_AXI_BAR_SIZE SZ_128M
-/* PCIe power enable pmic gpio */
+/* PCIe pmic gpios */
+#define PCIE_WAKE_N_PMIC_GPIO 12
#define PCIE_PWR_EN_PMIC_GPIO 13
#define PCIE_RST_N_PMIC_MPP 1
@@ -2075,6 +2076,7 @@
.gpio = msm_pcie_gpio_info,
.axi_addr = PCIE_AXI_BAR_PHYS,
.axi_size = PCIE_AXI_BAR_SIZE,
+ .wake_n = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, PCIE_WAKE_N_PMIC_GPIO),
};
static int __init mpq8064_pcie_enabled(void)
diff --git a/arch/arm/mach-msm/include/mach/msm_pcie.h b/arch/arm/mach-msm/include/mach/msm_pcie.h
index 8bc4317..74f0f5b 100644
--- a/arch/arm/mach-msm/include/mach/msm_pcie.h
+++ b/arch/arm/mach-msm/include/mach/msm_pcie.h
@@ -22,7 +22,7 @@
MSM_PCIE_MAX_GPIO
};
-/* gpio info structrue */
+/* gpio info structure */
struct msm_pcie_gpio_info_t {
char *name;
uint32_t num;
@@ -32,8 +32,10 @@
/* msm pcie platfrom data */
struct msm_pcie_platform {
struct msm_pcie_gpio_info_t *gpio;
+
uint32_t axi_addr;
uint32_t axi_size;
+ uint32_t wake_n;
};
#endif
diff --git a/arch/arm/mach-msm/pcie.c b/arch/arm/mach-msm/pcie.c
index d954b53..709c8e8 100644
--- a/arch/arm/mach-msm/pcie.c
+++ b/arch/arm/mach-msm/pcie.c
@@ -619,6 +619,7 @@
msm_pcie_dev.pdev = pdev;
pdata = pdev->dev.platform_data;
msm_pcie_dev.gpio = pdata->gpio;
+ msm_pcie_dev.wake_n = pdata->wake_n;
msm_pcie_dev.vreg = msm_pcie_vreg_info;
msm_pcie_dev.clk = msm_pcie_clk_info;
msm_pcie_dev.res = msm_pcie_res_info;
@@ -706,6 +707,26 @@
DECLARE_PCI_FIXUP_EARLY(PCIE_VENDOR_ID_RCP, PCIE_DEVICE_ID_RCP,
msm_pcie_fixup_early);
+/* enable wake_n interrupt during suspend */
+static void msm_pcie_fixup_suspend(struct pci_dev *dev)
+{
+ PCIE_DBG("enabling wake_n\n");
+ if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+ enable_irq(msm_pcie_dev.wake_n);
+}
+DECLARE_PCI_FIXUP_SUSPEND(PCIE_VENDOR_ID_RCP, PCIE_DEVICE_ID_RCP,
+ msm_pcie_fixup_suspend);
+
+/* disable wake_n interrupt when system is not in suspend */
+static void msm_pcie_fixup_resume(struct pci_dev *dev)
+{
+ PCIE_DBG("disabling wake_n\n");
+ if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+ disable_irq(msm_pcie_dev.wake_n);
+}
+DECLARE_PCI_FIXUP_RESUME(PCIE_VENDOR_ID_RCP, PCIE_DEVICE_ID_RCP,
+ msm_pcie_fixup_resume);
+
/*
* actual physical (BAR) address of the device resources starts from
* MSM_PCIE_DEV_BAR_ADDR; the system axi address for the device resources starts
diff --git a/arch/arm/mach-msm/pcie.h b/arch/arm/mach-msm/pcie.h
index fba6b11..d7cce3e 100644
--- a/arch/arm/mach-msm/pcie.h
+++ b/arch/arm/mach-msm/pcie.h
@@ -68,6 +68,8 @@
uint32_t axi_bar_end;
struct resource dev_mem_res;
+
+ uint32_t wake_n;
};
extern uint32_t msm_pcie_irq_init(struct msm_pcie_dev_t *dev);
diff --git a/arch/arm/mach-msm/pcie_irq.c b/arch/arm/mach-msm/pcie_irq.c
index d915561..5a44a17 100644
--- a/arch/arm/mach-msm/pcie_irq.c
+++ b/arch/arm/mach-msm/pcie_irq.c
@@ -39,7 +39,13 @@
static DECLARE_BITMAP(msi_irq_in_use, NR_PCIE_MSI_IRQS);
-irqreturn_t handle_msi_irq(int irq, void *data)
+static irqreturn_t handle_wake_irq(int irq, void *data)
+{
+ PCIE_DBG("\n");
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t handle_msi_irq(int irq, void *data)
{
int i, j;
unsigned long val;
@@ -87,15 +93,32 @@
/* register handler for physical MSI interrupt line */
rc = request_irq(PCIE20_INT_MSI, handle_msi_irq, IRQF_TRIGGER_RISING,
"msm_pcie_msi", dev);
- if (rc)
+ if (rc) {
pr_err("Unable to allocate msi interrupt\n");
+ goto out;
+ }
+ /* register handler for PCIE_WAKE_N interrupt line */
+ rc = request_irq(dev->wake_n, handle_wake_irq, IRQF_TRIGGER_FALLING,
+ "msm_pcie_wake", dev);
+ if (rc) {
+ pr_err("Unable to allocate wake interrupt\n");
+ free_irq(PCIE20_INT_MSI, dev);
+ goto out;
+ }
+
+ enable_irq_wake(dev->wake_n);
+
+ /* PCIE_WAKE_N should be enabled only during system suspend */
+ disable_irq(dev->wake_n);
+out:
return rc;
}
void __exit msm_pcie_irq_deinit(struct msm_pcie_dev_t *dev)
{
free_irq(PCIE20_INT_MSI, dev);
+ free_irq(dev->wake_n, dev);
}
void msm_pcie_destroy_irq(unsigned int irq)