mirror of
https://github.com/torvalds/linux.git
synced 2024-12-11 13:41:55 +00:00
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
|
config PCIE_DW_HOST
|
||||||
bool
|
bool
|
||||||
depends on PCI_MSI_IRQ_DOMAIN
|
|
||||||
select PCIE_DW
|
select PCIE_DW
|
||||||
|
|
||||||
config PCIE_DW_EP
|
config PCIE_DW_EP
|
||||||
bool
|
bool
|
||||||
depends on PCI_ENDPOINT
|
|
||||||
select PCIE_DW
|
select PCIE_DW
|
||||||
|
|
||||||
config PCI_DRA7XX
|
config PCI_DRA7XX
|
||||||
bool
|
tristate
|
||||||
|
|
||||||
config PCI_DRA7XX_HOST
|
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 SOC_DRA7XX || COMPILE_TEST
|
||||||
depends on PCI_MSI_IRQ_DOMAIN
|
|
||||||
depends on OF && HAS_IOMEM && TI_PIPE3
|
depends on OF && HAS_IOMEM && TI_PIPE3
|
||||||
|
depends on PCI_MSI_IRQ_DOMAIN
|
||||||
select PCIE_DW_HOST
|
select PCIE_DW_HOST
|
||||||
select PCI_DRA7XX
|
select PCI_DRA7XX
|
||||||
default y if SOC_DRA7XX
|
default y if SOC_DRA7XX
|
||||||
@ -36,10 +34,10 @@ config PCI_DRA7XX_HOST
|
|||||||
This uses the DesignWare core.
|
This uses the DesignWare core.
|
||||||
|
|
||||||
config PCI_DRA7XX_EP
|
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 SOC_DRA7XX || COMPILE_TEST
|
||||||
depends on PCI_ENDPOINT
|
|
||||||
depends on OF && HAS_IOMEM && TI_PIPE3
|
depends on OF && HAS_IOMEM && TI_PIPE3
|
||||||
|
depends on PCI_ENDPOINT
|
||||||
select PCIE_DW_EP
|
select PCIE_DW_EP
|
||||||
select PCI_DRA7XX
|
select PCI_DRA7XX
|
||||||
help
|
help
|
||||||
@ -55,7 +53,7 @@ config PCIE_DW_PLAT
|
|||||||
|
|
||||||
config PCIE_DW_PLAT_HOST
|
config PCIE_DW_PLAT_HOST
|
||||||
bool "Platform bus based DesignWare PCIe Controller - Host mode"
|
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_HOST
|
||||||
select PCIE_DW_PLAT
|
select PCIE_DW_PLAT
|
||||||
help
|
help
|
||||||
@ -138,8 +136,8 @@ config PCI_LAYERSCAPE
|
|||||||
bool "Freescale Layerscape PCIe controller - Host mode"
|
bool "Freescale Layerscape PCIe controller - Host mode"
|
||||||
depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
|
depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
|
||||||
depends on PCI_MSI_IRQ_DOMAIN
|
depends on PCI_MSI_IRQ_DOMAIN
|
||||||
select MFD_SYSCON
|
|
||||||
select PCIE_DW_HOST
|
select PCIE_DW_HOST
|
||||||
|
select MFD_SYSCON
|
||||||
help
|
help
|
||||||
Say Y here if you want to enable PCIe controller support on Layerscape
|
Say Y here if you want to enable PCIe controller support on Layerscape
|
||||||
SoCs to work in Host mode.
|
SoCs to work in Host mode.
|
||||||
@ -283,8 +281,8 @@ config PCIE_HISI_STB
|
|||||||
|
|
||||||
config PCI_MESON
|
config PCI_MESON
|
||||||
tristate "MESON PCIe controller"
|
tristate "MESON PCIe controller"
|
||||||
depends on PCI_MSI_IRQ_DOMAIN
|
|
||||||
default m if ARCH_MESON
|
default m if ARCH_MESON
|
||||||
|
depends on PCI_MSI_IRQ_DOMAIN
|
||||||
select PCIE_DW_HOST
|
select PCIE_DW_HOST
|
||||||
help
|
help
|
||||||
Say Y here if you want to enable PCI controller support on Amlogic
|
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>
|
* Authors: Kishon Vijay Abraham I <kishon@ti.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/clk.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
@ -14,7 +15,7 @@
|
|||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/irqdomain.h>
|
#include <linux/irqdomain.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/module.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/of_gpio.h>
|
#include <linux/of_gpio.h>
|
||||||
#include <linux/of_pci.h>
|
#include <linux/of_pci.h>
|
||||||
@ -90,6 +91,7 @@ struct dra7xx_pcie {
|
|||||||
int phy_count; /* DT phy-names count */
|
int phy_count; /* DT phy-names count */
|
||||||
struct phy **phy;
|
struct phy **phy;
|
||||||
struct irq_domain *irq_domain;
|
struct irq_domain *irq_domain;
|
||||||
|
struct clk *clk;
|
||||||
enum dw_pcie_device_mode mode;
|
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
|
* 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)
|
if (!link)
|
||||||
return -ENOMEM;
|
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++) {
|
for (i = 0; i < phy_count; i++) {
|
||||||
snprintf(name, sizeof(name), "pcie-phy%d", i);
|
snprintf(name, sizeof(name), "pcie-phy%d", i);
|
||||||
phy[i] = devm_phy_get(dev, name);
|
phy[i] = devm_phy_get(dev, name);
|
||||||
@ -925,6 +937,8 @@ static void dra7xx_pcie_shutdown(struct platform_device *pdev)
|
|||||||
|
|
||||||
pm_runtime_disable(dev);
|
pm_runtime_disable(dev);
|
||||||
dra7xx_pcie_disable_phy(dra7xx);
|
dra7xx_pcie_disable_phy(dra7xx);
|
||||||
|
|
||||||
|
clk_disable_unprepare(dra7xx->clk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct dev_pm_ops dra7xx_pcie_pm_ops = {
|
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,
|
.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++)
|
for (func_no = 0; func_no < funcs; func_no++)
|
||||||
__dw_pcie_ep_reset_bar(pci, func_no, bar, 0);
|
__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,
|
static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, u8 func_no,
|
||||||
u8 cap_ptr, u8 cap)
|
u8 cap_ptr, u8 cap)
|
||||||
|
@ -335,6 +335,16 @@ int dw_pcie_host_init(struct pcie_port *pp)
|
|||||||
if (pci->link_gen < 1)
|
if (pci->link_gen < 1)
|
||||||
pci->link_gen = of_pci_get_max_link_speed(np);
|
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()) {
|
if (pci_msi_enabled()) {
|
||||||
pp->has_msi_ctrl = !(pp->ops->msi_host_init ||
|
pp->has_msi_ctrl = !(pp->ops->msi_host_init ||
|
||||||
of_property_read_bool(np, "msi-parent") ||
|
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_iatu_detect(pci);
|
||||||
|
|
||||||
dw_pcie_setup_rc(pp);
|
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) &&
|
return ((val & PCIE_PORT_DEBUG1_LINK_UP) &&
|
||||||
(!(val & PCIE_PORT_DEBUG1_LINK_IN_TRAINING)));
|
(!(val & PCIE_PORT_DEBUG1_LINK_IN_TRAINING)));
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(dw_pcie_link_up);
|
||||||
|
|
||||||
void dw_pcie_upconfig_setup(struct dw_pcie *pci)
|
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);
|
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)
|
static void uniphier_pcie_irq_mask(struct irq_data *d)
|
||||||
{
|
{
|
||||||
struct pcie_port *pp = irq_data_get_irq_chip_data(d);
|
struct pcie_port *pp = irq_data_get_irq_chip_data(d);
|
||||||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||||
struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
|
struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
|
||||||
|
unsigned long flags;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
|
raw_spin_lock_irqsave(&pp->lock, flags);
|
||||||
|
|
||||||
val = readl(priv->base + PCL_RCV_INTX);
|
val = readl(priv->base + PCL_RCV_INTX);
|
||||||
val &= ~PCL_RCV_INTX_ALL_MASK;
|
|
||||||
val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
|
val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
|
||||||
writel(val, priv->base + PCL_RCV_INTX);
|
writel(val, priv->base + PCL_RCV_INTX);
|
||||||
|
|
||||||
|
raw_spin_unlock_irqrestore(&pp->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uniphier_pcie_irq_unmask(struct irq_data *d)
|
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 pcie_port *pp = irq_data_get_irq_chip_data(d);
|
||||||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||||
struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
|
struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
|
||||||
|
unsigned long flags;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
|
raw_spin_lock_irqsave(&pp->lock, flags);
|
||||||
|
|
||||||
val = readl(priv->base + PCL_RCV_INTX);
|
val = readl(priv->base + PCL_RCV_INTX);
|
||||||
val &= ~PCL_RCV_INTX_ALL_MASK;
|
|
||||||
val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
|
val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
|
||||||
writel(val, priv->base + PCL_RCV_INTX);
|
writel(val, priv->base + PCL_RCV_INTX);
|
||||||
|
|
||||||
|
raw_spin_unlock_irqrestore(&pp->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct irq_chip uniphier_pcie_irq_chip = {
|
static struct irq_chip uniphier_pcie_irq_chip = {
|
||||||
.name = "PCI",
|
.name = "PCI",
|
||||||
.irq_ack = uniphier_pcie_irq_ack,
|
|
||||||
.irq_mask = uniphier_pcie_irq_mask,
|
.irq_mask = uniphier_pcie_irq_mask,
|
||||||
.irq_unmask = uniphier_pcie_irq_unmask,
|
.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 dw_pcie *pci = &pcie->pci;
|
||||||
struct pcie_port *pp = &pci->pp;
|
struct pcie_port *pp = &pci->pp;
|
||||||
struct device *dev = &pdev->dev;
|
|
||||||
|
|
||||||
pp->irq = platform_get_irq_byname(pdev, "intr");
|
pp->irq = platform_get_irq_byname(pdev, "intr");
|
||||||
if (pp->irq < 0) {
|
if (pp->irq < 0)
|
||||||
dev_err(dev, "Interrupt intr is missing");
|
|
||||||
return pp->irq;
|
return pp->irq;
|
||||||
}
|
|
||||||
|
|
||||||
pp->ops = &visconti_pcie_host_ops;
|
pp->ops = &visconti_pcie_host_ops;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user