Commit 1ad9a873 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Bjorn Helgaas

Merge branch 'lorenzo/pci/dwc-msi'

* lorenzo/pci/dwc-msi:
  PCI: dwc: Expand maximum number of MSI IRQs from 32 to 256
  PCI: dwc: Remove old MSI IRQs API
  PCI: dwc: Move MSI IRQs allocation to IRQ domains hierarchical API
parents f3c91098 1f319cb0
...@@ -294,15 +294,6 @@ static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg) ...@@ -294,15 +294,6 @@ static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static irqreturn_t exynos_pcie_msi_irq_handler(int irq, void *arg)
{
struct exynos_pcie *ep = arg;
struct dw_pcie *pci = ep->pci;
struct pcie_port *pp = &pci->pp;
return dw_handle_msi_irq(pp);
}
static void exynos_pcie_msi_init(struct exynos_pcie *ep) static void exynos_pcie_msi_init(struct exynos_pcie *ep)
{ {
struct dw_pcie *pci = ep->pci; struct dw_pcie *pci = ep->pci;
...@@ -428,15 +419,6 @@ static int __init exynos_add_pcie_port(struct exynos_pcie *ep, ...@@ -428,15 +419,6 @@ static int __init exynos_add_pcie_port(struct exynos_pcie *ep,
dev_err(dev, "failed to get msi irq\n"); dev_err(dev, "failed to get msi irq\n");
return pp->msi_irq; return pp->msi_irq;
} }
ret = devm_request_irq(dev, pp->msi_irq,
exynos_pcie_msi_irq_handler,
IRQF_SHARED | IRQF_NO_THREAD,
"exynos-pcie", ep);
if (ret) {
dev_err(dev, "failed to request msi irq\n");
return ret;
}
} }
pp->root_bus_nr = -1; pp->root_bus_nr = -1;
......
...@@ -542,15 +542,6 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie) ...@@ -542,15 +542,6 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
return -EINVAL; return -EINVAL;
} }
static irqreturn_t imx6_pcie_msi_handler(int irq, void *arg)
{
struct imx6_pcie *imx6_pcie = arg;
struct dw_pcie *pci = imx6_pcie->pci;
struct pcie_port *pp = &pci->pp;
return dw_handle_msi_irq(pp);
}
static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
{ {
struct dw_pcie *pci = imx6_pcie->pci; struct dw_pcie *pci = imx6_pcie->pci;
...@@ -674,15 +665,6 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie, ...@@ -674,15 +665,6 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
dev_err(dev, "failed to get MSI irq\n"); dev_err(dev, "failed to get MSI irq\n");
return -ENODEV; return -ENODEV;
} }
ret = devm_request_irq(dev, pp->msi_irq,
imx6_pcie_msi_handler,
IRQF_SHARED | IRQF_NO_THREAD,
"mx6-pcie-msi", imx6_pcie);
if (ret) {
dev_err(dev, "failed to request MSI irq\n");
return ret;
}
} }
pp->root_bus_nr = -1; pp->root_bus_nr = -1;
......
...@@ -120,20 +120,15 @@ void ks_dw_pcie_handle_msi_irq(struct keystone_pcie *ks_pcie, int offset) ...@@ -120,20 +120,15 @@ void ks_dw_pcie_handle_msi_irq(struct keystone_pcie *ks_pcie, int offset)
} }
} }
static void ks_dw_pcie_msi_irq_ack(struct irq_data *d) void ks_dw_pcie_msi_irq_ack(int irq, struct pcie_port *pp)
{ {
u32 offset, reg_offset, bit_pos; u32 reg_offset, bit_pos;
struct keystone_pcie *ks_pcie; struct keystone_pcie *ks_pcie;
struct msi_desc *msi;
struct pcie_port *pp;
struct dw_pcie *pci; struct dw_pcie *pci;
msi = irq_data_get_msi_desc(d);
pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
pci = to_dw_pcie_from_pp(pp); pci = to_dw_pcie_from_pp(pp);
ks_pcie = to_keystone_pcie(pci); ks_pcie = to_keystone_pcie(pci);
offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); update_reg_offset_bit_pos(irq, &reg_offset, &bit_pos);
update_reg_offset_bit_pos(offset, &reg_offset, &bit_pos);
ks_dw_app_writel(ks_pcie, MSI0_IRQ_STATUS + (reg_offset << 4), ks_dw_app_writel(ks_pcie, MSI0_IRQ_STATUS + (reg_offset << 4),
BIT(bit_pos)); BIT(bit_pos));
...@@ -162,85 +157,9 @@ void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) ...@@ -162,85 +157,9 @@ void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq)
BIT(bit_pos)); BIT(bit_pos));
} }
static void ks_dw_pcie_msi_irq_mask(struct irq_data *d) int ks_dw_pcie_msi_host_init(struct pcie_port *pp)
{
struct msi_desc *msi;
struct pcie_port *pp;
u32 offset;
msi = irq_data_get_msi_desc(d);
pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);
/* Mask the end point if PVM implemented */
if (IS_ENABLED(CONFIG_PCI_MSI)) {
if (msi->msi_attrib.maskbit)
pci_msi_mask_irq(d);
}
ks_dw_pcie_msi_clear_irq(pp, offset);
}
static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d)
{
struct msi_desc *msi;
struct pcie_port *pp;
u32 offset;
msi = irq_data_get_msi_desc(d);
pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);
/* Mask the end point if PVM implemented */
if (IS_ENABLED(CONFIG_PCI_MSI)) {
if (msi->msi_attrib.maskbit)
pci_msi_unmask_irq(d);
}
ks_dw_pcie_msi_set_irq(pp, offset);
}
static struct irq_chip ks_dw_pcie_msi_irq_chip = {
.name = "Keystone-PCIe-MSI-IRQ",
.irq_ack = ks_dw_pcie_msi_irq_ack,
.irq_mask = ks_dw_pcie_msi_irq_mask,
.irq_unmask = ks_dw_pcie_msi_irq_unmask,
};
static int ks_dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
irq_hw_number_t hwirq)
{ {
irq_set_chip_and_handler(irq, &ks_dw_pcie_msi_irq_chip, return dw_pcie_allocate_domains(pp);
handle_level_irq);
irq_set_chip_data(irq, domain->host_data);
return 0;
}
static const struct irq_domain_ops ks_dw_pcie_msi_domain_ops = {
.map = ks_dw_pcie_msi_map,
};
int ks_dw_pcie_msi_host_init(struct pcie_port *pp, struct msi_controller *chip)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct keystone_pcie *ks_pcie = to_keystone_pcie(pci);
struct device *dev = pci->dev;
int i;
pp->irq_domain = irq_domain_add_linear(ks_pcie->msi_intc_np,
MAX_MSI_IRQS,
&ks_dw_pcie_msi_domain_ops,
chip);
if (!pp->irq_domain) {
dev_err(dev, "irq domain init failed\n");
return -ENXIO;
}
for (i = 0; i < MAX_MSI_IRQS; i++)
irq_create_mapping(pp->irq_domain, i);
return 0;
} }
void ks_dw_pcie_enable_legacy_irqs(struct keystone_pcie *ks_pcie) void ks_dw_pcie_enable_legacy_irqs(struct keystone_pcie *ks_pcie)
......
...@@ -297,6 +297,7 @@ static const struct dw_pcie_host_ops keystone_pcie_host_ops = { ...@@ -297,6 +297,7 @@ static const struct dw_pcie_host_ops keystone_pcie_host_ops = {
.msi_clear_irq = ks_dw_pcie_msi_clear_irq, .msi_clear_irq = ks_dw_pcie_msi_clear_irq,
.get_msi_addr = ks_dw_pcie_get_msi_addr, .get_msi_addr = ks_dw_pcie_get_msi_addr,
.msi_host_init = ks_dw_pcie_msi_host_init, .msi_host_init = ks_dw_pcie_msi_host_init,
.msi_irq_ack = ks_dw_pcie_msi_irq_ack,
.scan_bus = ks_dw_pcie_v3_65_scan_bus, .scan_bus = ks_dw_pcie_v3_65_scan_bus,
}; };
......
...@@ -49,9 +49,9 @@ int ks_dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, ...@@ -49,9 +49,9 @@ int ks_dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
unsigned int devfn, int where, int size, u32 *val); unsigned int devfn, int where, int size, u32 *val);
void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie); void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie);
void ks_dw_pcie_initiate_link_train(struct keystone_pcie *ks_pcie); void ks_dw_pcie_initiate_link_train(struct keystone_pcie *ks_pcie);
void ks_dw_pcie_msi_irq_ack(int i, struct pcie_port *pp);
void ks_dw_pcie_msi_set_irq(struct pcie_port *pp, int irq); void ks_dw_pcie_msi_set_irq(struct pcie_port *pp, int irq);
void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq); void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq);
void ks_dw_pcie_v3_65_scan_bus(struct pcie_port *pp); void ks_dw_pcie_v3_65_scan_bus(struct pcie_port *pp);
int ks_dw_pcie_msi_host_init(struct pcie_port *pp, int ks_dw_pcie_msi_host_init(struct pcie_port *pp);
struct msi_controller *chip);
int ks_dw_pcie_link_up(struct dw_pcie *pci); int ks_dw_pcie_link_up(struct dw_pcie *pci);
...@@ -182,8 +182,7 @@ static int ls1021_pcie_host_init(struct pcie_port *pp) ...@@ -182,8 +182,7 @@ static int ls1021_pcie_host_init(struct pcie_port *pp)
return ls_pcie_host_init(pp); return ls_pcie_host_init(pp);
} }
static int ls_pcie_msi_host_init(struct pcie_port *pp, static int ls_pcie_msi_host_init(struct pcie_port *pp)
struct msi_controller *chip)
{ {
struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct device *dev = pci->dev; struct device *dev = pci->dev;
......
...@@ -383,15 +383,6 @@ static const struct dw_pcie_host_ops artpec6_pcie_host_ops = { ...@@ -383,15 +383,6 @@ static const struct dw_pcie_host_ops artpec6_pcie_host_ops = {
.host_init = artpec6_pcie_host_init, .host_init = artpec6_pcie_host_init,
}; };
static irqreturn_t artpec6_pcie_msi_handler(int irq, void *arg)
{
struct artpec6_pcie *artpec6_pcie = arg;
struct dw_pcie *pci = artpec6_pcie->pci;
struct pcie_port *pp = &pci->pp;
return dw_handle_msi_irq(pp);
}
static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie, static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie,
struct platform_device *pdev) struct platform_device *pdev)
{ {
...@@ -406,15 +397,6 @@ static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie, ...@@ -406,15 +397,6 @@ static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie,
dev_err(dev, "failed to get MSI irq\n"); dev_err(dev, "failed to get MSI irq\n");
return pp->msi_irq; return pp->msi_irq;
} }
ret = devm_request_irq(dev, pp->msi_irq,
artpec6_pcie_msi_handler,
IRQF_SHARED | IRQF_NO_THREAD,
"artpec6-pcie-msi", artpec6_pcie);
if (ret) {
dev_err(dev, "failed to request MSI irq\n");
return ret;
}
} }
pp->root_bus_nr = -1; pp->root_bus_nr = -1;
......
This diff is collapsed.
...@@ -25,13 +25,6 @@ struct dw_plat_pcie { ...@@ -25,13 +25,6 @@ struct dw_plat_pcie {
struct dw_pcie *pci; struct dw_pcie *pci;
}; };
static irqreturn_t dw_plat_pcie_msi_irq_handler(int irq, void *arg)
{
struct pcie_port *pp = arg;
return dw_handle_msi_irq(pp);
}
static int dw_plat_pcie_host_init(struct pcie_port *pp) static int dw_plat_pcie_host_init(struct pcie_port *pp)
{ {
struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
...@@ -63,15 +56,6 @@ static int dw_plat_add_pcie_port(struct pcie_port *pp, ...@@ -63,15 +56,6 @@ static int dw_plat_add_pcie_port(struct pcie_port *pp,
pp->msi_irq = platform_get_irq(pdev, 0); pp->msi_irq = platform_get_irq(pdev, 0);
if (pp->msi_irq < 0) if (pp->msi_irq < 0)
return pp->msi_irq; return pp->msi_irq;
ret = devm_request_irq(dev, pp->msi_irq,
dw_plat_pcie_msi_irq_handler,
IRQF_SHARED | IRQF_NO_THREAD,
"dw-plat-pcie-msi", pp);
if (ret) {
dev_err(dev, "failed to request MSI IRQ\n");
return ret;
}
} }
pp->root_bus_nr = -1; pp->root_bus_nr = -1;
......
...@@ -107,13 +107,10 @@ ...@@ -107,13 +107,10 @@
#define MSI_MESSAGE_DATA_32 0x58 #define MSI_MESSAGE_DATA_32 0x58
#define MSI_MESSAGE_DATA_64 0x5C #define MSI_MESSAGE_DATA_64 0x5C
/* #define MAX_MSI_IRQS 256
* Maximum number of MSI IRQs can be 256 per controller. But keep #define MAX_MSI_IRQS_PER_CTRL 32
* it 32 as of now. Probably we will never need more than 32. If needed, #define MAX_MSI_CTRLS (MAX_MSI_IRQS / MAX_MSI_IRQS_PER_CTRL)
* then increment it in multiple of 32. #define MSI_DEF_NUM_VECTORS 32
*/
#define MAX_MSI_IRQS 32
#define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32)
/* Maximum number of inbound/outbound iATUs */ /* Maximum number of inbound/outbound iATUs */
#define MAX_IATU_IN 256 #define MAX_IATU_IN 256
...@@ -149,7 +146,9 @@ struct dw_pcie_host_ops { ...@@ -149,7 +146,9 @@ struct dw_pcie_host_ops {
phys_addr_t (*get_msi_addr)(struct pcie_port *pp); phys_addr_t (*get_msi_addr)(struct pcie_port *pp);
u32 (*get_msi_data)(struct pcie_port *pp, int pos); u32 (*get_msi_data)(struct pcie_port *pp, int pos);
void (*scan_bus)(struct pcie_port *pp); void (*scan_bus)(struct pcie_port *pp);
int (*msi_host_init)(struct pcie_port *pp, struct msi_controller *chip); void (*set_num_vectors)(struct pcie_port *pp);
int (*msi_host_init)(struct pcie_port *pp);
void (*msi_irq_ack)(int irq, struct pcie_port *pp);
}; };
struct pcie_port { struct pcie_port {
...@@ -174,7 +173,11 @@ struct pcie_port { ...@@ -174,7 +173,11 @@ struct pcie_port {
const struct dw_pcie_host_ops *ops; const struct dw_pcie_host_ops *ops;
int msi_irq; int msi_irq;
struct irq_domain *irq_domain; struct irq_domain *irq_domain;
struct irq_domain *msi_domain;
dma_addr_t msi_data; dma_addr_t msi_data;
u32 num_vectors;
u32 irq_status[MAX_MSI_CTRLS];
raw_spinlock_t lock;
DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
}; };
...@@ -316,8 +319,10 @@ static inline void dw_pcie_dbi_ro_wr_dis(struct dw_pcie *pci) ...@@ -316,8 +319,10 @@ static inline void dw_pcie_dbi_ro_wr_dis(struct dw_pcie *pci)
#ifdef CONFIG_PCIE_DW_HOST #ifdef CONFIG_PCIE_DW_HOST
irqreturn_t dw_handle_msi_irq(struct pcie_port *pp); irqreturn_t dw_handle_msi_irq(struct pcie_port *pp);
void dw_pcie_msi_init(struct pcie_port *pp); void dw_pcie_msi_init(struct pcie_port *pp);
void dw_pcie_free_msi(struct pcie_port *pp);
void dw_pcie_setup_rc(struct pcie_port *pp); void dw_pcie_setup_rc(struct pcie_port *pp);
int dw_pcie_host_init(struct pcie_port *pp); int dw_pcie_host_init(struct pcie_port *pp);
int dw_pcie_allocate_domains(struct pcie_port *pp);
#else #else
static inline irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) static inline irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
{ {
...@@ -328,6 +333,10 @@ static inline void dw_pcie_msi_init(struct pcie_port *pp) ...@@ -328,6 +333,10 @@ static inline void dw_pcie_msi_init(struct pcie_port *pp)
{ {
} }
static inline void dw_pcie_free_msi(struct pcie_port *pp)
{
}
static inline void dw_pcie_setup_rc(struct pcie_port *pp) static inline void dw_pcie_setup_rc(struct pcie_port *pp)
{ {
} }
...@@ -336,6 +345,11 @@ static inline int dw_pcie_host_init(struct pcie_port *pp) ...@@ -336,6 +345,11 @@ static inline int dw_pcie_host_init(struct pcie_port *pp)
{ {
return 0; return 0;
} }
static inline int dw_pcie_allocate_domains(struct pcie_port *pp)
{
return 0;
}
#endif #endif
#ifdef CONFIG_PCIE_DW_EP #ifdef CONFIG_PCIE_DW_EP
......
...@@ -208,13 +208,6 @@ static struct dw_pcie_host_ops histb_pcie_host_ops = { ...@@ -208,13 +208,6 @@ static struct dw_pcie_host_ops histb_pcie_host_ops = {
.host_init = histb_pcie_host_init, .host_init = histb_pcie_host_init,
}; };
static irqreturn_t histb_pcie_msi_irq_handler(int irq, void *arg)
{
struct pcie_port *pp = arg;
return dw_handle_msi_irq(pp);
}
static void histb_pcie_host_disable(struct histb_pcie *hipcie) static void histb_pcie_host_disable(struct histb_pcie *hipcie)
{ {
reset_control_assert(hipcie->soft_reset); reset_control_assert(hipcie->soft_reset);
...@@ -413,14 +406,6 @@ static int histb_pcie_probe(struct platform_device *pdev) ...@@ -413,14 +406,6 @@ static int histb_pcie_probe(struct platform_device *pdev)
dev_err(dev, "Failed to get MSI IRQ\n"); dev_err(dev, "Failed to get MSI IRQ\n");
return pp->msi_irq; return pp->msi_irq;
} }
ret = devm_request_irq(dev, pp->msi_irq,
histb_pcie_msi_irq_handler,
IRQF_SHARED, "histb-pcie-msi", pp);
if (ret) {
dev_err(dev, "cannot request MSI IRQ\n");
return ret;
}
} }
hipcie->phy = devm_phy_get(dev, "phy"); hipcie->phy = devm_phy_get(dev, "phy");
......
...@@ -181,13 +181,6 @@ static void qcom_ep_reset_deassert(struct qcom_pcie *pcie) ...@@ -181,13 +181,6 @@ static void qcom_ep_reset_deassert(struct qcom_pcie *pcie)
usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500); usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500);
} }
static irqreturn_t qcom_pcie_msi_irq_handler(int irq, void *arg)
{
struct pcie_port *pp = arg;
return dw_handle_msi_irq(pp);
}
static int qcom_pcie_establish_link(struct qcom_pcie *pcie) static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
{ {
struct dw_pcie *pci = pcie->pci; struct dw_pcie *pci = pcie->pci;
...@@ -1261,15 +1254,6 @@ static int qcom_pcie_probe(struct platform_device *pdev) ...@@ -1261,15 +1254,6 @@ static int qcom_pcie_probe(struct platform_device *pdev)
pp->msi_irq = platform_get_irq_byname(pdev, "msi"); pp->msi_irq = platform_get_irq_byname(pdev, "msi");
if (pp->msi_irq < 0) if (pp->msi_irq < 0)
return pp->msi_irq; return pp->msi_irq;
ret = devm_request_irq(dev, pp->msi_irq,
qcom_pcie_msi_irq_handler,
IRQF_SHARED | IRQF_NO_THREAD,
"qcom-pcie-msi", pp);
if (ret) {
dev_err(dev, "cannot request msi irq\n");
return ret;
}
} }
ret = phy_init(pcie->phy); ret = phy_init(pcie->phy);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment