Commit fa00cb26 authored by Thomas Gleixner's avatar Thomas Gleixner

Merge tag 'irqchip-core-4.6' of git://git.infradead.org/users/jcooper/linux into irq/core

Pull irqchip core changes for v4.6 from Jason Cooper:

- mvebu (armada-370-xp)
   - MSI support
   - Deconflict with mvebu's arm64 code

- ts4800
   - Restrict when ts4800 driver can be built
   - Make ts4800_ic_ops static const

- bcm2836: Drop superfluous memory barrier
parents f944b5a7 e4e1c0ea
...@@ -3,7 +3,6 @@ menuconfig ARCH_MVEBU ...@@ -3,7 +3,6 @@ menuconfig ARCH_MVEBU
depends on ARCH_MULTI_V7 || ARCH_MULTI_V5 depends on ARCH_MULTI_V7 || ARCH_MULTI_V5
select ARCH_SUPPORTS_BIG_ENDIAN select ARCH_SUPPORTS_BIG_ENDIAN
select CLKSRC_MMIO select CLKSRC_MMIO
select GENERIC_IRQ_CHIP
select PINCTRL select PINCTRL
select PLAT_ORION select PLAT_ORION
select SOC_BUS select SOC_BUS
...@@ -29,6 +28,7 @@ config MACH_ARMADA_370 ...@@ -29,6 +28,7 @@ config MACH_ARMADA_370
bool "Marvell Armada 370 boards" bool "Marvell Armada 370 boards"
depends on ARCH_MULTI_V7 depends on ARCH_MULTI_V7
select ARMADA_370_CLK select ARMADA_370_CLK
select ARMADA_370_XP_IRQ
select CPU_PJ4B select CPU_PJ4B
select MACH_MVEBU_V7 select MACH_MVEBU_V7
select PINCTRL_ARMADA_370 select PINCTRL_ARMADA_370
...@@ -39,6 +39,7 @@ config MACH_ARMADA_370 ...@@ -39,6 +39,7 @@ config MACH_ARMADA_370
config MACH_ARMADA_375 config MACH_ARMADA_375
bool "Marvell Armada 375 boards" bool "Marvell Armada 375 boards"
depends on ARCH_MULTI_V7 depends on ARCH_MULTI_V7
select ARMADA_370_XP_IRQ
select ARM_ERRATA_720789 select ARM_ERRATA_720789
select ARM_ERRATA_753970 select ARM_ERRATA_753970
select ARM_GIC select ARM_GIC
...@@ -58,6 +59,7 @@ config MACH_ARMADA_38X ...@@ -58,6 +59,7 @@ config MACH_ARMADA_38X
select ARM_ERRATA_720789 select ARM_ERRATA_720789
select ARM_ERRATA_753970 select ARM_ERRATA_753970
select ARM_GIC select ARM_GIC
select ARMADA_370_XP_IRQ
select ARMADA_38X_CLK select ARMADA_38X_CLK
select HAVE_ARM_SCU select HAVE_ARM_SCU
select HAVE_ARM_TWD if SMP select HAVE_ARM_TWD if SMP
...@@ -72,6 +74,7 @@ config MACH_ARMADA_39X ...@@ -72,6 +74,7 @@ config MACH_ARMADA_39X
bool "Marvell Armada 39x boards" bool "Marvell Armada 39x boards"
depends on ARCH_MULTI_V7 depends on ARCH_MULTI_V7
select ARM_GIC select ARM_GIC
select ARMADA_370_XP_IRQ
select ARMADA_39X_CLK select ARMADA_39X_CLK
select CACHE_L2X0 select CACHE_L2X0
select HAVE_ARM_SCU select HAVE_ARM_SCU
...@@ -86,6 +89,7 @@ config MACH_ARMADA_39X ...@@ -86,6 +89,7 @@ config MACH_ARMADA_39X
config MACH_ARMADA_XP config MACH_ARMADA_XP
bool "Marvell Armada XP boards" bool "Marvell Armada XP boards"
depends on ARCH_MULTI_V7 depends on ARCH_MULTI_V7
select ARMADA_370_XP_IRQ
select ARMADA_XP_CLK select ARMADA_XP_CLK
select CPU_PJ4B select CPU_PJ4B
select MACH_MVEBU_V7 select MACH_MVEBU_V7
......
...@@ -60,6 +60,11 @@ config ARM_VIC_NR ...@@ -60,6 +60,11 @@ config ARM_VIC_NR
The maximum number of VICs available in the system, for The maximum number of VICs available in the system, for
power management. power management.
config ARMADA_370_XP_IRQ
bool
select GENERIC_IRQ_CHIP
select PCI_MSI_IRQ_DOMAIN if PCI_MSI
config ATMEL_AIC_IRQ config ATMEL_AIC_IRQ
bool bool
select GENERIC_IRQ_CHIP select GENERIC_IRQ_CHIP
...@@ -165,6 +170,7 @@ config TS4800_IRQ ...@@ -165,6 +170,7 @@ config TS4800_IRQ
tristate "TS-4800 IRQ controller" tristate "TS-4800 IRQ controller"
select IRQ_DOMAIN select IRQ_DOMAIN
depends on HAS_IOMEM depends on HAS_IOMEM
depends on SOC_IMX51 || COMPILE_TEST
help help
Support for the TS-4800 FPGA IRQ controller Support for the TS-4800 FPGA IRQ controller
......
...@@ -5,7 +5,6 @@ obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o ...@@ -5,7 +5,6 @@ obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o
obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o
obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o
obj-$(CONFIG_ARCH_MMP) += irq-mmp.o obj-$(CONFIG_ARCH_MMP) += irq-mmp.o
obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o
obj-$(CONFIG_IRQ_MXS) += irq-mxs.o obj-$(CONFIG_IRQ_MXS) += irq-mxs.o
obj-$(CONFIG_ARCH_TEGRA) += irq-tegra.o obj-$(CONFIG_ARCH_TEGRA) += irq-tegra.o
obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o
...@@ -28,6 +27,7 @@ obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-g ...@@ -28,6 +27,7 @@ obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-g
obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o
obj-$(CONFIG_ARM_NVIC) += irq-nvic.o obj-$(CONFIG_ARM_NVIC) += irq-nvic.o
obj-$(CONFIG_ARM_VIC) += irq-vic.o obj-$(CONFIG_ARM_VIC) += irq-vic.o
obj-$(CONFIG_ARMADA_370_XP_IRQ) += irq-armada-370-xp.o
obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o
obj-$(CONFIG_ATMEL_AIC5_IRQ) += irq-atmel-aic-common.o irq-atmel-aic5.o obj-$(CONFIG_ATMEL_AIC5_IRQ) += irq-atmel-aic-common.o irq-atmel-aic5.o
obj-$(CONFIG_I8259) += irq-i8259.o obj-$(CONFIG_I8259) += irq-i8259.o
......
...@@ -71,6 +71,7 @@ static u32 doorbell_mask_reg; ...@@ -71,6 +71,7 @@ static u32 doorbell_mask_reg;
static int parent_irq; static int parent_irq;
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
static struct irq_domain *armada_370_xp_msi_domain; static struct irq_domain *armada_370_xp_msi_domain;
static struct irq_domain *armada_370_xp_msi_inner_domain;
static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR); static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR);
static DEFINE_MUTEX(msi_used_lock); static DEFINE_MUTEX(msi_used_lock);
static phys_addr_t msi_doorbell_addr; static phys_addr_t msi_doorbell_addr;
...@@ -115,127 +116,102 @@ static void armada_370_xp_irq_unmask(struct irq_data *d) ...@@ -115,127 +116,102 @@ static void armada_370_xp_irq_unmask(struct irq_data *d)
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
static int armada_370_xp_alloc_msi(void) static struct irq_chip armada_370_xp_msi_irq_chip = {
{ .name = "MPIC MSI",
int hwirq; .irq_mask = pci_msi_mask_irq,
.irq_unmask = pci_msi_unmask_irq,
};
mutex_lock(&msi_used_lock); static struct msi_domain_info armada_370_xp_msi_domain_info = {
hwirq = find_first_zero_bit(&msi_used, PCI_MSI_DOORBELL_NR); .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
if (hwirq >= PCI_MSI_DOORBELL_NR) MSI_FLAG_MULTI_PCI_MSI),
hwirq = -ENOSPC; .chip = &armada_370_xp_msi_irq_chip,
else };
set_bit(hwirq, msi_used);
mutex_unlock(&msi_used_lock);
return hwirq; static void armada_370_xp_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
{
msg->address_lo = lower_32_bits(msi_doorbell_addr);
msg->address_hi = upper_32_bits(msi_doorbell_addr);
msg->data = 0xf00 | (data->hwirq + PCI_MSI_DOORBELL_START);
} }
static void armada_370_xp_free_msi(int hwirq) static int armada_370_xp_msi_set_affinity(struct irq_data *irq_data,
const struct cpumask *mask, bool force)
{ {
mutex_lock(&msi_used_lock); return -EINVAL;
if (!test_bit(hwirq, msi_used))
pr_err("trying to free unused MSI#%d\n", hwirq);
else
clear_bit(hwirq, msi_used);
mutex_unlock(&msi_used_lock);
} }
static int armada_370_xp_setup_msi_irq(struct msi_controller *chip, static struct irq_chip armada_370_xp_msi_bottom_irq_chip = {
struct pci_dev *pdev, .name = "MPIC MSI",
struct msi_desc *desc) .irq_compose_msi_msg = armada_370_xp_compose_msi_msg,
{ .irq_set_affinity = armada_370_xp_msi_set_affinity,
struct msi_msg msg; };
int virq, hwirq;
/* We support MSI, but not MSI-X */ static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq,
if (desc->msi_attrib.is_msix) unsigned int nr_irqs, void *args)
return -EINVAL; {
int hwirq, i;
hwirq = armada_370_xp_alloc_msi(); mutex_lock(&msi_used_lock);
if (hwirq < 0)
return hwirq;
virq = irq_create_mapping(armada_370_xp_msi_domain, hwirq); hwirq = bitmap_find_next_zero_area(msi_used, PCI_MSI_DOORBELL_NR,
if (!virq) { 0, nr_irqs, 0);
armada_370_xp_free_msi(hwirq); if (hwirq >= PCI_MSI_DOORBELL_NR) {
return -EINVAL; mutex_unlock(&msi_used_lock);
return -ENOSPC;
} }
irq_set_msi_desc(virq, desc); bitmap_set(msi_used, hwirq, nr_irqs);
mutex_unlock(&msi_used_lock);
msg.address_lo = msi_doorbell_addr;
msg.address_hi = 0;
msg.data = 0xf00 | (hwirq + 16);
pci_write_msi_msg(virq, &msg);
return 0;
}
static void armada_370_xp_teardown_msi_irq(struct msi_controller *chip, for (i = 0; i < nr_irqs; i++) {
unsigned int irq) irq_domain_set_info(domain, virq + i, hwirq + i,
{ &armada_370_xp_msi_bottom_irq_chip,
struct irq_data *d = irq_get_irq_data(irq); domain->host_data, handle_simple_irq,
unsigned long hwirq = d->hwirq; NULL, NULL);
}
irq_dispose_mapping(irq); return hwirq;
armada_370_xp_free_msi(hwirq);
} }
static struct irq_chip armada_370_xp_msi_irq_chip = { static void armada_370_xp_msi_free(struct irq_domain *domain,
.name = "armada_370_xp_msi_irq", unsigned int virq, unsigned int nr_irqs)
.irq_enable = pci_msi_unmask_irq,
.irq_disable = pci_msi_mask_irq,
.irq_mask = pci_msi_mask_irq,
.irq_unmask = pci_msi_unmask_irq,
};
static int armada_370_xp_msi_map(struct irq_domain *domain, unsigned int virq,
irq_hw_number_t hw)
{ {
irq_set_chip_and_handler(virq, &armada_370_xp_msi_irq_chip, struct irq_data *d = irq_domain_get_irq_data(domain, virq);
handle_simple_irq);
return 0; mutex_lock(&msi_used_lock);
bitmap_clear(msi_used, d->hwirq, nr_irqs);
mutex_unlock(&msi_used_lock);
} }
static const struct irq_domain_ops armada_370_xp_msi_irq_ops = { static const struct irq_domain_ops armada_370_xp_msi_domain_ops = {
.map = armada_370_xp_msi_map, .alloc = armada_370_xp_msi_alloc,
.free = armada_370_xp_msi_free,
}; };
static int armada_370_xp_msi_init(struct device_node *node, static int armada_370_xp_msi_init(struct device_node *node,
phys_addr_t main_int_phys_base) phys_addr_t main_int_phys_base)
{ {
struct msi_controller *msi_chip;
u32 reg; u32 reg;
int ret;
msi_doorbell_addr = main_int_phys_base + msi_doorbell_addr = main_int_phys_base +
ARMADA_370_XP_SW_TRIG_INT_OFFS; ARMADA_370_XP_SW_TRIG_INT_OFFS;
msi_chip = kzalloc(sizeof(*msi_chip), GFP_KERNEL); armada_370_xp_msi_inner_domain =
if (!msi_chip) irq_domain_add_linear(NULL, PCI_MSI_DOORBELL_NR,
&armada_370_xp_msi_domain_ops, NULL);
if (!armada_370_xp_msi_inner_domain)
return -ENOMEM; return -ENOMEM;
msi_chip->setup_irq = armada_370_xp_setup_msi_irq;
msi_chip->teardown_irq = armada_370_xp_teardown_msi_irq;
msi_chip->of_node = node;
armada_370_xp_msi_domain = armada_370_xp_msi_domain =
irq_domain_add_linear(NULL, PCI_MSI_DOORBELL_NR, pci_msi_create_irq_domain(of_node_to_fwnode(node),
&armada_370_xp_msi_irq_ops, &armada_370_xp_msi_domain_info,
NULL); armada_370_xp_msi_inner_domain);
if (!armada_370_xp_msi_domain) { if (!armada_370_xp_msi_domain) {
kfree(msi_chip); irq_domain_remove(armada_370_xp_msi_inner_domain);
return -ENOMEM; return -ENOMEM;
} }
ret = of_pci_msi_chip_add(msi_chip);
if (ret < 0) {
irq_domain_remove(armada_370_xp_msi_domain);
kfree(msi_chip);
return ret;
}
reg = readl(per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS) reg = readl(per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS)
| PCI_MSI_DOORBELL_MASK; | PCI_MSI_DOORBELL_MASK;
...@@ -280,7 +256,7 @@ static int armada_xp_set_affinity(struct irq_data *d, ...@@ -280,7 +256,7 @@ static int armada_xp_set_affinity(struct irq_data *d,
#endif #endif
static struct irq_chip armada_370_xp_irq_chip = { static struct irq_chip armada_370_xp_irq_chip = {
.name = "armada_370_xp_irq", .name = "MPIC",
.irq_mask = armada_370_xp_irq_mask, .irq_mask = armada_370_xp_irq_mask,
.irq_mask_ack = armada_370_xp_irq_mask, .irq_mask_ack = armada_370_xp_irq_mask,
.irq_unmask = armada_370_xp_irq_unmask, .irq_unmask = armada_370_xp_irq_unmask,
...@@ -427,12 +403,12 @@ static void armada_370_xp_handle_msi_irq(struct pt_regs *regs, bool is_chained) ...@@ -427,12 +403,12 @@ static void armada_370_xp_handle_msi_irq(struct pt_regs *regs, bool is_chained)
continue; continue;
if (is_chained) { if (is_chained) {
irq = irq_find_mapping(armada_370_xp_msi_domain, irq = irq_find_mapping(armada_370_xp_msi_inner_domain,
msinr - 16); msinr - PCI_MSI_DOORBELL_START);
generic_handle_irq(irq); generic_handle_irq(irq);
} else { } else {
irq = msinr - 16; irq = msinr - PCI_MSI_DOORBELL_START;
handle_domain_irq(armada_370_xp_msi_domain, handle_domain_irq(armada_370_xp_msi_inner_domain,
irq, regs); irq, regs);
} }
} }
...@@ -604,8 +580,8 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, ...@@ -604,8 +580,8 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
armada_370_xp_mpic_domain = armada_370_xp_mpic_domain =
irq_domain_add_linear(node, nr_irqs, irq_domain_add_linear(node, nr_irqs,
&armada_370_xp_mpic_irq_ops, NULL); &armada_370_xp_mpic_irq_ops, NULL);
BUG_ON(!armada_370_xp_mpic_domain); BUG_ON(!armada_370_xp_mpic_domain);
armada_370_xp_mpic_domain->bus_token = DOMAIN_BUS_WIRED;
/* Setup for the boot CPU */ /* Setup for the boot CPU */
armada_xp_mpic_perf_init(); armada_xp_mpic_perf_init();
......
...@@ -229,7 +229,6 @@ int __init bcm2836_smp_boot_secondary(unsigned int cpu, ...@@ -229,7 +229,6 @@ int __init bcm2836_smp_boot_secondary(unsigned int cpu,
unsigned long secondary_startup_phys = unsigned long secondary_startup_phys =
(unsigned long)virt_to_phys((void *)secondary_startup); (unsigned long)virt_to_phys((void *)secondary_startup);
dsb();
writel(secondary_startup_phys, writel(secondary_startup_phys,
intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu); intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu);
......
...@@ -59,7 +59,7 @@ static int ts4800_irqdomain_map(struct irq_domain *d, unsigned int irq, ...@@ -59,7 +59,7 @@ static int ts4800_irqdomain_map(struct irq_domain *d, unsigned int irq,
return 0; return 0;
} }
struct irq_domain_ops ts4800_ic_ops = { static const struct irq_domain_ops ts4800_ic_ops = {
.map = ts4800_irqdomain_map, .map = ts4800_irqdomain_map,
.xlate = irq_domain_xlate_onecell, .xlate = irq_domain_xlate_onecell,
}; };
......
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