Merge branch 'pci/host/dwc'
- Export dw_pcie_ep_reset_bar(), dw_pcie_link_up() so more drivers can be modular (Luca Ceresoli) - Allow dra7xx host and endpoint drivers to be modules (Luca Ceresoli) - Enable dra7xx optional external clock if present (Luca Ceresoli) - Clean up Kconfig dependencies for PCIE_DW_HOST- and PCIE_DW_EP-based drivers (Andy Shevchenko) - Remove visconti redundant dev_err() after platform_get_irq_byname() failure (Krzysztof Wilczyński) - Run dwc .host_init() method before registering MSI interrupt handler so we have a chance to deal with pending interrupts left by bootloader (Bjorn Andersson) - Serialize uniphier INTx masking/unmasking (Kunihiko Hayashi) * pci/host/dwc: PCI: uniphier: Serialize INTx masking/unmasking and fix the bit operation PCI: dwc: Perform host_init() before registering msi PCI: visconti: Remove surplus dev_err() when using platform_get_irq_byname() PCI: dwc: Clean up Kconfig dependencies (PCIE_DW_EP) PCI: dwc: Clean up Kconfig dependencies (PCIE_DW_HOST) PCI: dra7xx: Get an optional clock PCI: dra7xx: Remove unused include PCI: dra7xx: Make it a kernel module PCI: dwc: Export more symbols to allow modular drivers
This commit is contained in:
commit
07dd8bbec1
|
@ -8,22 +8,20 @@ config PCIE_DW
|
|||
|
||||
config PCIE_DW_HOST
|
||||
bool
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIE_DW
|
||||
|
||||
config PCIE_DW_EP
|
||||
bool
|
||||
depends on PCI_ENDPOINT
|
||||
select PCIE_DW
|
||||
|
||||
config PCI_DRA7XX
|
||||
bool
|
||||
tristate
|
||||
|
||||
config PCI_DRA7XX_HOST
|
||||
bool "TI DRA7xx PCIe controller Host Mode"
|
||||
tristate "TI DRA7xx PCIe controller Host Mode"
|
||||
depends on SOC_DRA7XX || COMPILE_TEST
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
depends on OF && HAS_IOMEM && TI_PIPE3
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIE_DW_HOST
|
||||
select PCI_DRA7XX
|
||||
default y if SOC_DRA7XX
|
||||
|
@ -36,10 +34,10 @@ config PCI_DRA7XX_HOST
|
|||
This uses the DesignWare core.
|
||||
|
||||
config PCI_DRA7XX_EP
|
||||
bool "TI DRA7xx PCIe controller Endpoint Mode"
|
||||
tristate "TI DRA7xx PCIe controller Endpoint Mode"
|
||||
depends on SOC_DRA7XX || COMPILE_TEST
|
||||
depends on PCI_ENDPOINT
|
||||
depends on OF && HAS_IOMEM && TI_PIPE3
|
||||
depends on PCI_ENDPOINT
|
||||
select PCIE_DW_EP
|
||||
select PCI_DRA7XX
|
||||
help
|
||||
|
@ -55,7 +53,7 @@ config PCIE_DW_PLAT
|
|||
|
||||
config PCIE_DW_PLAT_HOST
|
||||
bool "Platform bus based DesignWare PCIe Controller - Host mode"
|
||||
depends on PCI && PCI_MSI_IRQ_DOMAIN
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIE_DW_HOST
|
||||
select PCIE_DW_PLAT
|
||||
help
|
||||
|
@ -138,8 +136,8 @@ config PCI_LAYERSCAPE
|
|||
bool "Freescale Layerscape PCIe controller - Host mode"
|
||||
depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select MFD_SYSCON
|
||||
select PCIE_DW_HOST
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Say Y here if you want to enable PCIe controller support on Layerscape
|
||||
SoCs to work in Host mode.
|
||||
|
@ -283,8 +281,8 @@ config PCIE_HISI_STB
|
|||
|
||||
config PCI_MESON
|
||||
tristate "MESON PCIe controller"
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
default m if ARCH_MESON
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIE_DW_HOST
|
||||
help
|
||||
Say Y here if you want to enable PCI controller support on Amlogic
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* Authors: Kishon Vijay Abraham I <kishon@ti.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
|
@ -14,7 +15,7 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_pci.h>
|
||||
|
@ -90,6 +91,7 @@ struct dra7xx_pcie {
|
|||
int phy_count; /* DT phy-names count */
|
||||
struct phy **phy;
|
||||
struct irq_domain *irq_domain;
|
||||
struct clk *clk;
|
||||
enum dw_pcie_device_mode mode;
|
||||
};
|
||||
|
||||
|
@ -607,6 +609,7 @@ static const struct of_device_id of_dra7xx_pcie_match[] = {
|
|||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_dra7xx_pcie_match);
|
||||
|
||||
/*
|
||||
* dra7xx_pcie_unaligned_memaccess: workaround for AM572x/AM571x Errata i870
|
||||
|
@ -740,6 +743,15 @@ static int dra7xx_pcie_probe(struct platform_device *pdev)
|
|||
if (!link)
|
||||
return -ENOMEM;
|
||||
|
||||
dra7xx->clk = devm_clk_get_optional(dev, NULL);
|
||||
if (IS_ERR(dra7xx->clk))
|
||||
return dev_err_probe(dev, PTR_ERR(dra7xx->clk),
|
||||
"clock request failed");
|
||||
|
||||
ret = clk_prepare_enable(dra7xx->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < phy_count; i++) {
|
||||
snprintf(name, sizeof(name), "pcie-phy%d", i);
|
||||
phy[i] = devm_phy_get(dev, name);
|
||||
|
@ -925,6 +937,8 @@ static void dra7xx_pcie_shutdown(struct platform_device *pdev)
|
|||
|
||||
pm_runtime_disable(dev);
|
||||
dra7xx_pcie_disable_phy(dra7xx);
|
||||
|
||||
clk_disable_unprepare(dra7xx->clk);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops dra7xx_pcie_pm_ops = {
|
||||
|
@ -943,4 +957,8 @@ static struct platform_driver dra7xx_pcie_driver = {
|
|||
},
|
||||
.shutdown = dra7xx_pcie_shutdown,
|
||||
};
|
||||
builtin_platform_driver(dra7xx_pcie_driver);
|
||||
module_platform_driver(dra7xx_pcie_driver);
|
||||
|
||||
MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
|
||||
MODULE_DESCRIPTION("PCIe controller driver for TI DRA7xx SoCs");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -83,6 +83,7 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
|
|||
for (func_no = 0; func_no < funcs; func_no++)
|
||||
__dw_pcie_ep_reset_bar(pci, func_no, bar, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dw_pcie_ep_reset_bar);
|
||||
|
||||
static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, u8 func_no,
|
||||
u8 cap_ptr, u8 cap)
|
||||
|
|
|
@ -335,6 +335,16 @@ int dw_pcie_host_init(struct pcie_port *pp)
|
|||
if (pci->link_gen < 1)
|
||||
pci->link_gen = of_pci_get_max_link_speed(np);
|
||||
|
||||
/* Set default bus ops */
|
||||
bridge->ops = &dw_pcie_ops;
|
||||
bridge->child_ops = &dw_child_pcie_ops;
|
||||
|
||||
if (pp->ops->host_init) {
|
||||
ret = pp->ops->host_init(pp);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pci_msi_enabled()) {
|
||||
pp->has_msi_ctrl = !(pp->ops->msi_host_init ||
|
||||
of_property_read_bool(np, "msi-parent") ||
|
||||
|
@ -388,15 +398,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
|
|||
}
|
||||
}
|
||||
|
||||
/* Set default bus ops */
|
||||
bridge->ops = &dw_pcie_ops;
|
||||
bridge->child_ops = &dw_child_pcie_ops;
|
||||
|
||||
if (pp->ops->host_init) {
|
||||
ret = pp->ops->host_init(pp);
|
||||
if (ret)
|
||||
goto err_free_msi;
|
||||
}
|
||||
dw_pcie_iatu_detect(pci);
|
||||
|
||||
dw_pcie_setup_rc(pp);
|
||||
|
|
|
@ -538,6 +538,7 @@ int dw_pcie_link_up(struct dw_pcie *pci)
|
|||
return ((val & PCIE_PORT_DEBUG1_LINK_UP) &&
|
||||
(!(val & PCIE_PORT_DEBUG1_LINK_IN_TRAINING)));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dw_pcie_link_up);
|
||||
|
||||
void dw_pcie_upconfig_setup(struct dw_pcie *pci)
|
||||
{
|
||||
|
|
|
@ -168,30 +168,21 @@ static void uniphier_pcie_irq_enable(struct uniphier_pcie_priv *priv)
|
|||
writel(PCL_RCV_INTX_ALL_ENABLE, priv->base + PCL_RCV_INTX);
|
||||
}
|
||||
|
||||
static void uniphier_pcie_irq_ack(struct irq_data *d)
|
||||
{
|
||||
struct pcie_port *pp = irq_data_get_irq_chip_data(d);
|
||||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||
struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
|
||||
u32 val;
|
||||
|
||||
val = readl(priv->base + PCL_RCV_INTX);
|
||||
val &= ~PCL_RCV_INTX_ALL_STATUS;
|
||||
val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT);
|
||||
writel(val, priv->base + PCL_RCV_INTX);
|
||||
}
|
||||
|
||||
static void uniphier_pcie_irq_mask(struct irq_data *d)
|
||||
{
|
||||
struct pcie_port *pp = irq_data_get_irq_chip_data(d);
|
||||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||
struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
raw_spin_lock_irqsave(&pp->lock, flags);
|
||||
|
||||
val = readl(priv->base + PCL_RCV_INTX);
|
||||
val &= ~PCL_RCV_INTX_ALL_MASK;
|
||||
val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
|
||||
writel(val, priv->base + PCL_RCV_INTX);
|
||||
|
||||
raw_spin_unlock_irqrestore(&pp->lock, flags);
|
||||
}
|
||||
|
||||
static void uniphier_pcie_irq_unmask(struct irq_data *d)
|
||||
|
@ -199,17 +190,20 @@ static void uniphier_pcie_irq_unmask(struct irq_data *d)
|
|||
struct pcie_port *pp = irq_data_get_irq_chip_data(d);
|
||||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||
struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
raw_spin_lock_irqsave(&pp->lock, flags);
|
||||
|
||||
val = readl(priv->base + PCL_RCV_INTX);
|
||||
val &= ~PCL_RCV_INTX_ALL_MASK;
|
||||
val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
|
||||
writel(val, priv->base + PCL_RCV_INTX);
|
||||
|
||||
raw_spin_unlock_irqrestore(&pp->lock, flags);
|
||||
}
|
||||
|
||||
static struct irq_chip uniphier_pcie_irq_chip = {
|
||||
.name = "PCI",
|
||||
.irq_ack = uniphier_pcie_irq_ack,
|
||||
.irq_mask = uniphier_pcie_irq_mask,
|
||||
.irq_unmask = uniphier_pcie_irq_unmask,
|
||||
};
|
||||
|
|
|
@ -279,13 +279,10 @@ static int visconti_add_pcie_port(struct visconti_pcie *pcie,
|
|||
{
|
||||
struct dw_pcie *pci = &pcie->pci;
|
||||
struct pcie_port *pp = &pci->pp;
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
pp->irq = platform_get_irq_byname(pdev, "intr");
|
||||
if (pp->irq < 0) {
|
||||
dev_err(dev, "Interrupt intr is missing");
|
||||
if (pp->irq < 0)
|
||||
return pp->irq;
|
||||
}
|
||||
|
||||
pp->ops = &visconti_pcie_host_ops;
|
||||
|
||||
|
|
Loading…
Reference in New Issue