PCI: exynos: Add support for MSI

This patch adds support for Message Signaled Interrupt in the
Exynos PCIe driver using Synopsys designware PCIe core IP.

Signed-off-by: Siva Reddy Kallam <siva.kallam@samsung.com>
Signed-off-by: Srikanth T Shivanand <ts.srikanth@samsung.com>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Pratyush Anand <pratyush.anand@st.com>
Cc: Mohit KUMAR <Mohit.KUMAR@st.com>
This commit is contained in:
Jingoo Han
2013-09-06 15:54:59 +09:00
committed by Bjorn Helgaas
parent 4af8225567
commit f342d940ee
3 changed files with 298 additions and 0 deletions

View File

@@ -48,6 +48,7 @@ struct exynos_pcie {
#define PCIE_IRQ_SPECIAL 0x008
#define PCIE_IRQ_EN_PULSE 0x00c
#define PCIE_IRQ_EN_LEVEL 0x010
#define IRQ_MSI_ENABLE (0x1 << 2)
#define PCIE_IRQ_EN_SPECIAL 0x014
#define PCIE_PWR_RESET 0x018
#define PCIE_CORE_RESET 0x01c
@@ -342,9 +343,36 @@ static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)
return IRQ_HANDLED;
}
static irqreturn_t exynos_pcie_msi_irq_handler(int irq, void *arg)
{
struct pcie_port *pp = arg;
dw_handle_msi_irq(pp);
return IRQ_HANDLED;
}
static void exynos_pcie_msi_init(struct pcie_port *pp)
{
u32 val;
struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
dw_pcie_msi_init(pp);
/* enable MSI interrupt */
val = exynos_elb_readl(exynos_pcie, PCIE_IRQ_EN_LEVEL);
val |= IRQ_MSI_ENABLE;
exynos_elb_writel(exynos_pcie, val, PCIE_IRQ_EN_LEVEL);
return;
}
static void exynos_pcie_enable_interrupts(struct pcie_port *pp)
{
exynos_pcie_enable_irq_pulse(pp);
if (IS_ENABLED(CONFIG_PCI_MSI))
exynos_pcie_msi_init(pp);
return;
}
@@ -430,6 +458,22 @@ static int add_pcie_port(struct pcie_port *pp, struct platform_device *pdev)
return ret;
}
if (IS_ENABLED(CONFIG_PCI_MSI)) {
pp->msi_irq = platform_get_irq(pdev, 0);
if (!pp->msi_irq) {
dev_err(&pdev->dev, "failed to get msi irq\n");
return -ENODEV;
}
ret = devm_request_irq(&pdev->dev, pp->msi_irq,
exynos_pcie_msi_irq_handler,
IRQF_SHARED, "exynos-pcie", pp);
if (ret) {
dev_err(&pdev->dev, "failed to request msi irq\n");
return ret;
}
}
pp->root_bus_nr = -1;
pp->ops = &exynos_pcie_host_ops;