Re: [GIT PULL] IRQ fixes
The pull request you sent on Mon, 3 Aug 2020 12:54:19 +0200: > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git > irq-urgent-2020-08-02 has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/3b4b84b2ea9938e44fffa356c7b95f496b4246ab Thank you! -- Deet-doot-dot, I am a bot. https://korg.wiki.kernel.org/userdoc/prtracker
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq/urgent fixes left over from the v5.8 cycle from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-2020-08-02 # HEAD: aa251fc5b936d3ddb4b4c4b36427eb9aa3347c82 genirq/debugfs: Add missing irqchip flags Fix a recent IRQ affinities regression, add in a missing debugfs printout that helps the debugging of IRQ affinity logic bugs, and fix a memory leak. Thanks, Ingo --> Jon Derrick (1): irqdomain/treewide: Free firmware node after domain removal Marc Zyngier (1): genirq/debugfs: Add missing irqchip flags Thomas Gleixner (1): genirq/affinity: Make affinity setting if activated opt-in arch/mips/pci/pci-xtalk-bridge.c| 3 +++ arch/x86/kernel/apic/io_apic.c | 5 + arch/x86/kernel/apic/vector.c | 4 drivers/iommu/intel/irq_remapping.c | 8 drivers/irqchip/irq-gic-v3-its.c| 5 - drivers/mfd/ioc3.c | 6 ++ drivers/pci/controller/vmd.c| 3 +++ include/linux/irq.h | 13 + kernel/irq/debugfs.c| 5 + kernel/irq/manage.c | 6 +- 10 files changed, 56 insertions(+), 2 deletions(-) diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c index 5958217861b8..9b3cc775c55e 100644 --- a/arch/mips/pci/pci-xtalk-bridge.c +++ b/arch/mips/pci/pci-xtalk-bridge.c @@ -728,6 +728,7 @@ static int bridge_probe(struct platform_device *pdev) pci_free_resource_list(>windows); err_remove_domain: irq_domain_remove(domain); + irq_domain_free_fwnode(fn); return err; } @@ -735,8 +736,10 @@ static int bridge_remove(struct platform_device *pdev) { struct pci_bus *bus = platform_get_drvdata(pdev); struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); + struct fwnode_handle *fn = bc->domain->fwnode; irq_domain_remove(bc->domain); + irq_domain_free_fwnode(fn); pci_lock_rescan_remove(); pci_stop_root_bus(bus); pci_remove_root_bus(bus); diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 81ffcfbfaef2..21325a4a78b9 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2335,8 +2335,13 @@ static int mp_irqdomain_create(int ioapic) static void ioapic_destroy_irqdomain(int idx) { + struct ioapic_domain_cfg *cfg = [idx].irqdomain_cfg; + struct fwnode_handle *fn = ioapics[idx].irqdomain->fwnode; + if (ioapics[idx].irqdomain) { irq_domain_remove(ioapics[idx].irqdomain); + if (!cfg->dev) + irq_domain_free_fwnode(fn); ioapics[idx].irqdomain = NULL; } } diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index 7649da2478d8..dae32d948bf2 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c @@ -560,6 +560,10 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq, * as that can corrupt the affinity move state. */ irqd_set_handle_enforce_irqctx(irqd); + + /* Don't invoke affinity setter on deactivated interrupts */ + irqd_set_affinity_on_activate(irqd); + /* * Legacy vectors are already assigned when the IOAPIC * takes them over. They stay on the same vector. This is diff --git a/drivers/iommu/intel/irq_remapping.c b/drivers/iommu/intel/irq_remapping.c index 9564d23d094f..aa096b333a99 100644 --- a/drivers/iommu/intel/irq_remapping.c +++ b/drivers/iommu/intel/irq_remapping.c @@ -628,13 +628,21 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu) static void intel_teardown_irq_remapping(struct intel_iommu *iommu) { + struct fwnode_handle *fn; + if (iommu && iommu->ir_table) { if (iommu->ir_msi_domain) { + fn = iommu->ir_msi_domain->fwnode; + irq_domain_remove(iommu->ir_msi_domain); + irq_domain_free_fwnode(fn); iommu->ir_msi_domain = NULL; } if (iommu->ir_domain) { + fn = iommu->ir_domain->fwnode; + irq_domain_remove(iommu->ir_domain); + irq_domain_free_fwnode(fn); iommu->ir_domain = NULL; } free_pages((unsigned long)iommu->ir_table->base, diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index beac4caefad9..103d850b5595 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -3523,6 +3523,7 @@ static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, msi_alloc_info_t *info = args; struct its_device *its_dev = info->scratchpad[0].ptr;
Re: [GIT PULL] IRQ fixes
The pull request you sent on Sat, 29 Jun 2019 10:50:33 +0200: > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/eed7d30e126dc5b883b77f3e26bbca6c5b0f4222 Thank you! -- Deet-doot-dot, I am a bot. https://korg.wiki.kernel.org/userdoc/prtracker
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: a52548dd0491a544558e971cd5963501e1a2024d Merge tag 'irqchip-5.2-2' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent Diverse irqchip driver fixes. Thanks, Ingo --> Guo Ren (1): irqchip/irq-csky-mpintc: Support auto irq deliver to all cpus Heyi Guo (1): irqchip/gic-v3-its: Fix command queue pointer comparison bug Paul Burton (1): irqchip/mips-gic: Use the correct local interrupt map registers Peter Ujfalusi (1): irqchip/ti-sci-inta: Fix kernel crash if irq_create_fwspec_mapping fail arch/mips/include/asm/mips-gic.h | 30 ++ drivers/irqchip/irq-csky-mpintc.c | 15 +-- drivers/irqchip/irq-gic-v3-its.c | 35 --- drivers/irqchip/irq-mips-gic.c| 4 ++-- drivers/irqchip/irq-ti-sci-inta.c | 4 ++-- 5 files changed, 71 insertions(+), 17 deletions(-) diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h index 558059a8f218..0277b56157af 100644 --- a/arch/mips/include/asm/mips-gic.h +++ b/arch/mips/include/asm/mips-gic.h @@ -314,6 +314,36 @@ static inline bool mips_gic_present(void) return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base; } +/** + * mips_gic_vx_map_reg() - Return GIC_Vx__MAP register offset + * @intr: A GIC local interrupt + * + * Determine the index of the GIC_VL__MAP or GIC_VO__MAP register + * within the block of GIC map registers. This is almost the same as the order + * of interrupts in the pending & mask registers, as used by enum + * mips_gic_local_interrupt, but moves the FDC interrupt & thus offsets the + * interrupts after it... + * + * Return: The map register index corresponding to @intr. + * + * The return value is suitable for use with the (read|write)_gic_v[lo]_map + * accessor functions. + */ +static inline unsigned int +mips_gic_vx_map_reg(enum mips_gic_local_interrupt intr) +{ + /* WD, Compare & Timer are 1:1 */ + if (intr <= GIC_LOCAL_INT_TIMER) + return intr; + + /* FDC moves to after Timer... */ + if (intr == GIC_LOCAL_INT_FDC) + return GIC_LOCAL_INT_TIMER + 1; + + /* As a result everything else is offset by 1 */ + return intr + 1; +} + /** * gic_get_c0_compare_int() - Return cp0 count/compare interrupt virq * diff --git a/drivers/irqchip/irq-csky-mpintc.c b/drivers/irqchip/irq-csky-mpintc.c index c67c961ab6cc..a4c1aacba1ff 100644 --- a/drivers/irqchip/irq-csky-mpintc.c +++ b/drivers/irqchip/irq-csky-mpintc.c @@ -89,8 +89,19 @@ static int csky_irq_set_affinity(struct irq_data *d, if (cpu >= nr_cpu_ids) return -EINVAL; - /* Enable interrupt destination */ - cpu |= BIT(31); + /* +* The csky,mpintc could support auto irq deliver, but it only +* could deliver external irq to one cpu or all cpus. So it +* doesn't support deliver external irq to a group of cpus +* with cpu_mask. +* SO we only use auto deliver mode when affinity mask_val is +* equal to cpu_present_mask. +* +*/ + if (cpumask_equal(mask_val, cpu_present_mask)) + cpu = 0; + else + cpu |= BIT(31); writel_relaxed(cpu, INTCG_base + INTCG_CIDSTR + offset); diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 1e364d3ad9c5..f0523916232d 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -744,32 +744,43 @@ static void its_flush_cmd(struct its_node *its, struct its_cmd_block *cmd) } static int its_wait_for_range_completion(struct its_node *its, -struct its_cmd_block *from, +u64prev_idx, struct its_cmd_block *to) { - u64 rd_idx, from_idx, to_idx; + u64 rd_idx, to_idx, linear_idx; u32 count = 100;/* 1s! */ - from_idx = its_cmd_ptr_to_offset(its, from); + /* Linearize to_idx if the command set has wrapped around */ to_idx = its_cmd_ptr_to_offset(its, to); + if (to_idx < prev_idx) + to_idx += ITS_CMD_QUEUE_SZ; + + linear_idx = prev_idx; while (1) { + s64 delta; + rd_idx = readl_relaxed(its->base + GITS_CREADR); - /* Direct case */ - if (from_idx < to_idx && rd_idx >= to_idx) - break; + /* +* Compute the read pointer progress, taking the +* potential wrap-around into account. +*/ + delta = rd_idx - prev_idx; + if (rd_idx < prev_idx) + delta += ITS_CMD_QUEUE_SZ; -
Re: [GIT PULL] IRQ fixes
The pull request you sent on Fri, 12 Apr 2019 13:52:19 +0200: > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/6a022984c3feda8cc7d2d8c028b429715d0af531 Thank you! -- Deet-doot-dot, I am a bot. https://korg.wiki.kernel.org/userdoc/prtracker
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 325aa19598e410672175ed50982f902d4e3f31c5 genirq: Respect IRQCHIP_SKIP_SET_WAKE in irq_chip_set_wake_parent() Two genirq fixes, plus an irqchip driver error handling fix. Thanks, Ingo --> Dan Carpenter (1): irqchip/irq-ls1x: Missing error code in ls1x_intc_of_init() Kefeng Wang (1): genirq: Initialize request_mutex if CONFIG_SPARSE_IRQ=n Stephen Boyd (1): genirq: Respect IRQCHIP_SKIP_SET_WAKE in irq_chip_set_wake_parent() drivers/irqchip/irq-ls1x.c | 1 + kernel/irq/chip.c | 4 kernel/irq/irqdesc.c | 1 + 3 files changed, 6 insertions(+) diff --git a/drivers/irqchip/irq-ls1x.c b/drivers/irqchip/irq-ls1x.c index 86b72fbd3b45..353111a10413 100644 --- a/drivers/irqchip/irq-ls1x.c +++ b/drivers/irqchip/irq-ls1x.c @@ -130,6 +130,7 @@ static int __init ls1x_intc_of_init(struct device_node *node, NULL); if (!priv->domain) { pr_err("ls1x-irq: cannot add IRQ domain\n"); + err = -ENOMEM; goto out_iounmap; } diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 3faef4a77f71..51128bea3846 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -1449,6 +1449,10 @@ int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info) int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on) { data = data->parent_data; + + if (data->chip->flags & IRQCHIP_SKIP_SET_WAKE) + return 0; + if (data->chip->irq_set_wake) return data->chip->irq_set_wake(data, on); diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 13539e12cd80..9f8a709337cf 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -558,6 +558,7 @@ int __init early_irq_init(void) alloc_masks([i], node); raw_spin_lock_init([i].lock); lockdep_set_class([i].lock, _desc_lock_class); + mutex_init([i].request_mutex); desc_set_defaults(i, [i], node, NULL, NULL); } return arch_early_irq_init();
Re: [GIT PULL] IRQ fixes
The pull request you sent on Sun, 10 Feb 2019 10:08:57 +0100: > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/73a4c52184141943146ebbf07de4dca27141f21c Thank you! -- Deet-doot-dot, I am a bot. https://korg.wiki.kernel.org/userdoc/prtracker
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 8087f407364d50d5c3ac8e39365548351e2859f2 Merge tag 'irqchip-5.0-3' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent irqchip driver fixes: most of them are race fixes for ARM GIC (General Interrupt Controller) variants, but also a fix for the ARM MMP (Marvell PXA168 et al) irqchip affecting OLPC keyboards. Thanks, Ingo --> Heyi Guo (1): irqchip/gic-v4: Fix occasional VLPI drop Lubomir Rintel (1): irqchip/mmp: Only touch the PJ4 IRQ & FIQ bits on enable/disable Marc Zyngier (2): irqchip/gic-v3-its: Plug allocation race for devices sharing a DevID irqchip/gic-v3-its: Gracefully fail on LPI exhaustion Zenghui Yu (1): irqchip/gic-v3-its: Fix ITT_entry_size accessor drivers/irqchip/irq-gic-v3-its.c | 101 + drivers/irqchip/irq-mmp.c | 6 ++- include/linux/irqchip/arm-gic-v3.h | 2 +- 3 files changed, 85 insertions(+), 24 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 7f2a45445b00..c3aba3fc818d 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -97,9 +97,14 @@ struct its_device; * The ITS structure - contains most of the infrastructure, with the * top-level MSI domain, the command queue, the collections, and the * list of devices writing to it. + * + * dev_alloc_lock has to be taken for device allocations, while the + * spinlock must be taken to parse data structures such as the device + * list. */ struct its_node { raw_spinlock_t lock; + struct mutexdev_alloc_lock; struct list_headentry; void __iomem*base; phys_addr_t phys_base; @@ -156,6 +161,7 @@ struct its_device { void*itt; u32 nr_ites; u32 device_id; + boolshared; }; static struct { @@ -1580,6 +1586,9 @@ static unsigned long *its_lpi_alloc(int nr_irqs, u32 *base, int *nr_ids) nr_irqs /= 2; } while (nr_irqs > 0); + if (!nr_irqs) + err = -ENOSPC; + if (err) goto out; @@ -2059,6 +2068,29 @@ static int __init allocate_lpi_tables(void) return 0; } +static u64 its_clear_vpend_valid(void __iomem *vlpi_base) +{ + u32 count = 100;/* 1s! */ + bool clean; + u64 val; + + val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); + val &= ~GICR_VPENDBASER_Valid; + gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER); + + do { + val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); + clean = !(val & GICR_VPENDBASER_Dirty); + if (!clean) { + count--; + cpu_relax(); + udelay(1); + } + } while (!clean && count); + + return val; +} + static void its_cpu_init_lpis(void) { void __iomem *rbase = gic_data_rdist_rd_base(); @@ -2144,6 +2176,30 @@ static void its_cpu_init_lpis(void) val |= GICR_CTLR_ENABLE_LPIS; writel_relaxed(val, rbase + GICR_CTLR); + if (gic_rdists->has_vlpis) { + void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); + + /* +* It's possible for CPU to receive VLPIs before it is +* sheduled as a vPE, especially for the first CPU, and the +* VLPI with INTID larger than 2^(IDbits+1) will be considered +* as out of range and dropped by GIC. +* So we initialize IDbits to known value to avoid VLPI drop. +*/ + val = (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK; + pr_debug("GICv4: CPU%d: Init IDbits to 0x%llx for GICR_VPROPBASER\n", + smp_processor_id(), val); + gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER); + + /* +* Also clear Valid bit of GICR_VPENDBASER, in case some +* ancient programming gets left in and has possibility of +* corrupting memory. +*/ + val = its_clear_vpend_valid(vlpi_base); + WARN_ON(val & GICR_VPENDBASER_Dirty); + } + /* Make sure the GIC has seen the above */ dsb(sy); out: @@ -2422,6 +2478,7 @@ static int its_msi_prepare(struct irq_domain *domain, struct device *dev, struct its_device *its_dev; struct msi_domain_info *msi_info; u32 dev_id; + int err = 0; /* * We ignore "dev" entierely, and rely on the dev_id that has @@ -2444,6 +2501,7 @@ static int
Re: [GIT PULL] IRQ fixes
On Sat, Nov 3, 2018 at 3:59 PM Ingo Molnar wrote: > > An irqchip driver fix and a memory (over-)allocation fix. Pulled, Linus
Re: [GIT PULL] IRQ fixes
On Sat, Nov 3, 2018 at 3:59 PM Ingo Molnar wrote: > > An irqchip driver fix and a memory (over-)allocation fix. Pulled, Linus
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 3424243e39e8ec138486926949e3668e7553125d irqchip/irq-mvebu-sei: Fix a NULL vs IS_ERR() bug in probe function An irqchip driver fix and a memory (over-)allocation fix. Thanks, Ingo --> Dan Carpenter (1): irqchip/irq-mvebu-sei: Fix a NULL vs IS_ERR() bug in probe function Michael Kelley (1): irq/matrix: Fix memory overallocation drivers/irqchip/irq-mvebu-sei.c | 4 ++-- kernel/irq/matrix.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-mvebu-sei.c b/drivers/irqchip/irq-mvebu-sei.c index 566d69a2edbc..add4c9c934c8 100644 --- a/drivers/irqchip/irq-mvebu-sei.c +++ b/drivers/irqchip/irq-mvebu-sei.c @@ -384,9 +384,9 @@ static int mvebu_sei_probe(struct platform_device *pdev) sei->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); sei->base = devm_ioremap_resource(sei->dev, sei->res); - if (!sei->base) { + if (IS_ERR(sei->base)) { dev_err(sei->dev, "Failed to remap SEI resource\n"); - return -ENODEV; + return PTR_ERR(sei->base); } /* Retrieve the SEI capabilities with the interrupt ranges */ diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c index 6e6d467f3dec..1f0985adf193 100644 --- a/kernel/irq/matrix.c +++ b/kernel/irq/matrix.c @@ -8,7 +8,7 @@ #include #include -#define IRQ_MATRIX_SIZE(BITS_TO_LONGS(IRQ_MATRIX_BITS) * sizeof(unsigned long)) +#define IRQ_MATRIX_SIZE(BITS_TO_LONGS(IRQ_MATRIX_BITS)) struct cpumap { unsigned intavailable;
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 3424243e39e8ec138486926949e3668e7553125d irqchip/irq-mvebu-sei: Fix a NULL vs IS_ERR() bug in probe function An irqchip driver fix and a memory (over-)allocation fix. Thanks, Ingo --> Dan Carpenter (1): irqchip/irq-mvebu-sei: Fix a NULL vs IS_ERR() bug in probe function Michael Kelley (1): irq/matrix: Fix memory overallocation drivers/irqchip/irq-mvebu-sei.c | 4 ++-- kernel/irq/matrix.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-mvebu-sei.c b/drivers/irqchip/irq-mvebu-sei.c index 566d69a2edbc..add4c9c934c8 100644 --- a/drivers/irqchip/irq-mvebu-sei.c +++ b/drivers/irqchip/irq-mvebu-sei.c @@ -384,9 +384,9 @@ static int mvebu_sei_probe(struct platform_device *pdev) sei->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); sei->base = devm_ioremap_resource(sei->dev, sei->res); - if (!sei->base) { + if (IS_ERR(sei->base)) { dev_err(sei->dev, "Failed to remap SEI resource\n"); - return -ENODEV; + return PTR_ERR(sei->base); } /* Retrieve the SEI capabilities with the interrupt ranges */ diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c index 6e6d467f3dec..1f0985adf193 100644 --- a/kernel/irq/matrix.c +++ b/kernel/irq/matrix.c @@ -8,7 +8,7 @@ #include #include -#define IRQ_MATRIX_SIZE(BITS_TO_LONGS(IRQ_MATRIX_BITS) * sizeof(unsigned long)) +#define IRQ_MATRIX_SIZE(BITS_TO_LONGS(IRQ_MATRIX_BITS)) struct cpumap { unsigned intavailable;
[GIT pull] irq fixes for 4.18
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A single bugfix for the irq core to prevent silent data corruption and malfunction of threaded interrupts under certain conditions. Thanks, tglx --> Thomas Gleixner (1): genirq: Make force irq threading setup more robust kernel/irq/manage.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index daeabd791d58..9a8b7ba9aa88 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1068,6 +1068,13 @@ static int irq_setup_forced_threading(struct irqaction *new) if (new->flags & (IRQF_NO_THREAD | IRQF_PERCPU | IRQF_ONESHOT)) return 0; + /* +* No further action required for interrupts which are requested as +* threaded interrupts already +*/ + if (new->handler == irq_default_primary_handler) + return 0; + new->flags |= IRQF_ONESHOT; /* @@ -1075,7 +1082,7 @@ static int irq_setup_forced_threading(struct irqaction *new) * thread handler. We force thread them as well by creating a * secondary action. */ - if (new->handler != irq_default_primary_handler && new->thread_fn) { + if (new->handler && new->thread_fn) { /* Allocate the secondary action */ new->secondary = kzalloc(sizeof(struct irqaction), GFP_KERNEL); if (!new->secondary)
[GIT pull] irq fixes for 4.18
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A single bugfix for the irq core to prevent silent data corruption and malfunction of threaded interrupts under certain conditions. Thanks, tglx --> Thomas Gleixner (1): genirq: Make force irq threading setup more robust kernel/irq/manage.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index daeabd791d58..9a8b7ba9aa88 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1068,6 +1068,13 @@ static int irq_setup_forced_threading(struct irqaction *new) if (new->flags & (IRQF_NO_THREAD | IRQF_PERCPU | IRQF_ONESHOT)) return 0; + /* +* No further action required for interrupts which are requested as +* threaded interrupts already +*/ + if (new->handler == irq_default_primary_handler) + return 0; + new->flags |= IRQF_ONESHOT; /* @@ -1075,7 +1082,7 @@ static int irq_setup_forced_threading(struct irqaction *new) * thread handler. We force thread them as well by creating a * secondary action. */ - if (new->handler != irq_default_primary_handler && new->thread_fn) { + if (new->handler && new->thread_fn) { /* Allocate the secondary action */ new->secondary = kzalloc(sizeof(struct irqaction), GFP_KERNEL); if (!new->secondary)
[GIT pull] irq fixes for 4.16
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Three fixes for irq chip drivers: - Make sure the allocations in the GIC-V3 ITS driver are large enough to accomodate the interrupt space - Fix a misplaced __iomem annotation which causes a splat of 26 sparse warnings - Remove an unused function in the IMX GPCV2 driver which causes build warnings Thanks, tglx --> Ard Biesheuvel (1): irqchip/gic-v3-its: Ensure nr_ites >= nr_lpis Fabio Estevam (1): irqchip/irq-imx-gpcv2: Remove unused function Robin Murphy (1): irqchip/gic-v3-its: Fix misplaced __iomem annotations drivers/irqchip/irq-gic-v3-its.c | 13 ++--- drivers/irqchip/irq-imx-gpcv2.c | 14 -- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 1d3056f53747..2cbb19cddbf8 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1412,7 +1412,7 @@ static struct irq_chip its_irq_chip = { * This gives us (((1UL << id_bits) - 8192) >> 5) possible allocations. */ #define IRQS_PER_CHUNK_SHIFT 5 -#define IRQS_PER_CHUNK (1 << IRQS_PER_CHUNK_SHIFT) +#define IRQS_PER_CHUNK (1UL << IRQS_PER_CHUNK_SHIFT) #define ITS_MAX_LPI_NRBITS 16 /* 64K LPIs */ static unsigned long *lpi_bitmap; @@ -2119,11 +2119,10 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, dev = kzalloc(sizeof(*dev), GFP_KERNEL); /* -* At least one bit of EventID is being used, hence a minimum -* of two entries. No, the architecture doesn't let you -* express an ITT with a single entry. +* We allocate at least one chunk worth of LPIs bet device, +* and thus that many ITEs. The device may require less though. */ - nr_ites = max(2UL, roundup_pow_of_two(nvecs)); + nr_ites = max(IRQS_PER_CHUNK, roundup_pow_of_two(nvecs)); sz = nr_ites * its->ite_size; sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; itt = kzalloc(sz, GFP_KERNEL); @@ -2495,7 +2494,7 @@ static int its_vpe_set_affinity(struct irq_data *d, static void its_vpe_schedule(struct its_vpe *vpe) { - void * __iomem vlpi_base = gic_data_rdist_vlpi_base(); + void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); u64 val; /* Schedule the VPE */ @@ -2527,7 +2526,7 @@ static void its_vpe_schedule(struct its_vpe *vpe) static void its_vpe_deschedule(struct its_vpe *vpe) { - void * __iomem vlpi_base = gic_data_rdist_vlpi_base(); + void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); u32 count = 100;/* 1s! */ bool clean; u64 val; diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c index 675eda5ff2b8..4760307ab43f 100644 --- a/drivers/irqchip/irq-imx-gpcv2.c +++ b/drivers/irqchip/irq-imx-gpcv2.c @@ -28,20 +28,6 @@ struct gpcv2_irqchip_data { static struct gpcv2_irqchip_data *imx_gpcv2_instance; -/* - * Interface for the low level wakeup code. - */ -u32 imx_gpcv2_get_wakeup_source(u32 **sources) -{ - if (!imx_gpcv2_instance) - return 0; - - if (sources) - *sources = imx_gpcv2_instance->wakeup_sources; - - return IMR_NUM; -} - static int gpcv2_wakeup_source_save(void) { struct gpcv2_irqchip_data *cd;
[GIT pull] irq fixes for 4.16
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Three fixes for irq chip drivers: - Make sure the allocations in the GIC-V3 ITS driver are large enough to accomodate the interrupt space - Fix a misplaced __iomem annotation which causes a splat of 26 sparse warnings - Remove an unused function in the IMX GPCV2 driver which causes build warnings Thanks, tglx --> Ard Biesheuvel (1): irqchip/gic-v3-its: Ensure nr_ites >= nr_lpis Fabio Estevam (1): irqchip/irq-imx-gpcv2: Remove unused function Robin Murphy (1): irqchip/gic-v3-its: Fix misplaced __iomem annotations drivers/irqchip/irq-gic-v3-its.c | 13 ++--- drivers/irqchip/irq-imx-gpcv2.c | 14 -- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 1d3056f53747..2cbb19cddbf8 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1412,7 +1412,7 @@ static struct irq_chip its_irq_chip = { * This gives us (((1UL << id_bits) - 8192) >> 5) possible allocations. */ #define IRQS_PER_CHUNK_SHIFT 5 -#define IRQS_PER_CHUNK (1 << IRQS_PER_CHUNK_SHIFT) +#define IRQS_PER_CHUNK (1UL << IRQS_PER_CHUNK_SHIFT) #define ITS_MAX_LPI_NRBITS 16 /* 64K LPIs */ static unsigned long *lpi_bitmap; @@ -2119,11 +2119,10 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, dev = kzalloc(sizeof(*dev), GFP_KERNEL); /* -* At least one bit of EventID is being used, hence a minimum -* of two entries. No, the architecture doesn't let you -* express an ITT with a single entry. +* We allocate at least one chunk worth of LPIs bet device, +* and thus that many ITEs. The device may require less though. */ - nr_ites = max(2UL, roundup_pow_of_two(nvecs)); + nr_ites = max(IRQS_PER_CHUNK, roundup_pow_of_two(nvecs)); sz = nr_ites * its->ite_size; sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; itt = kzalloc(sz, GFP_KERNEL); @@ -2495,7 +2494,7 @@ static int its_vpe_set_affinity(struct irq_data *d, static void its_vpe_schedule(struct its_vpe *vpe) { - void * __iomem vlpi_base = gic_data_rdist_vlpi_base(); + void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); u64 val; /* Schedule the VPE */ @@ -2527,7 +2526,7 @@ static void its_vpe_schedule(struct its_vpe *vpe) static void its_vpe_deschedule(struct its_vpe *vpe) { - void * __iomem vlpi_base = gic_data_rdist_vlpi_base(); + void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); u32 count = 100;/* 1s! */ bool clean; u64 val; diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c index 675eda5ff2b8..4760307ab43f 100644 --- a/drivers/irqchip/irq-imx-gpcv2.c +++ b/drivers/irqchip/irq-imx-gpcv2.c @@ -28,20 +28,6 @@ struct gpcv2_irqchip_data { static struct gpcv2_irqchip_data *imx_gpcv2_instance; -/* - * Interface for the low level wakeup code. - */ -u32 imx_gpcv2_get_wakeup_source(u32 **sources) -{ - if (!imx_gpcv2_instance) - return 0; - - if (sources) - *sources = imx_gpcv2_instance->wakeup_sources; - - return IMR_NUM; -} - static int gpcv2_wakeup_source_save(void) { struct gpcv2_irqchip_data *cd;
[GIT pull] irq fixes for 4.15
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A rather large update after the kaisered maintainer finally found time to handle regression reports. - The larger part addresses a regression caused by the x86 vector management rework. The reservation based model does not work reliable for MSI interrupts, if they cannot be masked (yes, yet another hw engineering trainwreck). The reason is that the reservation mode assigns a dummy vector when the interrupt is allocated and switches to a real vector when the interrupt is requested. If the MSI entry cannot be masked then the initialization might raise an interrupt before the interrupt is requested, which ends up as spurious interrupt and causes device malfunction and worse. The fix is to exclude MSI interrupts which do not support masking from reservation mode and assign a real vector right away. - Extend the extra lockdep class setup for nested interrupts with a class for the recently added irq_desc::request_mutex so lockdep can differeniate and does not emit false positive warnings. - A ratelimit guard for the bad irq printout so in case a bad irq comes back immediately the system does not drown in dmesg spam. Thanks, tglx --> Andrew Lunn (1): kernel/irq: Extend lockdep class for request mutex Guenter Roeck (1): genirq: Guard handle_bad_irq log messages Thomas Gleixner (6): gpio: brcmstb: Make really use of the new lockdep class genirq/msi: Handle reactivation only on success genirq: Introduce IRQD_CAN_RESERVE flag x86/vector: Use IRQD_CAN_RESERVE flag genirq/irqdomain: Rename early argument of irq_domain_activate_irq() genirq/msi, x86/vector: Prevent reservation mode for non maskable MSI arch/powerpc/sysdev/fsl_msi.c | 4 +- arch/x86/include/asm/irqdomain.h | 2 +- arch/x86/include/asm/trace/irq_vectors.h | 16 arch/x86/kernel/apic/io_apic.c| 2 +- arch/x86/kernel/apic/vector.c | 20 -- arch/x86/platform/uv/uv_irq.c | 2 +- drivers/gpio/gpio-bcm-kona.c | 3 +- drivers/gpio/gpio-brcmstb.c | 4 +- drivers/gpio/gpio-tegra.c | 4 +- drivers/gpio/gpio-xgene-sb.c | 2 +- drivers/gpio/gpiolib.c| 27 - drivers/iommu/amd_iommu.c | 2 +- drivers/iommu/intel_irq_remapping.c | 2 +- drivers/irqchip/irq-gic-v3-its.c | 4 +- drivers/irqchip/irq-renesas-intc-irqpin.c | 6 ++- drivers/mfd/arizona-irq.c | 4 +- drivers/pinctrl/pinctrl-single.c | 5 ++- drivers/pinctrl/stm32/pinctrl-stm32.c | 2 +- include/linux/gpio/driver.h | 33 ++-- include/linux/irq.h | 17 include/linux/irqdesc.h | 9 +++-- include/linux/irqdomain.h | 2 +- kernel/irq/debug.h| 5 +++ kernel/irq/debugfs.c | 1 + kernel/irq/generic-chip.c | 11 -- kernel/irq/internals.h| 2 +- kernel/irq/irqdomain.c| 13 --- kernel/irq/msi.c | 64 +++ 28 files changed, 196 insertions(+), 72 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 44cbf4c12ea1..df95102e732c 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -354,6 +354,7 @@ static int fsl_of_msi_remove(struct platform_device *ofdev) } static struct lock_class_key fsl_msi_irq_class; +static struct lock_class_key fsl_msi_irq_request_class; static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev, int offset, int irq_index) @@ -373,7 +374,8 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev, dev_err(>dev, "No memory for MSI cascade data\n"); return -ENOMEM; } - irq_set_lockdep_class(virt_msir, _msi_irq_class); + irq_set_lockdep_class(virt_msir, _msi_irq_class, + _msi_irq_request_class); cascade_data->index = offset; cascade_data->msi_data = msi; cascade_data->virq = virt_msir; diff --git a/arch/x86/include/asm/irqdomain.h b/arch/x86/include/asm/irqdomain.h index 139feef467f7..c066ffae222b 100644 --- a/arch/x86/include/asm/irqdomain.h +++ b/arch/x86/include/asm/irqdomain.h @@ -44,7 +44,7 @@ extern int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, extern void mp_irqdomain_free(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs); extern int mp_irqdomain_activate(struct irq_domain *domain, -
[GIT pull] irq fixes for 4.15
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A rather large update after the kaisered maintainer finally found time to handle regression reports. - The larger part addresses a regression caused by the x86 vector management rework. The reservation based model does not work reliable for MSI interrupts, if they cannot be masked (yes, yet another hw engineering trainwreck). The reason is that the reservation mode assigns a dummy vector when the interrupt is allocated and switches to a real vector when the interrupt is requested. If the MSI entry cannot be masked then the initialization might raise an interrupt before the interrupt is requested, which ends up as spurious interrupt and causes device malfunction and worse. The fix is to exclude MSI interrupts which do not support masking from reservation mode and assign a real vector right away. - Extend the extra lockdep class setup for nested interrupts with a class for the recently added irq_desc::request_mutex so lockdep can differeniate and does not emit false positive warnings. - A ratelimit guard for the bad irq printout so in case a bad irq comes back immediately the system does not drown in dmesg spam. Thanks, tglx --> Andrew Lunn (1): kernel/irq: Extend lockdep class for request mutex Guenter Roeck (1): genirq: Guard handle_bad_irq log messages Thomas Gleixner (6): gpio: brcmstb: Make really use of the new lockdep class genirq/msi: Handle reactivation only on success genirq: Introduce IRQD_CAN_RESERVE flag x86/vector: Use IRQD_CAN_RESERVE flag genirq/irqdomain: Rename early argument of irq_domain_activate_irq() genirq/msi, x86/vector: Prevent reservation mode for non maskable MSI arch/powerpc/sysdev/fsl_msi.c | 4 +- arch/x86/include/asm/irqdomain.h | 2 +- arch/x86/include/asm/trace/irq_vectors.h | 16 arch/x86/kernel/apic/io_apic.c| 2 +- arch/x86/kernel/apic/vector.c | 20 -- arch/x86/platform/uv/uv_irq.c | 2 +- drivers/gpio/gpio-bcm-kona.c | 3 +- drivers/gpio/gpio-brcmstb.c | 4 +- drivers/gpio/gpio-tegra.c | 4 +- drivers/gpio/gpio-xgene-sb.c | 2 +- drivers/gpio/gpiolib.c| 27 - drivers/iommu/amd_iommu.c | 2 +- drivers/iommu/intel_irq_remapping.c | 2 +- drivers/irqchip/irq-gic-v3-its.c | 4 +- drivers/irqchip/irq-renesas-intc-irqpin.c | 6 ++- drivers/mfd/arizona-irq.c | 4 +- drivers/pinctrl/pinctrl-single.c | 5 ++- drivers/pinctrl/stm32/pinctrl-stm32.c | 2 +- include/linux/gpio/driver.h | 33 ++-- include/linux/irq.h | 17 include/linux/irqdesc.h | 9 +++-- include/linux/irqdomain.h | 2 +- kernel/irq/debug.h| 5 +++ kernel/irq/debugfs.c | 1 + kernel/irq/generic-chip.c | 11 -- kernel/irq/internals.h| 2 +- kernel/irq/irqdomain.c| 13 --- kernel/irq/msi.c | 64 +++ 28 files changed, 196 insertions(+), 72 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 44cbf4c12ea1..df95102e732c 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -354,6 +354,7 @@ static int fsl_of_msi_remove(struct platform_device *ofdev) } static struct lock_class_key fsl_msi_irq_class; +static struct lock_class_key fsl_msi_irq_request_class; static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev, int offset, int irq_index) @@ -373,7 +374,8 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev, dev_err(>dev, "No memory for MSI cascade data\n"); return -ENOMEM; } - irq_set_lockdep_class(virt_msir, _msi_irq_class); + irq_set_lockdep_class(virt_msir, _msi_irq_class, + _msi_irq_request_class); cascade_data->index = offset; cascade_data->msi_data = msi; cascade_data->virq = virt_msir; diff --git a/arch/x86/include/asm/irqdomain.h b/arch/x86/include/asm/irqdomain.h index 139feef467f7..c066ffae222b 100644 --- a/arch/x86/include/asm/irqdomain.h +++ b/arch/x86/include/asm/irqdomain.h @@ -44,7 +44,7 @@ extern int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, extern void mp_irqdomain_free(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs); extern int mp_irqdomain_activate(struct irq_domain *domain, -
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 4ce413d1840b25b101be3c0559161db8891f3360 irqdesc: Use bool return type instead of int Two fixes: use bool type consistently, plus a irq_matrix_available() bugfix. Thanks, Ingo --> Thomas Gleixner (1): genirq/matrix: Fix the precedence fix for real Will Deacon (1): irqdesc: Use bool return type instead of int include/linux/irqdesc.h | 6 +++--- kernel/irq/matrix.c | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index dd418955962b..39fb3700f7a9 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -230,7 +230,7 @@ irq_set_chip_handler_name_locked(struct irq_data *data, struct irq_chip *chip, data->chip = chip; } -static inline int irq_balancing_disabled(unsigned int irq) +static inline bool irq_balancing_disabled(unsigned int irq) { struct irq_desc *desc; @@ -238,7 +238,7 @@ static inline int irq_balancing_disabled(unsigned int irq) return desc->status_use_accessors & IRQ_NO_BALANCING_MASK; } -static inline int irq_is_percpu(unsigned int irq) +static inline bool irq_is_percpu(unsigned int irq) { struct irq_desc *desc; @@ -246,7 +246,7 @@ static inline int irq_is_percpu(unsigned int irq) return desc->status_use_accessors & IRQ_PER_CPU; } -static inline int irq_is_percpu_devid(unsigned int irq) +static inline bool irq_is_percpu_devid(unsigned int irq) { struct irq_desc *desc; diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c index 7df2480005f8..0ba0dd8863a7 100644 --- a/kernel/irq/matrix.c +++ b/kernel/irq/matrix.c @@ -384,7 +384,9 @@ unsigned int irq_matrix_available(struct irq_matrix *m, bool cpudown) { struct cpumap *cm = this_cpu_ptr(m->maps); - return (m->global_available - cpudown) ? cm->available : 0; + if (!cpudown) + return m->global_available; + return m->global_available - cm->available; } /**
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 4ce413d1840b25b101be3c0559161db8891f3360 irqdesc: Use bool return type instead of int Two fixes: use bool type consistently, plus a irq_matrix_available() bugfix. Thanks, Ingo --> Thomas Gleixner (1): genirq/matrix: Fix the precedence fix for real Will Deacon (1): irqdesc: Use bool return type instead of int include/linux/irqdesc.h | 6 +++--- kernel/irq/matrix.c | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index dd418955962b..39fb3700f7a9 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -230,7 +230,7 @@ irq_set_chip_handler_name_locked(struct irq_data *data, struct irq_chip *chip, data->chip = chip; } -static inline int irq_balancing_disabled(unsigned int irq) +static inline bool irq_balancing_disabled(unsigned int irq) { struct irq_desc *desc; @@ -238,7 +238,7 @@ static inline int irq_balancing_disabled(unsigned int irq) return desc->status_use_accessors & IRQ_NO_BALANCING_MASK; } -static inline int irq_is_percpu(unsigned int irq) +static inline bool irq_is_percpu(unsigned int irq) { struct irq_desc *desc; @@ -246,7 +246,7 @@ static inline int irq_is_percpu(unsigned int irq) return desc->status_use_accessors & IRQ_PER_CPU; } -static inline int irq_is_percpu_devid(unsigned int irq) +static inline bool irq_is_percpu_devid(unsigned int irq) { struct irq_desc *desc; diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c index 7df2480005f8..0ba0dd8863a7 100644 --- a/kernel/irq/matrix.c +++ b/kernel/irq/matrix.c @@ -384,7 +384,9 @@ unsigned int irq_matrix_available(struct irq_matrix *m, bool cpudown) { struct cpumap *cm = this_cpu_ptr(m->maps); - return (m->global_available - cpudown) ? cm->available : 0; + if (!cpudown) + return m->global_available; + return m->global_available - cm->available; } /**
[GIT pull] irq fixes for 4.14
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A set of small fixes mostly in the irq drivers area: - Make the tango irq chip work correctly, which requires a new function in the generiq irq chip implementation - A set of updates to the GIC-V3 ITS driver removing a bogus BUG_ON() and parsing the VCPU table size correctly. Thanks, tglx --> Doug Berger (2): genirq: generic chip: Add irq_gc_mask_disable_and_ack_set() genirq: generic chip: remove irq_gc_mask_disable_reg_and_ack() Florian Fainelli (1): irqchip/tango: Use irq_gc_mask_disable_and_ack_set Julien Grall (1): DT: arm,gic-v3: Update the ITS size in the examples Shanker Donthineni (3): irqchip/gic-v3-its: Fix the incorrect BUG_ON in its_init_vpe_domain() irqchip/gic-v3-its: Fix the incorrect parsing of VCPU table size irqchip/gic-v3-its: Add missing changes to support 52bit physical address .../bindings/interrupt-controller/arm,gic-v3.txt | 6 +-- drivers/irqchip/irq-gic-v3-its.c | 43 +- drivers/irqchip/irq-tango.c| 2 +- include/linux/irq.h| 2 +- include/linux/irqchip/arm-gic-v3.h | 2 + kernel/irq/generic-chip.c | 15 ++-- 6 files changed, 52 insertions(+), 18 deletions(-) diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt index 4c29cdab0ea5..5eb108e180fa 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt @@ -99,7 +99,7 @@ Examples: compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; - reg = <0x0 0x2c20 0 0x20>; + reg = <0x0 0x2c20 0 0x2>; }; }; @@ -124,14 +124,14 @@ Examples: compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; - reg = <0x0 0x2c20 0 0x20>; + reg = <0x0 0x2c20 0 0x2>; }; gic-its@2c40 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; - reg = <0x0 0x2c40 0 0x20>; + reg = <0x0 0x2c40 0 0x2>; }; ppi-partitions { diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index e8d89343d613..e88395605e32 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -107,6 +107,10 @@ struct its_node { #define ITS_ITT_ALIGN SZ_256 +/* The maximum number of VPEID bits supported by VLPI commands */ +#define ITS_MAX_VPEID_BITS (16) +#define ITS_MAX_VPEID (1 << (ITS_MAX_VPEID_BITS)) + /* Convert page order to size in bytes */ #define PAGE_ORDER_TO_SIZE(o) (PAGE_SIZE << (o)) @@ -308,7 +312,7 @@ static void its_encode_size(struct its_cmd_block *cmd, u8 size) static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr) { - its_mask_encode(>raw_cmd[2], itt_addr >> 8, 50, 8); + its_mask_encode(>raw_cmd[2], itt_addr >> 8, 51, 8); } static void its_encode_valid(struct its_cmd_block *cmd, int valid) @@ -318,7 +322,7 @@ static void its_encode_valid(struct its_cmd_block *cmd, int valid) static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr) { - its_mask_encode(>raw_cmd[2], target_addr >> 16, 50, 16); + its_mask_encode(>raw_cmd[2], target_addr >> 16, 51, 16); } static void its_encode_collection(struct its_cmd_block *cmd, u16 col) @@ -358,7 +362,7 @@ static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list) static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa) { - its_mask_encode(>raw_cmd[3], vpt_pa >> 16, 50, 16); + its_mask_encode(>raw_cmd[3], vpt_pa >> 16, 51, 16); } static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size) @@ -1478,9 +1482,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, u64 val = its_read_baser(its, baser); u64 esz = GITS_BASER_ENTRY_SIZE(val); u64 type = GITS_BASER_TYPE(val); + u64 baser_phys, tmp; u32 alloc_pages; void *base; - u64 tmp; retry_alloc_baser: alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz); @@ -1496,8 +1500,24 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, if (!base) return -ENOMEM; +
[GIT pull] irq fixes for 4.14
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A set of small fixes mostly in the irq drivers area: - Make the tango irq chip work correctly, which requires a new function in the generiq irq chip implementation - A set of updates to the GIC-V3 ITS driver removing a bogus BUG_ON() and parsing the VCPU table size correctly. Thanks, tglx --> Doug Berger (2): genirq: generic chip: Add irq_gc_mask_disable_and_ack_set() genirq: generic chip: remove irq_gc_mask_disable_reg_and_ack() Florian Fainelli (1): irqchip/tango: Use irq_gc_mask_disable_and_ack_set Julien Grall (1): DT: arm,gic-v3: Update the ITS size in the examples Shanker Donthineni (3): irqchip/gic-v3-its: Fix the incorrect BUG_ON in its_init_vpe_domain() irqchip/gic-v3-its: Fix the incorrect parsing of VCPU table size irqchip/gic-v3-its: Add missing changes to support 52bit physical address .../bindings/interrupt-controller/arm,gic-v3.txt | 6 +-- drivers/irqchip/irq-gic-v3-its.c | 43 +- drivers/irqchip/irq-tango.c| 2 +- include/linux/irq.h| 2 +- include/linux/irqchip/arm-gic-v3.h | 2 + kernel/irq/generic-chip.c | 15 ++-- 6 files changed, 52 insertions(+), 18 deletions(-) diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt index 4c29cdab0ea5..5eb108e180fa 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt @@ -99,7 +99,7 @@ Examples: compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; - reg = <0x0 0x2c20 0 0x20>; + reg = <0x0 0x2c20 0 0x2>; }; }; @@ -124,14 +124,14 @@ Examples: compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; - reg = <0x0 0x2c20 0 0x20>; + reg = <0x0 0x2c20 0 0x2>; }; gic-its@2c40 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; - reg = <0x0 0x2c40 0 0x20>; + reg = <0x0 0x2c40 0 0x2>; }; ppi-partitions { diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index e8d89343d613..e88395605e32 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -107,6 +107,10 @@ struct its_node { #define ITS_ITT_ALIGN SZ_256 +/* The maximum number of VPEID bits supported by VLPI commands */ +#define ITS_MAX_VPEID_BITS (16) +#define ITS_MAX_VPEID (1 << (ITS_MAX_VPEID_BITS)) + /* Convert page order to size in bytes */ #define PAGE_ORDER_TO_SIZE(o) (PAGE_SIZE << (o)) @@ -308,7 +312,7 @@ static void its_encode_size(struct its_cmd_block *cmd, u8 size) static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr) { - its_mask_encode(>raw_cmd[2], itt_addr >> 8, 50, 8); + its_mask_encode(>raw_cmd[2], itt_addr >> 8, 51, 8); } static void its_encode_valid(struct its_cmd_block *cmd, int valid) @@ -318,7 +322,7 @@ static void its_encode_valid(struct its_cmd_block *cmd, int valid) static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr) { - its_mask_encode(>raw_cmd[2], target_addr >> 16, 50, 16); + its_mask_encode(>raw_cmd[2], target_addr >> 16, 51, 16); } static void its_encode_collection(struct its_cmd_block *cmd, u16 col) @@ -358,7 +362,7 @@ static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list) static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa) { - its_mask_encode(>raw_cmd[3], vpt_pa >> 16, 50, 16); + its_mask_encode(>raw_cmd[3], vpt_pa >> 16, 51, 16); } static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size) @@ -1478,9 +1482,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, u64 val = its_read_baser(its, baser); u64 esz = GITS_BASER_ENTRY_SIZE(val); u64 type = GITS_BASER_TYPE(val); + u64 baser_phys, tmp; u32 alloc_pages; void *base; - u64 tmp; retry_alloc_baser: alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz); @@ -1496,8 +1500,24 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, if (!base) return -ENOMEM; +
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: e43b3b58548051f8809391eb7bec7a27ed3003ea genirq/cpuhotplug: Enforce affinity setting on startup of managed irqs A CPU hotplug related fix, plus two related sanity checks. Thanks, Ingo --> Thomas Gleixner (3): genirq: Warn when effective affinity is not updated genirq/cpuhotplug: Add sanity check for effective affinity mask genirq/cpuhotplug: Enforce affinity setting on startup of managed irqs kernel/irq/chip.c | 2 +- kernel/irq/cpuhotplug.c | 28 +++- kernel/irq/manage.c | 17 + 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 6fc89fd93824..5a2ef92c2782 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -265,8 +265,8 @@ int irq_startup(struct irq_desc *desc, bool resend, bool force) irq_setup_affinity(desc); break; case IRQ_STARTUP_MANAGED: + irq_do_set_affinity(d, aff, false); ret = __irq_startup(desc); - irq_set_affinity_locked(d, aff, false); break; case IRQ_STARTUP_ABORT: return 0; diff --git a/kernel/irq/cpuhotplug.c b/kernel/irq/cpuhotplug.c index 638eb9c83d9f..9eb09aef0313 100644 --- a/kernel/irq/cpuhotplug.c +++ b/kernel/irq/cpuhotplug.c @@ -18,8 +18,34 @@ static inline bool irq_needs_fixup(struct irq_data *d) { const struct cpumask *m = irq_data_get_effective_affinity_mask(d); + unsigned int cpu = smp_processor_id(); - return cpumask_test_cpu(smp_processor_id(), m); +#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK + /* +* The cpumask_empty() check is a workaround for interrupt chips, +* which do not implement effective affinity, but the architecture has +* enabled the config switch. Use the general affinity mask instead. +*/ + if (cpumask_empty(m)) + m = irq_data_get_affinity_mask(d); + + /* +* Sanity check. If the mask is not empty when excluding the outgoing +* CPU then it must contain at least one online CPU. The outgoing CPU +* has been removed from the online mask already. +*/ + if (cpumask_any_but(m, cpu) < nr_cpu_ids && + cpumask_any_and(m, cpu_online_mask) >= nr_cpu_ids) { + /* +* If this happens then there was a missed IRQ fixup at some +* point. Warn about it and enforce fixup. +*/ + pr_warn("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n", + cpumask_pr_args(m), d->irq, cpu); + return true; + } +#endif + return cpumask_test_cpu(cpu, m); } static bool migrate_one_irq(struct irq_desc *desc) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index d00132b5c325..4bff6a10ae8e 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -168,6 +168,19 @@ void irq_set_thread_affinity(struct irq_desc *desc) set_bit(IRQTF_AFFINITY, >thread_flags); } +static void irq_validate_effective_affinity(struct irq_data *data) +{ +#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK + const struct cpumask *m = irq_data_get_effective_affinity_mask(data); + struct irq_chip *chip = irq_data_get_irq_chip(data); + + if (!cpumask_empty(m)) + return; + pr_warn_once("irq_chip %s did not update eff. affinity mask of irq %u\n", +chip->name, data->irq); +#endif +} + int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { @@ -175,12 +188,16 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask, struct irq_chip *chip = irq_data_get_irq_chip(data); int ret; + if (!chip || !chip->irq_set_affinity) + return -EINVAL; + ret = chip->irq_set_affinity(data, mask, force); switch (ret) { case IRQ_SET_MASK_OK: case IRQ_SET_MASK_OK_DONE: cpumask_copy(desc->irq_common_data.affinity, mask); case IRQ_SET_MASK_OK_NOCOPY: + irq_validate_effective_affinity(data); irq_set_thread_affinity(desc); ret = 0; }
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: e43b3b58548051f8809391eb7bec7a27ed3003ea genirq/cpuhotplug: Enforce affinity setting on startup of managed irqs A CPU hotplug related fix, plus two related sanity checks. Thanks, Ingo --> Thomas Gleixner (3): genirq: Warn when effective affinity is not updated genirq/cpuhotplug: Add sanity check for effective affinity mask genirq/cpuhotplug: Enforce affinity setting on startup of managed irqs kernel/irq/chip.c | 2 +- kernel/irq/cpuhotplug.c | 28 +++- kernel/irq/manage.c | 17 + 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 6fc89fd93824..5a2ef92c2782 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -265,8 +265,8 @@ int irq_startup(struct irq_desc *desc, bool resend, bool force) irq_setup_affinity(desc); break; case IRQ_STARTUP_MANAGED: + irq_do_set_affinity(d, aff, false); ret = __irq_startup(desc); - irq_set_affinity_locked(d, aff, false); break; case IRQ_STARTUP_ABORT: return 0; diff --git a/kernel/irq/cpuhotplug.c b/kernel/irq/cpuhotplug.c index 638eb9c83d9f..9eb09aef0313 100644 --- a/kernel/irq/cpuhotplug.c +++ b/kernel/irq/cpuhotplug.c @@ -18,8 +18,34 @@ static inline bool irq_needs_fixup(struct irq_data *d) { const struct cpumask *m = irq_data_get_effective_affinity_mask(d); + unsigned int cpu = smp_processor_id(); - return cpumask_test_cpu(smp_processor_id(), m); +#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK + /* +* The cpumask_empty() check is a workaround for interrupt chips, +* which do not implement effective affinity, but the architecture has +* enabled the config switch. Use the general affinity mask instead. +*/ + if (cpumask_empty(m)) + m = irq_data_get_affinity_mask(d); + + /* +* Sanity check. If the mask is not empty when excluding the outgoing +* CPU then it must contain at least one online CPU. The outgoing CPU +* has been removed from the online mask already. +*/ + if (cpumask_any_but(m, cpu) < nr_cpu_ids && + cpumask_any_and(m, cpu_online_mask) >= nr_cpu_ids) { + /* +* If this happens then there was a missed IRQ fixup at some +* point. Warn about it and enforce fixup. +*/ + pr_warn("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n", + cpumask_pr_args(m), d->irq, cpu); + return true; + } +#endif + return cpumask_test_cpu(cpu, m); } static bool migrate_one_irq(struct irq_desc *desc) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index d00132b5c325..4bff6a10ae8e 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -168,6 +168,19 @@ void irq_set_thread_affinity(struct irq_desc *desc) set_bit(IRQTF_AFFINITY, >thread_flags); } +static void irq_validate_effective_affinity(struct irq_data *data) +{ +#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK + const struct cpumask *m = irq_data_get_effective_affinity_mask(data); + struct irq_chip *chip = irq_data_get_irq_chip(data); + + if (!cpumask_empty(m)) + return; + pr_warn_once("irq_chip %s did not update eff. affinity mask of irq %u\n", +chip->name, data->irq); +#endif +} + int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { @@ -175,12 +188,16 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask, struct irq_chip *chip = irq_data_get_irq_chip(data); int ret; + if (!chip || !chip->irq_set_affinity) + return -EINVAL; + ret = chip->irq_set_affinity(data, mask, force); switch (ret) { case IRQ_SET_MASK_OK: case IRQ_SET_MASK_OK_DONE: cpumask_copy(desc->irq_common_data.affinity, mask); case IRQ_SET_MASK_OK_NOCOPY: + irq_validate_effective_affinity(data); irq_set_thread_affinity(desc); ret = 0; }
[GIT pull] irq fixes for 4.14
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus This pull request provides the following fixes: - Add a missing NULL pointer check in free_irq() - Fix a memory leak/memory corruption in the generic irq chip - Add missing rcu annotations for radix tree access - Use ffs instead of fls when extracting data from a chip register in the MIPS GIC irq driver - Fix the unmasking of IPI interrupts in the MIPS GIC driver so they end up at the target CPU and not at CPU0 Thanks, tglx --> Alexandru Moise (1): genirq: Check __free_irq() return value for NULL Jeffy Chen (1): irq/generic-chip: Don't replace domain's name Masahiro Yamada (1): irqdomain: Add __rcu annotations to radix tree accessors Paul Burton (2): irqchip/mips-gic: Fix shifts to extract register fields irqchip/mips-gic: Use effective affinity to unmask drivers/irqchip/irq-mips-gic.c | 13 - kernel/irq/generic-chip.c | 1 - kernel/irq/irqdomain.c | 4 ++-- kernel/irq/manage.c| 4 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 40159ac12ac8..c90976d7e53c 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -175,14 +175,13 @@ static void gic_mask_irq(struct irq_data *d) static void gic_unmask_irq(struct irq_data *d) { - struct cpumask *affinity = irq_data_get_affinity_mask(d); unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq); unsigned int cpu; write_gic_smask(intr); gic_clear_pcpu_masks(intr); - cpu = cpumask_first_and(affinity, cpu_online_mask); + cpu = cpumask_first(irq_data_get_effective_affinity_mask(d)); set_bit(intr, per_cpu_ptr(pcpu_masks, cpu)); } @@ -420,13 +419,17 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw, unsigned int cpu) { int intr = GIC_HWIRQ_TO_SHARED(hw); + struct irq_data *data; unsigned long flags; + data = irq_get_irq_data(virq); + spin_lock_irqsave(_lock, flags); write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin); write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu))); gic_clear_pcpu_masks(intr); set_bit(intr, per_cpu_ptr(pcpu_masks, cpu)); + irq_data_update_effective_affinity(data, cpumask_of(cpu)); spin_unlock_irqrestore(_lock, flags); return 0; @@ -645,7 +648,7 @@ static int __init gic_of_init(struct device_node *node, /* Find the first available CPU vector. */ i = 0; - reserved = (C_SW0 | C_SW1) >> __fls(C_SW0); + reserved = (C_SW0 | C_SW1) >> __ffs(C_SW0); while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors", i++, _vec)) reserved |= BIT(cpu_vec); @@ -684,11 +687,11 @@ static int __init gic_of_init(struct device_node *node, gicconfig = read_gic_config(); gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS; - gic_shared_intrs >>= __fls(GIC_CONFIG_NUMINTERRUPTS); + gic_shared_intrs >>= __ffs(GIC_CONFIG_NUMINTERRUPTS); gic_shared_intrs = (gic_shared_intrs + 1) * 8; gic_vpes = gicconfig & GIC_CONFIG_PVPS; - gic_vpes >>= __fls(GIC_CONFIG_PVPS); + gic_vpes >>= __ffs(GIC_CONFIG_PVPS); gic_vpes = gic_vpes + 1; if (cpu_has_veic) { diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c index f7086b78ad6e..5270a54b9fa4 100644 --- a/kernel/irq/generic-chip.c +++ b/kernel/irq/generic-chip.c @@ -322,7 +322,6 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip, /* Calc pointer to the next generic chip */ tmp += sizeof(*gc) + num_ct * sizeof(struct irq_chip_type); } - d->name = name; return 0; } EXPORT_SYMBOL_GPL(__irq_alloc_domain_generic_chips); diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index e84b7056bb08..ac4644e92b49 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -945,7 +945,7 @@ static int virq_debug_show(struct seq_file *m, void *private) struct irq_desc *desc; struct irq_domain *domain; struct radix_tree_iter iter; - void **slot; + void __rcu **slot; int i; seq_printf(m, " %-16s %-6s %-10s %-10s %s\n", @@ -1453,7 +1453,7 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, /* The irq_data was moved, fix the revmap to refer to the new location */ static void irq_domain_fix_revmap(struct irq_data *d) { - void **slot; + void __rcu **slot; if (d->hwirq < d->domain->revmap_size) return; /* Not
[GIT pull] irq fixes for 4.14
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus This pull request provides the following fixes: - Add a missing NULL pointer check in free_irq() - Fix a memory leak/memory corruption in the generic irq chip - Add missing rcu annotations for radix tree access - Use ffs instead of fls when extracting data from a chip register in the MIPS GIC irq driver - Fix the unmasking of IPI interrupts in the MIPS GIC driver so they end up at the target CPU and not at CPU0 Thanks, tglx --> Alexandru Moise (1): genirq: Check __free_irq() return value for NULL Jeffy Chen (1): irq/generic-chip: Don't replace domain's name Masahiro Yamada (1): irqdomain: Add __rcu annotations to radix tree accessors Paul Burton (2): irqchip/mips-gic: Fix shifts to extract register fields irqchip/mips-gic: Use effective affinity to unmask drivers/irqchip/irq-mips-gic.c | 13 - kernel/irq/generic-chip.c | 1 - kernel/irq/irqdomain.c | 4 ++-- kernel/irq/manage.c| 4 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 40159ac12ac8..c90976d7e53c 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -175,14 +175,13 @@ static void gic_mask_irq(struct irq_data *d) static void gic_unmask_irq(struct irq_data *d) { - struct cpumask *affinity = irq_data_get_affinity_mask(d); unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq); unsigned int cpu; write_gic_smask(intr); gic_clear_pcpu_masks(intr); - cpu = cpumask_first_and(affinity, cpu_online_mask); + cpu = cpumask_first(irq_data_get_effective_affinity_mask(d)); set_bit(intr, per_cpu_ptr(pcpu_masks, cpu)); } @@ -420,13 +419,17 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw, unsigned int cpu) { int intr = GIC_HWIRQ_TO_SHARED(hw); + struct irq_data *data; unsigned long flags; + data = irq_get_irq_data(virq); + spin_lock_irqsave(_lock, flags); write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin); write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu))); gic_clear_pcpu_masks(intr); set_bit(intr, per_cpu_ptr(pcpu_masks, cpu)); + irq_data_update_effective_affinity(data, cpumask_of(cpu)); spin_unlock_irqrestore(_lock, flags); return 0; @@ -645,7 +648,7 @@ static int __init gic_of_init(struct device_node *node, /* Find the first available CPU vector. */ i = 0; - reserved = (C_SW0 | C_SW1) >> __fls(C_SW0); + reserved = (C_SW0 | C_SW1) >> __ffs(C_SW0); while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors", i++, _vec)) reserved |= BIT(cpu_vec); @@ -684,11 +687,11 @@ static int __init gic_of_init(struct device_node *node, gicconfig = read_gic_config(); gic_shared_intrs = gicconfig & GIC_CONFIG_NUMINTERRUPTS; - gic_shared_intrs >>= __fls(GIC_CONFIG_NUMINTERRUPTS); + gic_shared_intrs >>= __ffs(GIC_CONFIG_NUMINTERRUPTS); gic_shared_intrs = (gic_shared_intrs + 1) * 8; gic_vpes = gicconfig & GIC_CONFIG_PVPS; - gic_vpes >>= __fls(GIC_CONFIG_PVPS); + gic_vpes >>= __ffs(GIC_CONFIG_PVPS); gic_vpes = gic_vpes + 1; if (cpu_has_veic) { diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c index f7086b78ad6e..5270a54b9fa4 100644 --- a/kernel/irq/generic-chip.c +++ b/kernel/irq/generic-chip.c @@ -322,7 +322,6 @@ int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip, /* Calc pointer to the next generic chip */ tmp += sizeof(*gc) + num_ct * sizeof(struct irq_chip_type); } - d->name = name; return 0; } EXPORT_SYMBOL_GPL(__irq_alloc_domain_generic_chips); diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index e84b7056bb08..ac4644e92b49 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -945,7 +945,7 @@ static int virq_debug_show(struct seq_file *m, void *private) struct irq_desc *desc; struct irq_domain *domain; struct radix_tree_iter iter; - void **slot; + void __rcu **slot; int i; seq_printf(m, " %-16s %-6s %-10s %-10s %s\n", @@ -1453,7 +1453,7 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, /* The irq_data was moved, fix the revmap to refer to the new location */ static void irq_domain_fix_revmap(struct irq_data *d) { - void **slot; + void __rcu **slot; if (d->hwirq < d->domain->revmap_size) return; /* Not
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: cf00ab842eec7cd4923a3f0f3b5ddcead9b11306 Merge tag 'irqchip-4.14-2' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent Three irqchip driver fixes, and an affinity mask helper function bug fix affecting x86. Thanks, Ingo --> Arnd Bergmann (1): irqchip/gic-v4: Fix building with ancient gcc Paul Burton (1): irqchip.mips-gic: Fix shared interrupt mask writes Thomas Gleixner (1): Revert "genirq: Restrict effective affinity to interrupts actually using it" zijun_hu (1): irqchip/gic-v3: Iterate over possible CPUs by for_each_possible_cpu() drivers/irqchip/irq-gic-v3.c | 8 drivers/irqchip/irq-gic-v4.c | 12 +--- drivers/irqchip/irq-mips-gic.c | 6 +++--- include/linux/irq.h| 5 + 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 519149ec9053..b5df99c6f680 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1042,7 +1042,7 @@ static int get_cpu_number(struct device_node *dn) { const __be32 *cell; u64 hwid; - int i; + int cpu; cell = of_get_property(dn, "reg", NULL); if (!cell) @@ -1056,9 +1056,9 @@ static int get_cpu_number(struct device_node *dn) if (hwid & ~MPIDR_HWID_BITMASK) return -1; - for (i = 0; i < num_possible_cpus(); i++) - if (cpu_logical_map(i) == hwid) - return i; + for_each_possible_cpu(cpu) + if (cpu_logical_map(cpu) == hwid) + return cpu; return -1; } diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c index 2370e6d9e603..cd0bcc3b7e33 100644 --- a/drivers/irqchip/irq-gic-v4.c +++ b/drivers/irqchip/irq-gic-v4.c @@ -173,7 +173,9 @@ int its_map_vlpi(int irq, struct its_vlpi_map *map) { struct its_cmd_info info = { .cmd_type = MAP_VLPI, - .map = map, + { + .map = map, + }, }; /* @@ -189,7 +191,9 @@ int its_get_vlpi(int irq, struct its_vlpi_map *map) { struct its_cmd_info info = { .cmd_type = GET_VLPI, - .map = map, + { + .map = map, + }, }; return irq_set_vcpu_affinity(irq, ); @@ -205,7 +209,9 @@ int its_prop_update_vlpi(int irq, u8 config, bool inv) { struct its_cmd_info info = { .cmd_type = inv ? PROP_UPDATE_AND_INV_VLPI : PROP_UPDATE_VLPI, - .config = config, + { + .config = config, + }, }; return irq_set_vcpu_affinity(irq, ); diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 6e52a88bbd9e..40159ac12ac8 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -169,7 +169,7 @@ static void gic_mask_irq(struct irq_data *d) { unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq); - write_gic_rmask(BIT(intr)); + write_gic_rmask(intr); gic_clear_pcpu_masks(intr); } @@ -179,7 +179,7 @@ static void gic_unmask_irq(struct irq_data *d) unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq); unsigned int cpu; - write_gic_smask(BIT(intr)); + write_gic_smask(intr); gic_clear_pcpu_masks(intr); cpu = cpumask_first_and(affinity, cpu_online_mask); @@ -767,7 +767,7 @@ static int __init gic_of_init(struct device_node *node, for (i = 0; i < gic_shared_intrs; i++) { change_gic_pol(i, GIC_POL_ACTIVE_HIGH); change_gic_trig(i, GIC_TRIG_LEVEL); - write_gic_rmask(BIT(i)); + write_gic_rmask(i); } for (i = 0; i < gic_vpes; i++) { diff --git a/include/linux/irq.h b/include/linux/irq.h index b99a784635ff..d4728bf6a537 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -783,10 +783,7 @@ static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d) static inline struct cpumask *irq_data_get_effective_affinity_mask(struct irq_data *d) { - if (!cpumask_empty(d->common->effective_affinity)) - return d->common->effective_affinity; - - return d->common->affinity; + return d->common->effective_affinity; } static inline void irq_data_update_effective_affinity(struct irq_data *d, const struct cpumask *m)
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: cf00ab842eec7cd4923a3f0f3b5ddcead9b11306 Merge tag 'irqchip-4.14-2' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent Three irqchip driver fixes, and an affinity mask helper function bug fix affecting x86. Thanks, Ingo --> Arnd Bergmann (1): irqchip/gic-v4: Fix building with ancient gcc Paul Burton (1): irqchip.mips-gic: Fix shared interrupt mask writes Thomas Gleixner (1): Revert "genirq: Restrict effective affinity to interrupts actually using it" zijun_hu (1): irqchip/gic-v3: Iterate over possible CPUs by for_each_possible_cpu() drivers/irqchip/irq-gic-v3.c | 8 drivers/irqchip/irq-gic-v4.c | 12 +--- drivers/irqchip/irq-mips-gic.c | 6 +++--- include/linux/irq.h| 5 + 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 519149ec9053..b5df99c6f680 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1042,7 +1042,7 @@ static int get_cpu_number(struct device_node *dn) { const __be32 *cell; u64 hwid; - int i; + int cpu; cell = of_get_property(dn, "reg", NULL); if (!cell) @@ -1056,9 +1056,9 @@ static int get_cpu_number(struct device_node *dn) if (hwid & ~MPIDR_HWID_BITMASK) return -1; - for (i = 0; i < num_possible_cpus(); i++) - if (cpu_logical_map(i) == hwid) - return i; + for_each_possible_cpu(cpu) + if (cpu_logical_map(cpu) == hwid) + return cpu; return -1; } diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c index 2370e6d9e603..cd0bcc3b7e33 100644 --- a/drivers/irqchip/irq-gic-v4.c +++ b/drivers/irqchip/irq-gic-v4.c @@ -173,7 +173,9 @@ int its_map_vlpi(int irq, struct its_vlpi_map *map) { struct its_cmd_info info = { .cmd_type = MAP_VLPI, - .map = map, + { + .map = map, + }, }; /* @@ -189,7 +191,9 @@ int its_get_vlpi(int irq, struct its_vlpi_map *map) { struct its_cmd_info info = { .cmd_type = GET_VLPI, - .map = map, + { + .map = map, + }, }; return irq_set_vcpu_affinity(irq, ); @@ -205,7 +209,9 @@ int its_prop_update_vlpi(int irq, u8 config, bool inv) { struct its_cmd_info info = { .cmd_type = inv ? PROP_UPDATE_AND_INV_VLPI : PROP_UPDATE_VLPI, - .config = config, + { + .config = config, + }, }; return irq_set_vcpu_affinity(irq, ); diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 6e52a88bbd9e..40159ac12ac8 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -169,7 +169,7 @@ static void gic_mask_irq(struct irq_data *d) { unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq); - write_gic_rmask(BIT(intr)); + write_gic_rmask(intr); gic_clear_pcpu_masks(intr); } @@ -179,7 +179,7 @@ static void gic_unmask_irq(struct irq_data *d) unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq); unsigned int cpu; - write_gic_smask(BIT(intr)); + write_gic_smask(intr); gic_clear_pcpu_masks(intr); cpu = cpumask_first_and(affinity, cpu_online_mask); @@ -767,7 +767,7 @@ static int __init gic_of_init(struct device_node *node, for (i = 0; i < gic_shared_intrs; i++) { change_gic_pol(i, GIC_POL_ACTIVE_HIGH); change_gic_trig(i, GIC_TRIG_LEVEL); - write_gic_rmask(BIT(i)); + write_gic_rmask(i); } for (i = 0; i < gic_vpes; i++) { diff --git a/include/linux/irq.h b/include/linux/irq.h index b99a784635ff..d4728bf6a537 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -783,10 +783,7 @@ static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d) static inline struct cpumask *irq_data_get_effective_affinity_mask(struct irq_data *d) { - if (!cpumask_empty(d->common->effective_affinity)) - return d->common->effective_affinity; - - return d->common->affinity; + return d->common->effective_affinity; } static inline void irq_data_update_effective_affinity(struct irq_data *d, const struct cpumask *m)
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 12ac1d0f6c3e95732d144ffa65c8b20fbd9aa462 genirq: Make sparse_irq_lock protect what it should protect A sparse irq race/locking fix, and a MSI irq domains population fix. Thanks, Ingo --> John Keeping (1): genirq/msi: Fix populating multiple interrupts Thomas Gleixner (1): genirq: Make sparse_irq_lock protect what it should protect kernel/irq/irqdesc.c | 24 +++- kernel/irq/msi.c | 5 +++-- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 73be2b3909bd..82afb7ed369f 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -421,10 +421,8 @@ static void free_desc(unsigned int irq) * The sysfs entry must be serialized against a concurrent * irq_sysfs_init() as well. */ - mutex_lock(_irq_lock); kobject_del(>kobj); delete_irq_desc(irq); - mutex_unlock(_irq_lock); /* * We free the descriptor, masks and stat fields via RCU. That @@ -462,20 +460,15 @@ static int alloc_descs(unsigned int start, unsigned int cnt, int node, desc = alloc_desc(start + i, node, flags, mask, owner); if (!desc) goto err; - mutex_lock(_irq_lock); irq_insert_desc(start + i, desc); irq_sysfs_add(start + i, desc); - mutex_unlock(_irq_lock); } + bitmap_set(allocated_irqs, start, cnt); return start; err: for (i--; i >= 0; i--) free_desc(start + i); - - mutex_lock(_irq_lock); - bitmap_clear(allocated_irqs, start, cnt); - mutex_unlock(_irq_lock); return -ENOMEM; } @@ -575,6 +568,7 @@ static inline int alloc_descs(unsigned int start, unsigned int cnt, int node, desc->owner = owner; } + bitmap_set(allocated_irqs, start, cnt); return start; } @@ -670,10 +664,10 @@ void irq_free_descs(unsigned int from, unsigned int cnt) if (from >= nr_irqs || (from + cnt) > nr_irqs) return; + mutex_lock(_irq_lock); for (i = 0; i < cnt; i++) free_desc(from + i); - mutex_lock(_irq_lock); bitmap_clear(allocated_irqs, from, cnt); mutex_unlock(_irq_lock); } @@ -720,19 +714,15 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, from, cnt, 0); ret = -EEXIST; if (irq >=0 && start != irq) - goto err; + goto unlock; if (start + cnt > nr_irqs) { ret = irq_expand_nr_irqs(start + cnt); if (ret) - goto err; + goto unlock; } - - bitmap_set(allocated_irqs, start, cnt); - mutex_unlock(_irq_lock); - return alloc_descs(start, cnt, node, affinity, owner); - -err: + ret = alloc_descs(start, cnt, node, affinity, owner); +unlock: mutex_unlock(_irq_lock); return ret; } diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index 48eadf416c24..3fa4bd59f569 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -315,11 +315,12 @@ int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev, ops->set_desc(arg, desc); /* Assumes the domain mutex is held! */ - ret = irq_domain_alloc_irqs_hierarchy(domain, virq, 1, arg); + ret = irq_domain_alloc_irqs_hierarchy(domain, desc->irq, 1, + arg); if (ret) break; - irq_set_msi_desc_off(virq, 0, desc); + irq_set_msi_desc_off(desc->irq, 0, desc); } if (ret) {
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 12ac1d0f6c3e95732d144ffa65c8b20fbd9aa462 genirq: Make sparse_irq_lock protect what it should protect A sparse irq race/locking fix, and a MSI irq domains population fix. Thanks, Ingo --> John Keeping (1): genirq/msi: Fix populating multiple interrupts Thomas Gleixner (1): genirq: Make sparse_irq_lock protect what it should protect kernel/irq/irqdesc.c | 24 +++- kernel/irq/msi.c | 5 +++-- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 73be2b3909bd..82afb7ed369f 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -421,10 +421,8 @@ static void free_desc(unsigned int irq) * The sysfs entry must be serialized against a concurrent * irq_sysfs_init() as well. */ - mutex_lock(_irq_lock); kobject_del(>kobj); delete_irq_desc(irq); - mutex_unlock(_irq_lock); /* * We free the descriptor, masks and stat fields via RCU. That @@ -462,20 +460,15 @@ static int alloc_descs(unsigned int start, unsigned int cnt, int node, desc = alloc_desc(start + i, node, flags, mask, owner); if (!desc) goto err; - mutex_lock(_irq_lock); irq_insert_desc(start + i, desc); irq_sysfs_add(start + i, desc); - mutex_unlock(_irq_lock); } + bitmap_set(allocated_irqs, start, cnt); return start; err: for (i--; i >= 0; i--) free_desc(start + i); - - mutex_lock(_irq_lock); - bitmap_clear(allocated_irqs, start, cnt); - mutex_unlock(_irq_lock); return -ENOMEM; } @@ -575,6 +568,7 @@ static inline int alloc_descs(unsigned int start, unsigned int cnt, int node, desc->owner = owner; } + bitmap_set(allocated_irqs, start, cnt); return start; } @@ -670,10 +664,10 @@ void irq_free_descs(unsigned int from, unsigned int cnt) if (from >= nr_irqs || (from + cnt) > nr_irqs) return; + mutex_lock(_irq_lock); for (i = 0; i < cnt; i++) free_desc(from + i); - mutex_lock(_irq_lock); bitmap_clear(allocated_irqs, from, cnt); mutex_unlock(_irq_lock); } @@ -720,19 +714,15 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, from, cnt, 0); ret = -EEXIST; if (irq >=0 && start != irq) - goto err; + goto unlock; if (start + cnt > nr_irqs) { ret = irq_expand_nr_irqs(start + cnt); if (ret) - goto err; + goto unlock; } - - bitmap_set(allocated_irqs, start, cnt); - mutex_unlock(_irq_lock); - return alloc_descs(start, cnt, node, affinity, owner); - -err: + ret = alloc_descs(start, cnt, node, affinity, owner); +unlock: mutex_unlock(_irq_lock); return ret; } diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index 48eadf416c24..3fa4bd59f569 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -315,11 +315,12 @@ int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev, ops->set_desc(arg, desc); /* Assumes the domain mutex is held! */ - ret = irq_domain_alloc_irqs_hierarchy(domain, virq, 1, arg); + ret = irq_domain_alloc_irqs_hierarchy(domain, desc->irq, 1, + arg); if (ret) break; - irq_set_msi_desc_off(virq, 0, desc); + irq_set_msi_desc_off(desc->irq, 0, desc); } if (ret) {
[GIT pull] irq fixes for 4.13
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A pile of smallish changes all over the place: - Add a missing ISB in the GIC V1 driver - Remove an ACPI version check in the GIC V3 ITS driver - Add the missing irq_pm_shutdown function for BRCMSTB-L2 to avoid spurious wakeups - Remove the artifical limitation of ITS instances to the number of NUMA nodes which prevents utilizing the ITS hardware correctly - Prevent a infinite parsing loop in the GIC-V3 ITS/MSI code - Honour the force affinity argument in the GIC-V3 driver which is required to make perf work correctly - Correctly report allocation failures in GIC-V2/V3 to avoid using half allocated and initialized interrupts. - Fixup checks against nr_cpu_ids in the generic IPI code Thanks, tglx --> Alexey Dobriyan (1): genirq/ipi: Fixup checks against nr_cpu_ids Boris Brezillon (3): irqchip/atmel-aic: Fix unbalanced of_node_put() in aic_common_irq_fixup() irqchip/atmel-aic: Fix unbalanced refcount in aic_common_rtc_irq_fixup() irqchip/atmel-aic: Remove root argument from ->fixup() prototype Florian Fainelli (2): irqchip: brcmstb-l2: Define an irq_pm_shutdown function MAINTAINERS: Remove Jason Cooper's irqchip git tree Hanjun Guo (1): irqchip/gic-v3-its: Allow GIC ITS number more than MAX_NUMNODES Lorenzo Pieralisi (1): irqchip/gic-v3-its-platform-msi: Fix msi-parent parsing loop Marc Zyngier (1): genirq: Restore trigger settings in irq_modify_status() Robert Richter (1): irqchip/gic-v3-its: Remove ACPICA version check for ACPI NUMA Suzuki K Poulose (3): irqchip/gic-v2: Report failures in gic_irq_domain_alloc irqchip/gic-v3: Report failures in gic_irq_domain_alloc irqchip/gic-v3: Honor forced affinity setting Will Deacon (1): irqchip/gic: Ensure we have an ISB between ack and ->handle_irq MAINTAINERS | 1 - drivers/irqchip/irq-atmel-aic-common.c| 13 - drivers/irqchip/irq-atmel-aic-common.h| 4 +-- drivers/irqchip/irq-atmel-aic.c | 14 +- drivers/irqchip/irq-atmel-aic5.c | 4 +-- drivers/irqchip/irq-brcmstb-l2.c | 1 + drivers/irqchip/irq-gic-v3-its-platform-msi.c | 1 + drivers/irqchip/irq-gic-v3-its.c | 40 +-- drivers/irqchip/irq-gic-v3.c | 16 +-- drivers/irqchip/irq-gic.c | 14 +++--- kernel/irq/chip.c | 10 +-- kernel/irq/ipi.c | 4 +-- 12 files changed, 84 insertions(+), 38 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f66488dfdbc9..b116efa1a087 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7102,7 +7102,6 @@ M:Marc ZyngierL: linux-kernel@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core -T: git git://git.infradead.org/users/jcooper/linux.git irqchip/core F: Documentation/devicetree/bindings/interrupt-controller/ F: drivers/irqchip/ diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c index 28b26c80f4cf..072bd227b6c6 100644 --- a/drivers/irqchip/irq-atmel-aic-common.c +++ b/drivers/irqchip/irq-atmel-aic-common.c @@ -137,14 +137,14 @@ static void __init aic_common_ext_irq_of_init(struct irq_domain *domain) #define AT91_RTC_IMR 0x28 #define AT91_RTC_IRQ_MASK 0x1f -void __init aic_common_rtc_irq_fixup(struct device_node *root) +void __init aic_common_rtc_irq_fixup(void) { struct device_node *np; void __iomem *regs; - np = of_find_compatible_node(root, NULL, "atmel,at91rm9200-rtc"); + np = of_find_compatible_node(NULL, NULL, "atmel,at91rm9200-rtc"); if (!np) - np = of_find_compatible_node(root, NULL, + np = of_find_compatible_node(NULL, NULL, "atmel,at91sam9x5-rtc"); if (!np) @@ -165,7 +165,7 @@ void __init aic_common_rtc_irq_fixup(struct device_node *root) #define AT91_RTT_ALMIEN(1 << 16) /* Alarm Interrupt Enable */ #define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */ -void __init aic_common_rtt_irq_fixup(struct device_node *root) +void __init aic_common_rtt_irq_fixup(void) { struct device_node *np; void __iomem *regs; @@ -196,11 +196,10 @@ static void __init aic_common_irq_fixup(const struct of_device_id *matches) return; match = of_match_node(matches, root); - of_node_put(root); if (match) { - void (*fixup)(struct device_node *) = match->data; -
[GIT pull] irq fixes for 4.13
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A pile of smallish changes all over the place: - Add a missing ISB in the GIC V1 driver - Remove an ACPI version check in the GIC V3 ITS driver - Add the missing irq_pm_shutdown function for BRCMSTB-L2 to avoid spurious wakeups - Remove the artifical limitation of ITS instances to the number of NUMA nodes which prevents utilizing the ITS hardware correctly - Prevent a infinite parsing loop in the GIC-V3 ITS/MSI code - Honour the force affinity argument in the GIC-V3 driver which is required to make perf work correctly - Correctly report allocation failures in GIC-V2/V3 to avoid using half allocated and initialized interrupts. - Fixup checks against nr_cpu_ids in the generic IPI code Thanks, tglx --> Alexey Dobriyan (1): genirq/ipi: Fixup checks against nr_cpu_ids Boris Brezillon (3): irqchip/atmel-aic: Fix unbalanced of_node_put() in aic_common_irq_fixup() irqchip/atmel-aic: Fix unbalanced refcount in aic_common_rtc_irq_fixup() irqchip/atmel-aic: Remove root argument from ->fixup() prototype Florian Fainelli (2): irqchip: brcmstb-l2: Define an irq_pm_shutdown function MAINTAINERS: Remove Jason Cooper's irqchip git tree Hanjun Guo (1): irqchip/gic-v3-its: Allow GIC ITS number more than MAX_NUMNODES Lorenzo Pieralisi (1): irqchip/gic-v3-its-platform-msi: Fix msi-parent parsing loop Marc Zyngier (1): genirq: Restore trigger settings in irq_modify_status() Robert Richter (1): irqchip/gic-v3-its: Remove ACPICA version check for ACPI NUMA Suzuki K Poulose (3): irqchip/gic-v2: Report failures in gic_irq_domain_alloc irqchip/gic-v3: Report failures in gic_irq_domain_alloc irqchip/gic-v3: Honor forced affinity setting Will Deacon (1): irqchip/gic: Ensure we have an ISB between ack and ->handle_irq MAINTAINERS | 1 - drivers/irqchip/irq-atmel-aic-common.c| 13 - drivers/irqchip/irq-atmel-aic-common.h| 4 +-- drivers/irqchip/irq-atmel-aic.c | 14 +- drivers/irqchip/irq-atmel-aic5.c | 4 +-- drivers/irqchip/irq-brcmstb-l2.c | 1 + drivers/irqchip/irq-gic-v3-its-platform-msi.c | 1 + drivers/irqchip/irq-gic-v3-its.c | 40 +-- drivers/irqchip/irq-gic-v3.c | 16 +-- drivers/irqchip/irq-gic.c | 14 +++--- kernel/irq/chip.c | 10 +-- kernel/irq/ipi.c | 4 +-- 12 files changed, 84 insertions(+), 38 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f66488dfdbc9..b116efa1a087 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7102,7 +7102,6 @@ M:Marc Zyngier L: linux-kernel@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core -T: git git://git.infradead.org/users/jcooper/linux.git irqchip/core F: Documentation/devicetree/bindings/interrupt-controller/ F: drivers/irqchip/ diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c index 28b26c80f4cf..072bd227b6c6 100644 --- a/drivers/irqchip/irq-atmel-aic-common.c +++ b/drivers/irqchip/irq-atmel-aic-common.c @@ -137,14 +137,14 @@ static void __init aic_common_ext_irq_of_init(struct irq_domain *domain) #define AT91_RTC_IMR 0x28 #define AT91_RTC_IRQ_MASK 0x1f -void __init aic_common_rtc_irq_fixup(struct device_node *root) +void __init aic_common_rtc_irq_fixup(void) { struct device_node *np; void __iomem *regs; - np = of_find_compatible_node(root, NULL, "atmel,at91rm9200-rtc"); + np = of_find_compatible_node(NULL, NULL, "atmel,at91rm9200-rtc"); if (!np) - np = of_find_compatible_node(root, NULL, + np = of_find_compatible_node(NULL, NULL, "atmel,at91sam9x5-rtc"); if (!np) @@ -165,7 +165,7 @@ void __init aic_common_rtc_irq_fixup(struct device_node *root) #define AT91_RTT_ALMIEN(1 << 16) /* Alarm Interrupt Enable */ #define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */ -void __init aic_common_rtt_irq_fixup(struct device_node *root) +void __init aic_common_rtt_irq_fixup(void) { struct device_node *np; void __iomem *regs; @@ -196,11 +196,10 @@ static void __init aic_common_irq_fixup(const struct of_device_id *matches) return; match = of_match_node(matches, root); - of_node_put(root); if (match) { - void (*fixup)(struct device_node *) = match->data; - fixup(root); +
[GIT PULL] irq fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: acc80c39929b9f2ff8b45fcfe103385a3e45c1a7 irqchip/digicolor: Drop unnecessary static A resume_irq() fix, plus a number of static declaration fixes. Thanks, Ingo --> Juergen Gross (1): genirq/PM: Properly pretend disabled state when force resuming interrupts Julia Lawall (3): irqchip/gic/realview: Drop unnecessary static irqchip/mips-cpu: Drop unnecessary static irqchip/digicolor: Drop unnecessary static Matt Redfearn (1): irqchip/mips-gic: Remove population of irq domain names drivers/irqchip/irq-digicolor.c| 2 +- drivers/irqchip/irq-gic-realview.c | 2 +- drivers/irqchip/irq-mips-cpu.c | 2 +- drivers/irqchip/irq-mips-gic.c | 2 -- kernel/irq/chip.c | 10 -- kernel/irq/internals.h | 10 ++ kernel/irq/pm.c| 2 ++ 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/irqchip/irq-digicolor.c b/drivers/irqchip/irq-digicolor.c index dad85e74c37c..3aae015469a5 100644 --- a/drivers/irqchip/irq-digicolor.c +++ b/drivers/irqchip/irq-digicolor.c @@ -71,7 +71,7 @@ static void __init digicolor_set_gc(void __iomem *reg_base, unsigned irq_base, static int __init digicolor_of_init(struct device_node *node, struct device_node *parent) { - static void __iomem *reg_base; + void __iomem *reg_base; unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; struct regmap *ucregs; int ret; diff --git a/drivers/irqchip/irq-gic-realview.c b/drivers/irqchip/irq-gic-realview.c index 54c296401525..18d58d2b4ffe 100644 --- a/drivers/irqchip/irq-gic-realview.c +++ b/drivers/irqchip/irq-gic-realview.c @@ -43,7 +43,7 @@ static const struct of_device_id syscon_pldset_of_match[] = { static int __init realview_gic_of_init(struct device_node *node, struct device_node *parent) { - static struct regmap *map; + struct regmap *map; struct device_node *np; const struct of_device_id *gic_id; u32 pld1_ctrl; diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c index 0a8ed1c05518..14461cbfab2f 100644 --- a/drivers/irqchip/irq-mips-cpu.c +++ b/drivers/irqchip/irq-mips-cpu.c @@ -154,7 +154,7 @@ asmlinkage void __weak plat_irq_dispatch(void) static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { - static struct irq_chip *chip; + struct irq_chip *chip; if (hw < 2 && cpu_has_mipsmt) { /* Software interrupts are used for MT/CMT IPI */ diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 832ebf4062f7..6ab1d3afec02 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -950,7 +950,6 @@ static void __init __gic_init(unsigned long gic_base_addr, _irq_domain_ops, NULL); if (!gic_irq_domain) panic("Failed to add GIC IRQ domain"); - gic_irq_domain->name = "mips-gic-irq"; gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain, IRQ_DOMAIN_FLAG_IPI_PER_CPU, @@ -959,7 +958,6 @@ static void __init __gic_init(unsigned long gic_base_addr, if (!gic_ipi_domain) panic("Failed to add GIC IPI domain"); - gic_ipi_domain->name = "mips-gic-ipi"; irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI); if (node && diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index d171bc57e1e0..a3cc37c0c85e 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -170,21 +170,11 @@ static void irq_state_clr_disabled(struct irq_desc *desc) irqd_clear(>irq_data, IRQD_IRQ_DISABLED); } -static void irq_state_set_disabled(struct irq_desc *desc) -{ - irqd_set(>irq_data, IRQD_IRQ_DISABLED); -} - static void irq_state_clr_masked(struct irq_desc *desc) { irqd_clear(>irq_data, IRQD_IRQ_MASKED); } -static void irq_state_set_masked(struct irq_desc *desc) -{ - irqd_set(>irq_data, IRQD_IRQ_MASKED); -} - static void irq_state_clr_started(struct irq_desc *desc) { irqd_clear(>irq_data, IRQD_IRQ_STARTED); diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index dbfba9933ed2..a2c48058354c 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h @@ -227,6 +227,16 @@ static inline bool irqd_has_set(struct irq_data *d, unsigned int mask) return __irqd_to_state(d) & mask; } +static inline void irq_state_set_disabled(struct irq_desc *desc) +{ + irqd_set(>irq_data, IRQD_IRQ_DISABLED); +} + +static inline void irq_state_set_masked(struct irq_desc *desc) +{ + irqd_set(>irq_data, IRQD_IRQ_MASKED); +} + #undef
[GIT PULL] irq fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: acc80c39929b9f2ff8b45fcfe103385a3e45c1a7 irqchip/digicolor: Drop unnecessary static A resume_irq() fix, plus a number of static declaration fixes. Thanks, Ingo --> Juergen Gross (1): genirq/PM: Properly pretend disabled state when force resuming interrupts Julia Lawall (3): irqchip/gic/realview: Drop unnecessary static irqchip/mips-cpu: Drop unnecessary static irqchip/digicolor: Drop unnecessary static Matt Redfearn (1): irqchip/mips-gic: Remove population of irq domain names drivers/irqchip/irq-digicolor.c| 2 +- drivers/irqchip/irq-gic-realview.c | 2 +- drivers/irqchip/irq-mips-cpu.c | 2 +- drivers/irqchip/irq-mips-gic.c | 2 -- kernel/irq/chip.c | 10 -- kernel/irq/internals.h | 10 ++ kernel/irq/pm.c| 2 ++ 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/irqchip/irq-digicolor.c b/drivers/irqchip/irq-digicolor.c index dad85e74c37c..3aae015469a5 100644 --- a/drivers/irqchip/irq-digicolor.c +++ b/drivers/irqchip/irq-digicolor.c @@ -71,7 +71,7 @@ static void __init digicolor_set_gc(void __iomem *reg_base, unsigned irq_base, static int __init digicolor_of_init(struct device_node *node, struct device_node *parent) { - static void __iomem *reg_base; + void __iomem *reg_base; unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; struct regmap *ucregs; int ret; diff --git a/drivers/irqchip/irq-gic-realview.c b/drivers/irqchip/irq-gic-realview.c index 54c296401525..18d58d2b4ffe 100644 --- a/drivers/irqchip/irq-gic-realview.c +++ b/drivers/irqchip/irq-gic-realview.c @@ -43,7 +43,7 @@ static const struct of_device_id syscon_pldset_of_match[] = { static int __init realview_gic_of_init(struct device_node *node, struct device_node *parent) { - static struct regmap *map; + struct regmap *map; struct device_node *np; const struct of_device_id *gic_id; u32 pld1_ctrl; diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c index 0a8ed1c05518..14461cbfab2f 100644 --- a/drivers/irqchip/irq-mips-cpu.c +++ b/drivers/irqchip/irq-mips-cpu.c @@ -154,7 +154,7 @@ asmlinkage void __weak plat_irq_dispatch(void) static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { - static struct irq_chip *chip; + struct irq_chip *chip; if (hw < 2 && cpu_has_mipsmt) { /* Software interrupts are used for MT/CMT IPI */ diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 832ebf4062f7..6ab1d3afec02 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -950,7 +950,6 @@ static void __init __gic_init(unsigned long gic_base_addr, _irq_domain_ops, NULL); if (!gic_irq_domain) panic("Failed to add GIC IRQ domain"); - gic_irq_domain->name = "mips-gic-irq"; gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain, IRQ_DOMAIN_FLAG_IPI_PER_CPU, @@ -959,7 +958,6 @@ static void __init __gic_init(unsigned long gic_base_addr, if (!gic_ipi_domain) panic("Failed to add GIC IPI domain"); - gic_ipi_domain->name = "mips-gic-ipi"; irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI); if (node && diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index d171bc57e1e0..a3cc37c0c85e 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -170,21 +170,11 @@ static void irq_state_clr_disabled(struct irq_desc *desc) irqd_clear(>irq_data, IRQD_IRQ_DISABLED); } -static void irq_state_set_disabled(struct irq_desc *desc) -{ - irqd_set(>irq_data, IRQD_IRQ_DISABLED); -} - static void irq_state_clr_masked(struct irq_desc *desc) { irqd_clear(>irq_data, IRQD_IRQ_MASKED); } -static void irq_state_set_masked(struct irq_desc *desc) -{ - irqd_set(>irq_data, IRQD_IRQ_MASKED); -} - static void irq_state_clr_started(struct irq_desc *desc) { irqd_clear(>irq_data, IRQD_IRQ_STARTED); diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index dbfba9933ed2..a2c48058354c 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h @@ -227,6 +227,16 @@ static inline bool irqd_has_set(struct irq_data *d, unsigned int mask) return __irqd_to_state(d) & mask; } +static inline void irq_state_set_disabled(struct irq_desc *desc) +{ + irqd_set(>irq_data, IRQD_IRQ_DISABLED); +} + +static inline void irq_state_set_masked(struct irq_desc *desc) +{ + irqd_set(>irq_data, IRQD_IRQ_MASKED); +} + #undef
[GIT pull] irq fixes for 4.12
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A set of small fixes for the irq subsystem: - Cure a data ordering problem with chained interrupts - Three small fixlets for the mbigen irq chip Thanks, tglx --> Hanjun Guo (2): irqchip/mbigen: Fix memory mapping code irqchip/mbigen: Fix potential NULL dereferencing MaJun (1): irqchip/mbigen: Fix the clear register offset calculation Thomas Gleixner (1): genirq: Fix chained interrupt data ordering drivers/irqchip/irq-mbigen.c | 17 ++--- kernel/irq/chip.c| 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c index d2306c821ebb..31d6b5a582d2 100644 --- a/drivers/irqchip/irq-mbigen.c +++ b/drivers/irqchip/irq-mbigen.c @@ -106,10 +106,7 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq, static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq, u32 *mask, u32 *addr) { - unsigned int ofst; - - hwirq -= RESERVED_IRQ_PER_MBIGEN_CHIP; - ofst = hwirq / 32 * 4; + unsigned int ofst = (hwirq / 32) * 4; *mask = 1 << (hwirq % 32); *addr = ofst + REG_MBIGEN_CLEAR_OFFSET; @@ -337,9 +334,15 @@ static int mbigen_device_probe(struct platform_device *pdev) mgn_chip->pdev = pdev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mgn_chip->base = devm_ioremap_resource(>dev, res); - if (IS_ERR(mgn_chip->base)) - return PTR_ERR(mgn_chip->base); + if (!res) + return -EINVAL; + + mgn_chip->base = devm_ioremap(>dev, res->start, + resource_size(res)); + if (!mgn_chip->base) { + dev_err(>dev, "failed to ioremap %pR\n", res); + return -ENOMEM; + } if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) err = mbigen_of_create_domain(pdev, mgn_chip); diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 686be4b73018..c94da688ee9b 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -880,8 +880,8 @@ irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle, if (!desc) return; - __irq_do_set_handler(desc, handle, 1, NULL); desc->irq_common_data.handler_data = data; + __irq_do_set_handler(desc, handle, 1, NULL); irq_put_desc_busunlock(desc, flags); }
[GIT pull] irq fixes for 4.12
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A set of small fixes for the irq subsystem: - Cure a data ordering problem with chained interrupts - Three small fixlets for the mbigen irq chip Thanks, tglx --> Hanjun Guo (2): irqchip/mbigen: Fix memory mapping code irqchip/mbigen: Fix potential NULL dereferencing MaJun (1): irqchip/mbigen: Fix the clear register offset calculation Thomas Gleixner (1): genirq: Fix chained interrupt data ordering drivers/irqchip/irq-mbigen.c | 17 ++--- kernel/irq/chip.c| 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c index d2306c821ebb..31d6b5a582d2 100644 --- a/drivers/irqchip/irq-mbigen.c +++ b/drivers/irqchip/irq-mbigen.c @@ -106,10 +106,7 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq, static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq, u32 *mask, u32 *addr) { - unsigned int ofst; - - hwirq -= RESERVED_IRQ_PER_MBIGEN_CHIP; - ofst = hwirq / 32 * 4; + unsigned int ofst = (hwirq / 32) * 4; *mask = 1 << (hwirq % 32); *addr = ofst + REG_MBIGEN_CLEAR_OFFSET; @@ -337,9 +334,15 @@ static int mbigen_device_probe(struct platform_device *pdev) mgn_chip->pdev = pdev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mgn_chip->base = devm_ioremap_resource(>dev, res); - if (IS_ERR(mgn_chip->base)) - return PTR_ERR(mgn_chip->base); + if (!res) + return -EINVAL; + + mgn_chip->base = devm_ioremap(>dev, res->start, + resource_size(res)); + if (!mgn_chip->base) { + dev_err(>dev, "failed to ioremap %pR\n", res); + return -ENOMEM; + } if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) err = mbigen_of_create_domain(pdev, mgn_chip); diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 686be4b73018..c94da688ee9b 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -880,8 +880,8 @@ irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle, if (!desc) return; - __irq_do_set_handler(desc, handle, 1, NULL); desc->irq_common_data.handler_data = data; + __irq_do_set_handler(desc, handle, 1, NULL); irq_put_desc_busunlock(desc, flags); }
[GIT pull] irq fixes for 4.11
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus The irq department provides: - Two fixes for the CPU affinity spread infrastructure to prevent unbalanced spreading in corner cases which leads to horrible performance, because interrupts are rather aggregated than spread - Add a missing spinlock initializer in the imx-gpcv2 init code Thanks, tglx --> Keith Busch (2): irq/affinity: Fix CPU spread for unbalanced nodes irq/affinity: Fix extra vecs calculation Tyler Baker (1): irqchip/irq-imx-gpcv2: Fix spinlock initialization drivers/irqchip/irq-imx-gpcv2.c | 2 ++ kernel/irq/affinity.c | 20 +++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c index 15af9a9753e5..2d203b422129 100644 --- a/drivers/irqchip/irq-imx-gpcv2.c +++ b/drivers/irqchip/irq-imx-gpcv2.c @@ -230,6 +230,8 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node, return -ENOMEM; } + raw_spin_lock_init(>rlock); + cd->gpc_base = of_iomap(node, 0); if (!cd->gpc_base) { pr_err("fsl-gpcv2: unable to map gpc registers\n"); diff --git a/kernel/irq/affinity.c b/kernel/irq/affinity.c index 4544b115f5eb..d052947fe785 100644 --- a/kernel/irq/affinity.c +++ b/kernel/irq/affinity.c @@ -59,7 +59,7 @@ static int get_nodes_in_cpumask(const struct cpumask *mask, nodemask_t *nodemsk) struct cpumask * irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd) { - int n, nodes, vecs_per_node, cpus_per_vec, extra_vecs, curvec; + int n, nodes, cpus_per_vec, extra_vecs, curvec; int affv = nvecs - affd->pre_vectors - affd->post_vectors; int last_affv = affv + affd->pre_vectors; nodemask_t nodemsk = NODE_MASK_NONE; @@ -94,19 +94,21 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd) goto done; } - /* Spread the vectors per node */ - vecs_per_node = affv / nodes; - /* Account for rounding errors */ - extra_vecs = affv - (nodes * vecs_per_node); - for_each_node_mask(n, nodemsk) { - int ncpus, v, vecs_to_assign = vecs_per_node; + int ncpus, v, vecs_to_assign, vecs_per_node; + + /* Spread the vectors per node */ + vecs_per_node = (affv - curvec) / nodes; /* Get the cpus on this node which are in the mask */ cpumask_and(nmsk, cpu_online_mask, cpumask_of_node(n)); /* Calculate the number of cpus per vector */ ncpus = cpumask_weight(nmsk); + vecs_to_assign = min(vecs_per_node, ncpus); + + /* Account for rounding errors */ + extra_vecs = ncpus - vecs_to_assign * (ncpus / vecs_to_assign); for (v = 0; curvec < last_affv && v < vecs_to_assign; curvec++, v++) { @@ -115,14 +117,14 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd) /* Account for extra vectors to compensate rounding errors */ if (extra_vecs) { cpus_per_vec++; - if (!--extra_vecs) - vecs_per_node++; + --extra_vecs; } irq_spread_init_one(masks + curvec, nmsk, cpus_per_vec); } if (curvec >= last_affv) break; + --nodes; } done:
[GIT pull] irq fixes for 4.11
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus The irq department provides: - Two fixes for the CPU affinity spread infrastructure to prevent unbalanced spreading in corner cases which leads to horrible performance, because interrupts are rather aggregated than spread - Add a missing spinlock initializer in the imx-gpcv2 init code Thanks, tglx --> Keith Busch (2): irq/affinity: Fix CPU spread for unbalanced nodes irq/affinity: Fix extra vecs calculation Tyler Baker (1): irqchip/irq-imx-gpcv2: Fix spinlock initialization drivers/irqchip/irq-imx-gpcv2.c | 2 ++ kernel/irq/affinity.c | 20 +++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c index 15af9a9753e5..2d203b422129 100644 --- a/drivers/irqchip/irq-imx-gpcv2.c +++ b/drivers/irqchip/irq-imx-gpcv2.c @@ -230,6 +230,8 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node, return -ENOMEM; } + raw_spin_lock_init(>rlock); + cd->gpc_base = of_iomap(node, 0); if (!cd->gpc_base) { pr_err("fsl-gpcv2: unable to map gpc registers\n"); diff --git a/kernel/irq/affinity.c b/kernel/irq/affinity.c index 4544b115f5eb..d052947fe785 100644 --- a/kernel/irq/affinity.c +++ b/kernel/irq/affinity.c @@ -59,7 +59,7 @@ static int get_nodes_in_cpumask(const struct cpumask *mask, nodemask_t *nodemsk) struct cpumask * irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd) { - int n, nodes, vecs_per_node, cpus_per_vec, extra_vecs, curvec; + int n, nodes, cpus_per_vec, extra_vecs, curvec; int affv = nvecs - affd->pre_vectors - affd->post_vectors; int last_affv = affv + affd->pre_vectors; nodemask_t nodemsk = NODE_MASK_NONE; @@ -94,19 +94,21 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd) goto done; } - /* Spread the vectors per node */ - vecs_per_node = affv / nodes; - /* Account for rounding errors */ - extra_vecs = affv - (nodes * vecs_per_node); - for_each_node_mask(n, nodemsk) { - int ncpus, v, vecs_to_assign = vecs_per_node; + int ncpus, v, vecs_to_assign, vecs_per_node; + + /* Spread the vectors per node */ + vecs_per_node = (affv - curvec) / nodes; /* Get the cpus on this node which are in the mask */ cpumask_and(nmsk, cpu_online_mask, cpumask_of_node(n)); /* Calculate the number of cpus per vector */ ncpus = cpumask_weight(nmsk); + vecs_to_assign = min(vecs_per_node, ncpus); + + /* Account for rounding errors */ + extra_vecs = ncpus - vecs_to_assign * (ncpus / vecs_to_assign); for (v = 0; curvec < last_affv && v < vecs_to_assign; curvec++, v++) { @@ -115,14 +117,14 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd) /* Account for extra vectors to compensate rounding errors */ if (extra_vecs) { cpus_per_vec++; - if (!--extra_vecs) - vecs_per_node++; + --extra_vecs; } irq_spread_init_one(masks + curvec, nmsk, cpus_per_vec); } if (curvec >= last_affv) break; + --nodes; } done:
[GIT pull] irq fixes for 4.11
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Two small fixlets: - Select a required Kconfig to make the MVEBU driver compile - Add the missing MIPS local GIC interrupts which prevent drivers to probe successfully. Thanks, tglx --> Arnd Bergmann (1): irqchip/mvebu-odmi: Select GENERIC_MSI_IRQ_DOMAIN Matt Redfearn (1): irqchip/mips-gic: Fix Local compare interrupt drivers/irqchip/Kconfig| 1 + drivers/irqchip/irq-mips-gic.c | 4 2 files changed, 5 insertions(+) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 125528f39e92..8162121bb1bc 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -262,6 +262,7 @@ config IRQ_MXS config MVEBU_ODMI bool + select GENERIC_MSI_IRQ_DOMAIN config MVEBU_PIC bool diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 11d12bccc4e7..cd20df12d63d 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -991,8 +991,12 @@ static void __init gic_map_single_int(struct device_node *node, static void __init gic_map_interrupts(struct device_node *node) { + gic_map_single_int(node, GIC_LOCAL_INT_WD); + gic_map_single_int(node, GIC_LOCAL_INT_COMPARE); gic_map_single_int(node, GIC_LOCAL_INT_TIMER); gic_map_single_int(node, GIC_LOCAL_INT_PERFCTR); + gic_map_single_int(node, GIC_LOCAL_INT_SWINT0); + gic_map_single_int(node, GIC_LOCAL_INT_SWINT1); gic_map_single_int(node, GIC_LOCAL_INT_FDC); }
[GIT pull] irq fixes for 4.11
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Two small fixlets: - Select a required Kconfig to make the MVEBU driver compile - Add the missing MIPS local GIC interrupts which prevent drivers to probe successfully. Thanks, tglx --> Arnd Bergmann (1): irqchip/mvebu-odmi: Select GENERIC_MSI_IRQ_DOMAIN Matt Redfearn (1): irqchip/mips-gic: Fix Local compare interrupt drivers/irqchip/Kconfig| 1 + drivers/irqchip/irq-mips-gic.c | 4 2 files changed, 5 insertions(+) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 125528f39e92..8162121bb1bc 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -262,6 +262,7 @@ config IRQ_MXS config MVEBU_ODMI bool + select GENERIC_MSI_IRQ_DOMAIN config MVEBU_PIC bool diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 11d12bccc4e7..cd20df12d63d 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -991,8 +991,12 @@ static void __init gic_map_single_int(struct device_node *node, static void __init gic_map_interrupts(struct device_node *node) { + gic_map_single_int(node, GIC_LOCAL_INT_WD); + gic_map_single_int(node, GIC_LOCAL_INT_COMPARE); gic_map_single_int(node, GIC_LOCAL_INT_TIMER); gic_map_single_int(node, GIC_LOCAL_INT_PERFCTR); + gic_map_single_int(node, GIC_LOCAL_INT_SWINT0); + gic_map_single_int(node, GIC_LOCAL_INT_SWINT1); gic_map_single_int(node, GIC_LOCAL_INT_FDC); }
[GIT pull] irq fixes for 4.11
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus This update contains: - A workaround for a GIC erratum - A missing stub function for CONFIG_IRQDOMAIN=n - Fixes for a couple of type inconsistencies Thanks, tglx --> Franck Demathieu (3): irqchip/crossbar: Fix incorrect type of local variables irqchip/crossbar: Fix incorrect type of local variables irqchip/crossbar: Fix incorrect type of register size Mian Yousaf Kaukab (1): irqdomain: Add empty irq_domain_check_msi_remap Shanker Donthineni (1): irqchip/gicv3-its: Add workaround for QDF2400 ITS erratum 0065 Documentation/arm64/silicon-errata.txt | 1 + arch/arm64/Kconfig | 10 ++ drivers/irqchip/irq-crossbar.c | 9 + drivers/irqchip/irq-gic-v3-its.c | 16 include/linux/irqdomain.h | 4 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index a71b8095dbd8..2f66683500b8 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -68,3 +68,4 @@ stable kernels. || | | | | Qualcomm Tech. | Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003| | Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009| +| Qualcomm Tech. | QDF2400 ITS | E0065 | QCOM_QDF2400_ERRATUM_0065 | diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index a39029b5414e..8c7c244247b6 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -508,6 +508,16 @@ config QCOM_FALKOR_ERRATUM_1009 If unsure, say Y. +config QCOM_QDF2400_ERRATUM_0065 + bool "QDF2400 E0065: Incorrect GITS_TYPER.ITT_Entry_size" + default y + help + On Qualcomm Datacenter Technologies QDF2400 SoC, ITS hardware reports + ITE size incorrectly. The GITS_TYPER.ITT_Entry_size field should have + been indicated as 16Bytes (0xf), not 8Bytes (0x7). + + If unsure, say Y. + endmenu diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index 1eef56a89b1f..f96601268f71 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c @@ -198,7 +198,8 @@ static const struct irq_domain_ops crossbar_domain_ops = { static int __init crossbar_of_init(struct device_node *node) { - int i, size, max = 0, reserved = 0, entry; + u32 max = 0, entry, reg_size; + int i, size, reserved = 0; const __be32 *irqsr; int ret = -ENOMEM; @@ -275,9 +276,9 @@ static int __init crossbar_of_init(struct device_node *node) if (!cb->register_offsets) goto err_irq_map; - of_property_read_u32(node, "ti,reg-size", ); + of_property_read_u32(node, "ti,reg-size", _size); - switch (size) { + switch (reg_size) { case 1: cb->write = crossbar_writeb; break; @@ -303,7 +304,7 @@ static int __init crossbar_of_init(struct device_node *node) continue; cb->register_offsets[i] = reserved; - reserved += size; + reserved += reg_size; } of_property_read_u32(node, "ti,irqs-safe-map", >safe_map); diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 23201004fd7a..f77f840d2b5f 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1601,6 +1601,14 @@ static void __maybe_unused its_enable_quirk_cavium_23144(void *data) its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_23144; } +static void __maybe_unused its_enable_quirk_qdf2400_e0065(void *data) +{ + struct its_node *its = data; + + /* On QDF2400, the size of the ITE is 16Bytes */ + its->ite_size = 16; +} + static const struct gic_quirk its_quirks[] = { #ifdef CONFIG_CAVIUM_ERRATUM_22375 { @@ -1618,6 +1626,14 @@ static const struct gic_quirk its_quirks[] = { .init = its_enable_quirk_cavium_23144, }, #endif +#ifdef CONFIG_QCOM_QDF2400_ERRATUM_0065 + { + .desc = "ITS: QDF2400 erratum 0065", + .iidr = 0x1070, /* QDF2400 ITS rev 1.x */ + .mask = 0x, + .init = its_enable_quirk_qdf2400_e0065, + }, +#endif { } }; diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 188eced6813e..9f3616085423 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -524,6 +524,10 @@ static inline struct irq_domain *irq_find_matching_fwnode( { return NULL; } +static inline bool irq_domain_check_msi_remap(void) +{ + return false; +} #endif
[GIT pull] irq fixes for 4.11
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus This update contains: - A workaround for a GIC erratum - A missing stub function for CONFIG_IRQDOMAIN=n - Fixes for a couple of type inconsistencies Thanks, tglx --> Franck Demathieu (3): irqchip/crossbar: Fix incorrect type of local variables irqchip/crossbar: Fix incorrect type of local variables irqchip/crossbar: Fix incorrect type of register size Mian Yousaf Kaukab (1): irqdomain: Add empty irq_domain_check_msi_remap Shanker Donthineni (1): irqchip/gicv3-its: Add workaround for QDF2400 ITS erratum 0065 Documentation/arm64/silicon-errata.txt | 1 + arch/arm64/Kconfig | 10 ++ drivers/irqchip/irq-crossbar.c | 9 + drivers/irqchip/irq-gic-v3-its.c | 16 include/linux/irqdomain.h | 4 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt index a71b8095dbd8..2f66683500b8 100644 --- a/Documentation/arm64/silicon-errata.txt +++ b/Documentation/arm64/silicon-errata.txt @@ -68,3 +68,4 @@ stable kernels. || | | | | Qualcomm Tech. | Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003| | Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009| +| Qualcomm Tech. | QDF2400 ITS | E0065 | QCOM_QDF2400_ERRATUM_0065 | diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index a39029b5414e..8c7c244247b6 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -508,6 +508,16 @@ config QCOM_FALKOR_ERRATUM_1009 If unsure, say Y. +config QCOM_QDF2400_ERRATUM_0065 + bool "QDF2400 E0065: Incorrect GITS_TYPER.ITT_Entry_size" + default y + help + On Qualcomm Datacenter Technologies QDF2400 SoC, ITS hardware reports + ITE size incorrectly. The GITS_TYPER.ITT_Entry_size field should have + been indicated as 16Bytes (0xf), not 8Bytes (0x7). + + If unsure, say Y. + endmenu diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index 1eef56a89b1f..f96601268f71 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c @@ -198,7 +198,8 @@ static const struct irq_domain_ops crossbar_domain_ops = { static int __init crossbar_of_init(struct device_node *node) { - int i, size, max = 0, reserved = 0, entry; + u32 max = 0, entry, reg_size; + int i, size, reserved = 0; const __be32 *irqsr; int ret = -ENOMEM; @@ -275,9 +276,9 @@ static int __init crossbar_of_init(struct device_node *node) if (!cb->register_offsets) goto err_irq_map; - of_property_read_u32(node, "ti,reg-size", ); + of_property_read_u32(node, "ti,reg-size", _size); - switch (size) { + switch (reg_size) { case 1: cb->write = crossbar_writeb; break; @@ -303,7 +304,7 @@ static int __init crossbar_of_init(struct device_node *node) continue; cb->register_offsets[i] = reserved; - reserved += size; + reserved += reg_size; } of_property_read_u32(node, "ti,irqs-safe-map", >safe_map); diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 23201004fd7a..f77f840d2b5f 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1601,6 +1601,14 @@ static void __maybe_unused its_enable_quirk_cavium_23144(void *data) its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_23144; } +static void __maybe_unused its_enable_quirk_qdf2400_e0065(void *data) +{ + struct its_node *its = data; + + /* On QDF2400, the size of the ITE is 16Bytes */ + its->ite_size = 16; +} + static const struct gic_quirk its_quirks[] = { #ifdef CONFIG_CAVIUM_ERRATUM_22375 { @@ -1618,6 +1626,14 @@ static const struct gic_quirk its_quirks[] = { .init = its_enable_quirk_cavium_23144, }, #endif +#ifdef CONFIG_QCOM_QDF2400_ERRATUM_0065 + { + .desc = "ITS: QDF2400 erratum 0065", + .iidr = 0x1070, /* QDF2400 ITS rev 1.x */ + .mask = 0x, + .init = its_enable_quirk_qdf2400_e0065, + }, +#endif { } }; diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 188eced6813e..9f3616085423 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -524,6 +524,10 @@ static inline struct irq_domain *irq_find_matching_fwnode( { return NULL; } +static inline bool irq_domain_check_msi_remap(void) +{ + return false; +} #endif
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: d128dfb514f55af040c38a6b3b131d72b6f115d0 Merge tag 'irqchip-fixes-4.10' of git://git.infradead.org/users/jcooper/linux into irq/urgent Two last minute ARM irqchip driver fixes. Thanks, Ingo --> Stefan Wahren (1): irqchip/mxs: Enable SKIP_SET_WAKE and MASK_ON_SUSPEND Strashko, Grygorii (1): irqchip/keystone: Fix "scheduling while atomic" on rt drivers/irqchip/irq-keystone.c | 28 +++- drivers/irqchip/irq-mxs.c | 4 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c index 54a5e870a8f5..efbcf8435185 100644 --- a/drivers/irqchip/irq-keystone.c +++ b/drivers/irqchip/irq-keystone.c @@ -19,9 +19,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -39,6 +39,7 @@ struct keystone_irq_device { struct irq_domain *irqd; struct regmap *devctrl_regs; u32 devctrl_offset; + raw_spinlock_t wa_lock; }; static inline u32 keystone_irq_readl(struct keystone_irq_device *kirq) @@ -83,17 +84,15 @@ static void keystone_irq_ack(struct irq_data *d) /* nothing to do here */ } -static void keystone_irq_handler(struct irq_desc *desc) +static irqreturn_t keystone_irq_handler(int irq, void *keystone_irq) { - unsigned int irq = irq_desc_get_irq(desc); - struct keystone_irq_device *kirq = irq_desc_get_handler_data(desc); + struct keystone_irq_device *kirq = keystone_irq; + unsigned long wa_lock_flags; unsigned long pending; int src, virq; dev_dbg(kirq->dev, "start irq %d\n", irq); - chained_irq_enter(irq_desc_get_chip(desc), desc); - pending = keystone_irq_readl(kirq); keystone_irq_writel(kirq, pending); @@ -111,13 +110,15 @@ static void keystone_irq_handler(struct irq_desc *desc) if (!virq) dev_warn(kirq->dev, "spurious irq detected hwirq %d, virq %d\n", src, virq); + raw_spin_lock_irqsave(>wa_lock, wa_lock_flags); generic_handle_irq(virq); + raw_spin_unlock_irqrestore(>wa_lock, + wa_lock_flags); } } - chained_irq_exit(irq_desc_get_chip(desc), desc); - dev_dbg(kirq->dev, "end irq %d\n", irq); + return IRQ_HANDLED; } static int keystone_irq_map(struct irq_domain *h, unsigned int virq, @@ -182,9 +183,16 @@ static int keystone_irq_probe(struct platform_device *pdev) return -ENODEV; } + raw_spin_lock_init(>wa_lock); + platform_set_drvdata(pdev, kirq); - irq_set_chained_handler_and_data(kirq->irq, keystone_irq_handler, kirq); + ret = request_irq(kirq->irq, keystone_irq_handler, + 0, dev_name(dev), kirq); + if (ret) { + irq_domain_remove(kirq->irqd); + return ret; + } /* clear all source bits */ keystone_irq_writel(kirq, ~0x0); @@ -199,6 +207,8 @@ static int keystone_irq_remove(struct platform_device *pdev) struct keystone_irq_device *kirq = platform_get_drvdata(pdev); int hwirq; + free_irq(kirq->irq, kirq); + for (hwirq = 0; hwirq < KEYSTONE_N_IRQ; hwirq++) irq_dispose_mapping(irq_find_mapping(kirq->irqd, hwirq)); diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c index 17304705f2cf..05fa9f7af53c 100644 --- a/drivers/irqchip/irq-mxs.c +++ b/drivers/irqchip/irq-mxs.c @@ -131,12 +131,16 @@ static struct irq_chip mxs_icoll_chip = { .irq_ack = icoll_ack_irq, .irq_mask = icoll_mask_irq, .irq_unmask = icoll_unmask_irq, + .flags = IRQCHIP_MASK_ON_SUSPEND | +IRQCHIP_SKIP_SET_WAKE, }; static struct irq_chip asm9260_icoll_chip = { .irq_ack = icoll_ack_irq, .irq_mask = asm9260_mask_irq, .irq_unmask = asm9260_unmask_irq, + .flags = IRQCHIP_MASK_ON_SUSPEND | +IRQCHIP_SKIP_SET_WAKE, }; asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: d128dfb514f55af040c38a6b3b131d72b6f115d0 Merge tag 'irqchip-fixes-4.10' of git://git.infradead.org/users/jcooper/linux into irq/urgent Two last minute ARM irqchip driver fixes. Thanks, Ingo --> Stefan Wahren (1): irqchip/mxs: Enable SKIP_SET_WAKE and MASK_ON_SUSPEND Strashko, Grygorii (1): irqchip/keystone: Fix "scheduling while atomic" on rt drivers/irqchip/irq-keystone.c | 28 +++- drivers/irqchip/irq-mxs.c | 4 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c index 54a5e870a8f5..efbcf8435185 100644 --- a/drivers/irqchip/irq-keystone.c +++ b/drivers/irqchip/irq-keystone.c @@ -19,9 +19,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -39,6 +39,7 @@ struct keystone_irq_device { struct irq_domain *irqd; struct regmap *devctrl_regs; u32 devctrl_offset; + raw_spinlock_t wa_lock; }; static inline u32 keystone_irq_readl(struct keystone_irq_device *kirq) @@ -83,17 +84,15 @@ static void keystone_irq_ack(struct irq_data *d) /* nothing to do here */ } -static void keystone_irq_handler(struct irq_desc *desc) +static irqreturn_t keystone_irq_handler(int irq, void *keystone_irq) { - unsigned int irq = irq_desc_get_irq(desc); - struct keystone_irq_device *kirq = irq_desc_get_handler_data(desc); + struct keystone_irq_device *kirq = keystone_irq; + unsigned long wa_lock_flags; unsigned long pending; int src, virq; dev_dbg(kirq->dev, "start irq %d\n", irq); - chained_irq_enter(irq_desc_get_chip(desc), desc); - pending = keystone_irq_readl(kirq); keystone_irq_writel(kirq, pending); @@ -111,13 +110,15 @@ static void keystone_irq_handler(struct irq_desc *desc) if (!virq) dev_warn(kirq->dev, "spurious irq detected hwirq %d, virq %d\n", src, virq); + raw_spin_lock_irqsave(>wa_lock, wa_lock_flags); generic_handle_irq(virq); + raw_spin_unlock_irqrestore(>wa_lock, + wa_lock_flags); } } - chained_irq_exit(irq_desc_get_chip(desc), desc); - dev_dbg(kirq->dev, "end irq %d\n", irq); + return IRQ_HANDLED; } static int keystone_irq_map(struct irq_domain *h, unsigned int virq, @@ -182,9 +183,16 @@ static int keystone_irq_probe(struct platform_device *pdev) return -ENODEV; } + raw_spin_lock_init(>wa_lock); + platform_set_drvdata(pdev, kirq); - irq_set_chained_handler_and_data(kirq->irq, keystone_irq_handler, kirq); + ret = request_irq(kirq->irq, keystone_irq_handler, + 0, dev_name(dev), kirq); + if (ret) { + irq_domain_remove(kirq->irqd); + return ret; + } /* clear all source bits */ keystone_irq_writel(kirq, ~0x0); @@ -199,6 +207,8 @@ static int keystone_irq_remove(struct platform_device *pdev) struct keystone_irq_device *kirq = platform_get_drvdata(pdev); int hwirq; + free_irq(kirq->irq, kirq); + for (hwirq = 0; hwirq < KEYSTONE_N_IRQ; hwirq++) irq_dispose_mapping(irq_find_mapping(kirq->irqd, hwirq)); diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c index 17304705f2cf..05fa9f7af53c 100644 --- a/drivers/irqchip/irq-mxs.c +++ b/drivers/irqchip/irq-mxs.c @@ -131,12 +131,16 @@ static struct irq_chip mxs_icoll_chip = { .irq_ack = icoll_ack_irq, .irq_mask = icoll_mask_irq, .irq_unmask = icoll_unmask_irq, + .flags = IRQCHIP_MASK_ON_SUSPEND | +IRQCHIP_SKIP_SET_WAKE, }; static struct irq_chip asm9260_icoll_chip = { .irq_ack = icoll_ack_irq, .irq_mask = asm9260_mask_irq, .irq_unmask = asm9260_unmask_irq, + .flags = IRQCHIP_MASK_ON_SUSPEND | +IRQCHIP_SKIP_SET_WAKE, }; asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
[GIT pull] irq fixes for 4.10
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus This update contains: - Prevent double activation of interrupt lines, which causes problems on certain interrupt controllers - Handle the fallout of the above because x86 (ab)uses the activation function to reconfigure interrupts under the hood. Thanks, tglx --> Marc Zyngier (1): irqdomain: Avoid activating interrupts more than once Thomas Gleixner (1): x86/irq: Make irq activate operations symmetric arch/x86/kernel/apic/io_apic.c | 2 ++ arch/x86/kernel/hpet.c | 1 + include/linux/irq.h| 17 kernel/irq/irqdomain.c | 44 -- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 1e35dd06b090..52f352b063fd 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2117,6 +2117,7 @@ static inline void __init check_timer(void) if (idx != -1 && irq_trigger(idx)) unmask_ioapic_irq(irq_get_chip_data(0)); } + irq_domain_deactivate_irq(irq_data); irq_domain_activate_irq(irq_data); if (timer_irq_works()) { if (disable_timer_pin_1 > 0) @@ -2138,6 +2139,7 @@ static inline void __init check_timer(void) * legacy devices should be connected to IO APIC #0 */ replace_pin_at_irq_node(data, node, apic1, pin1, apic2, pin2); + irq_domain_deactivate_irq(irq_data); irq_domain_activate_irq(irq_data); legacy_pic->unmask(0); if (timer_irq_works()) { diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 85e87b46c318..dc6ba5bda9fc 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -352,6 +352,7 @@ static int hpet_resume(struct clock_event_device *evt, int timer) } else { struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt); + irq_domain_deactivate_irq(irq_get_irq_data(hdev->irq)); irq_domain_activate_irq(irq_get_irq_data(hdev->irq)); disable_irq(hdev->irq); irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu)); diff --git a/include/linux/irq.h b/include/linux/irq.h index e79875574b39..39e3254e5769 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -184,6 +184,7 @@ struct irq_data { * * IRQD_TRIGGER_MASK - Mask for the trigger type bits * IRQD_SETAFFINITY_PENDING- Affinity setting is pending + * IRQD_ACTIVATED - Interrupt has already been activated * IRQD_NO_BALANCING - Balancing disabled for this IRQ * IRQD_PER_CPU- Interrupt is per cpu * IRQD_AFFINITY_SET - Interrupt affinity was set @@ -202,6 +203,7 @@ struct irq_data { enum { IRQD_TRIGGER_MASK = 0xf, IRQD_SETAFFINITY_PENDING= (1 << 8), + IRQD_ACTIVATED = (1 << 9), IRQD_NO_BALANCING = (1 << 10), IRQD_PER_CPU= (1 << 11), IRQD_AFFINITY_SET = (1 << 12), @@ -312,6 +314,21 @@ static inline bool irqd_affinity_is_managed(struct irq_data *d) return __irqd_to_state(d) & IRQD_AFFINITY_MANAGED; } +static inline bool irqd_is_activated(struct irq_data *d) +{ + return __irqd_to_state(d) & IRQD_ACTIVATED; +} + +static inline void irqd_set_activated(struct irq_data *d) +{ + __irqd_to_state(d) |= IRQD_ACTIVATED; +} + +static inline void irqd_clr_activated(struct irq_data *d) +{ + __irqd_to_state(d) &= ~IRQD_ACTIVATED; +} + #undef __irqd_to_state static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 8c0a0ae43521..b59e6768c5e9 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1346,6 +1346,30 @@ void irq_domain_free_irqs_parent(struct irq_domain *domain, } EXPORT_SYMBOL_GPL(irq_domain_free_irqs_parent); +static void __irq_domain_activate_irq(struct irq_data *irq_data) +{ + if (irq_data && irq_data->domain) { + struct irq_domain *domain = irq_data->domain; + + if (irq_data->parent_data) + __irq_domain_activate_irq(irq_data->parent_data); + if (domain->ops->activate) + domain->ops->activate(domain, irq_data); + } +} + +static void __irq_domain_deactivate_irq(struct irq_data *irq_data) +{ + if (irq_data && irq_data->domain) { + struct irq_domain *domain = irq_data->domain; + + if (domain->ops->deactivate) + domain->ops->deactivate(domain,
[GIT pull] irq fixes for 4.10
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus This update contains: - Prevent double activation of interrupt lines, which causes problems on certain interrupt controllers - Handle the fallout of the above because x86 (ab)uses the activation function to reconfigure interrupts under the hood. Thanks, tglx --> Marc Zyngier (1): irqdomain: Avoid activating interrupts more than once Thomas Gleixner (1): x86/irq: Make irq activate operations symmetric arch/x86/kernel/apic/io_apic.c | 2 ++ arch/x86/kernel/hpet.c | 1 + include/linux/irq.h| 17 kernel/irq/irqdomain.c | 44 -- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 1e35dd06b090..52f352b063fd 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2117,6 +2117,7 @@ static inline void __init check_timer(void) if (idx != -1 && irq_trigger(idx)) unmask_ioapic_irq(irq_get_chip_data(0)); } + irq_domain_deactivate_irq(irq_data); irq_domain_activate_irq(irq_data); if (timer_irq_works()) { if (disable_timer_pin_1 > 0) @@ -2138,6 +2139,7 @@ static inline void __init check_timer(void) * legacy devices should be connected to IO APIC #0 */ replace_pin_at_irq_node(data, node, apic1, pin1, apic2, pin2); + irq_domain_deactivate_irq(irq_data); irq_domain_activate_irq(irq_data); legacy_pic->unmask(0); if (timer_irq_works()) { diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 85e87b46c318..dc6ba5bda9fc 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -352,6 +352,7 @@ static int hpet_resume(struct clock_event_device *evt, int timer) } else { struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt); + irq_domain_deactivate_irq(irq_get_irq_data(hdev->irq)); irq_domain_activate_irq(irq_get_irq_data(hdev->irq)); disable_irq(hdev->irq); irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu)); diff --git a/include/linux/irq.h b/include/linux/irq.h index e79875574b39..39e3254e5769 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -184,6 +184,7 @@ struct irq_data { * * IRQD_TRIGGER_MASK - Mask for the trigger type bits * IRQD_SETAFFINITY_PENDING- Affinity setting is pending + * IRQD_ACTIVATED - Interrupt has already been activated * IRQD_NO_BALANCING - Balancing disabled for this IRQ * IRQD_PER_CPU- Interrupt is per cpu * IRQD_AFFINITY_SET - Interrupt affinity was set @@ -202,6 +203,7 @@ struct irq_data { enum { IRQD_TRIGGER_MASK = 0xf, IRQD_SETAFFINITY_PENDING= (1 << 8), + IRQD_ACTIVATED = (1 << 9), IRQD_NO_BALANCING = (1 << 10), IRQD_PER_CPU= (1 << 11), IRQD_AFFINITY_SET = (1 << 12), @@ -312,6 +314,21 @@ static inline bool irqd_affinity_is_managed(struct irq_data *d) return __irqd_to_state(d) & IRQD_AFFINITY_MANAGED; } +static inline bool irqd_is_activated(struct irq_data *d) +{ + return __irqd_to_state(d) & IRQD_ACTIVATED; +} + +static inline void irqd_set_activated(struct irq_data *d) +{ + __irqd_to_state(d) |= IRQD_ACTIVATED; +} + +static inline void irqd_clr_activated(struct irq_data *d) +{ + __irqd_to_state(d) &= ~IRQD_ACTIVATED; +} + #undef __irqd_to_state static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 8c0a0ae43521..b59e6768c5e9 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1346,6 +1346,30 @@ void irq_domain_free_irqs_parent(struct irq_domain *domain, } EXPORT_SYMBOL_GPL(irq_domain_free_irqs_parent); +static void __irq_domain_activate_irq(struct irq_data *irq_data) +{ + if (irq_data && irq_data->domain) { + struct irq_domain *domain = irq_data->domain; + + if (irq_data->parent_data) + __irq_domain_activate_irq(irq_data->parent_data); + if (domain->ops->activate) + domain->ops->activate(domain, irq_data); + } +} + +static void __irq_domain_deactivate_irq(struct irq_data *irq_data) +{ + if (irq_data && irq_data->domain) { + struct irq_domain *domain = irq_data->domain; + + if (domain->ops->deactivate) + domain->ops->deactivate(domain,
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: a442950d4af036006757bc3da00a2cb939fb2f59 Merge tag 'gic-fixes-for-4.9-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent Mostly irqchip driver fixes, plus a symbol export. Thanks, Ingo --> Marc Zyngier (2): irqchip/gic-v3-its: Fix 64bit GIC{R,ITS}_TYPER accesses irqchip/gic: Add missing \n to CPU IF adjustment message Rich Felker (1): irqchip/jcore: Don't show Kconfig menu item for driver Sudip Mukherjee (1): kernel/irq: Export irq_set_parent() Vladimir Murzin (1): irqchip/gic-v3-its: Fix entry size mask for GITS_BASER Wei Yongjun (1): irqchip/eznps: Drop pointless static qualifier in nps400_of_init() drivers/irqchip/Kconfig| 4 ++-- drivers/irqchip/irq-eznps.c| 2 +- drivers/irqchip/irq-gic-v3-its.c | 10 +- drivers/irqchip/irq-gic.c | 2 +- include/linux/irqchip/arm-gic-v3.h | 2 +- kernel/irq/manage.c| 1 + 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 82b0b5daf3f5..bc0af3307bbf 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -158,8 +158,8 @@ config PIC32_EVIC select IRQ_DOMAIN config JCORE_AIC - bool "J-Core integrated AIC" - depends on OF && (SUPERH || COMPILE_TEST) + bool "J-Core integrated AIC" if COMPILE_TEST + depends on OF select IRQ_DOMAIN help Support for the J-Core integrated AIC. diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c index ebc2b0b15f67..2a7a38830a8d 100644 --- a/drivers/irqchip/irq-eznps.c +++ b/drivers/irqchip/irq-eznps.c @@ -135,7 +135,7 @@ static const struct irq_domain_ops nps400_irq_ops = { static int __init nps400_of_init(struct device_node *node, struct device_node *parent) { - static struct irq_domain *nps400_root_domain; + struct irq_domain *nps400_root_domain; if (parent) { pr_err("DeviceTree incore ic not a root irq controller\n"); diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 003495d91f9c..c5dee300e8a3 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1023,7 +1023,7 @@ static void its_free_tables(struct its_node *its) static int its_alloc_tables(struct its_node *its) { - u64 typer = readq_relaxed(its->base + GITS_TYPER); + u64 typer = gic_read_typer(its->base + GITS_TYPER); u32 ids = GITS_TYPER_DEVBITS(typer); u64 shr = GITS_BASER_InnerShareable; u64 cache = GITS_BASER_WaWb; @@ -1198,7 +1198,7 @@ static void its_cpu_init_collection(void) * We now have to bind each collection to its target * redistributor. */ - if (readq_relaxed(its->base + GITS_TYPER) & GITS_TYPER_PTA) { + if (gic_read_typer(its->base + GITS_TYPER) & GITS_TYPER_PTA) { /* * This ITS wants the physical address of the * redistributor. @@ -1208,7 +1208,7 @@ static void its_cpu_init_collection(void) /* * This ITS wants a linear CPU number. */ - target = readq_relaxed(gic_data_rdist_rd_base() + GICR_TYPER); + target = gic_read_typer(gic_data_rdist_rd_base() + GICR_TYPER); target = GICR_TYPER_CPU_NUMBER(target) << 16; } @@ -1691,7 +1691,7 @@ static int __init its_probe_one(struct resource *res, INIT_LIST_HEAD(>its_device_list); its->base = its_base; its->phys_base = res->start; - its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1; + its->ite_size = ((gic_read_typer(its_base + GITS_TYPER) >> 4) & 0xf) + 1; its->numa_node = numa_node; its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL); @@ -1763,7 +1763,7 @@ static int __init its_probe_one(struct resource *res, static bool gic_rdists_supports_plpis(void) { - return !!(readl_relaxed(gic_data_rdist_rd_base() + GICR_TYPER) & GICR_TYPER_PLPIS); + return !!(gic_read_typer(gic_data_rdist_rd_base() + GICR_TYPER) & GICR_TYPER_PLPIS); } int its_cpu_init(void) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 58e5b4e87056..d6c404b3584d 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -1279,7 +1279,7 @@ static bool gic_check_eoimode(struct device_node *node, void __iomem **base) */ *base += 0xf000; cpuif_res.start += 0xf000; - pr_warn("GIC: Adjusting CPU
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: a442950d4af036006757bc3da00a2cb939fb2f59 Merge tag 'gic-fixes-for-4.9-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent Mostly irqchip driver fixes, plus a symbol export. Thanks, Ingo --> Marc Zyngier (2): irqchip/gic-v3-its: Fix 64bit GIC{R,ITS}_TYPER accesses irqchip/gic: Add missing \n to CPU IF adjustment message Rich Felker (1): irqchip/jcore: Don't show Kconfig menu item for driver Sudip Mukherjee (1): kernel/irq: Export irq_set_parent() Vladimir Murzin (1): irqchip/gic-v3-its: Fix entry size mask for GITS_BASER Wei Yongjun (1): irqchip/eznps: Drop pointless static qualifier in nps400_of_init() drivers/irqchip/Kconfig| 4 ++-- drivers/irqchip/irq-eznps.c| 2 +- drivers/irqchip/irq-gic-v3-its.c | 10 +- drivers/irqchip/irq-gic.c | 2 +- include/linux/irqchip/arm-gic-v3.h | 2 +- kernel/irq/manage.c| 1 + 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 82b0b5daf3f5..bc0af3307bbf 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -158,8 +158,8 @@ config PIC32_EVIC select IRQ_DOMAIN config JCORE_AIC - bool "J-Core integrated AIC" - depends on OF && (SUPERH || COMPILE_TEST) + bool "J-Core integrated AIC" if COMPILE_TEST + depends on OF select IRQ_DOMAIN help Support for the J-Core integrated AIC. diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c index ebc2b0b15f67..2a7a38830a8d 100644 --- a/drivers/irqchip/irq-eznps.c +++ b/drivers/irqchip/irq-eznps.c @@ -135,7 +135,7 @@ static const struct irq_domain_ops nps400_irq_ops = { static int __init nps400_of_init(struct device_node *node, struct device_node *parent) { - static struct irq_domain *nps400_root_domain; + struct irq_domain *nps400_root_domain; if (parent) { pr_err("DeviceTree incore ic not a root irq controller\n"); diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 003495d91f9c..c5dee300e8a3 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1023,7 +1023,7 @@ static void its_free_tables(struct its_node *its) static int its_alloc_tables(struct its_node *its) { - u64 typer = readq_relaxed(its->base + GITS_TYPER); + u64 typer = gic_read_typer(its->base + GITS_TYPER); u32 ids = GITS_TYPER_DEVBITS(typer); u64 shr = GITS_BASER_InnerShareable; u64 cache = GITS_BASER_WaWb; @@ -1198,7 +1198,7 @@ static void its_cpu_init_collection(void) * We now have to bind each collection to its target * redistributor. */ - if (readq_relaxed(its->base + GITS_TYPER) & GITS_TYPER_PTA) { + if (gic_read_typer(its->base + GITS_TYPER) & GITS_TYPER_PTA) { /* * This ITS wants the physical address of the * redistributor. @@ -1208,7 +1208,7 @@ static void its_cpu_init_collection(void) /* * This ITS wants a linear CPU number. */ - target = readq_relaxed(gic_data_rdist_rd_base() + GICR_TYPER); + target = gic_read_typer(gic_data_rdist_rd_base() + GICR_TYPER); target = GICR_TYPER_CPU_NUMBER(target) << 16; } @@ -1691,7 +1691,7 @@ static int __init its_probe_one(struct resource *res, INIT_LIST_HEAD(>its_device_list); its->base = its_base; its->phys_base = res->start; - its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1; + its->ite_size = ((gic_read_typer(its_base + GITS_TYPER) >> 4) & 0xf) + 1; its->numa_node = numa_node; its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL); @@ -1763,7 +1763,7 @@ static int __init its_probe_one(struct resource *res, static bool gic_rdists_supports_plpis(void) { - return !!(readl_relaxed(gic_data_rdist_rd_base() + GICR_TYPER) & GICR_TYPER_PLPIS); + return !!(gic_read_typer(gic_data_rdist_rd_base() + GICR_TYPER) & GICR_TYPER_PLPIS); } int its_cpu_init(void) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 58e5b4e87056..d6c404b3584d 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -1279,7 +1279,7 @@ static bool gic_check_eoimode(struct device_node *node, void __iomem **base) */ *base += 0xf000; cpuif_res.start += 0xf000; - pr_warn("GIC: Adjusting CPU
[GIT PULL] irq fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: d102eb5c1ac5e6743b1c6d145c06a25d98ad1375 irqchip/gicv3: Handle loop timeout proper Three irqchip driver fixes. Thanks, Ingo --> Dan Carpenter (1): irqchip/gicv3: Handle loop timeout proper Noam Camus (1): irqchip/eznps: Acknowledge NPS_IPI before calling the handler Rich Felker (1): irqchip/jcore: Fix lost per-cpu interrupts drivers/irqchip/irq-eznps.c | 4 ++-- drivers/irqchip/irq-gic-v3.c| 2 +- drivers/irqchip/irq-jcore-aic.c | 20 +++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c index efbf0e4304b7..ebc2b0b15f67 100644 --- a/drivers/irqchip/irq-eznps.c +++ b/drivers/irqchip/irq-eznps.c @@ -85,7 +85,7 @@ static void nps400_irq_eoi_global(struct irq_data *irqd) nps_ack_gic(); } -static void nps400_irq_eoi(struct irq_data *irqd) +static void nps400_irq_ack(struct irq_data *irqd) { unsigned int __maybe_unused irq = irqd_to_hwirq(irqd); @@ -103,7 +103,7 @@ static struct irq_chip nps400_irq_chip_percpu = { .name = "NPS400 IC", .irq_mask = nps400_irq_mask, .irq_unmask = nps400_irq_unmask, - .irq_eoi= nps400_irq_eoi, + .irq_ack= nps400_irq_ack, }; static int nps400_irq_map(struct irq_domain *d, unsigned int virq, diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 9b81bd8b929c..19d642eae096 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -153,7 +153,7 @@ static void gic_enable_redist(bool enable) return; /* No PM support in this redistributor */ } - while (count--) { + while (--count) { val = readl_relaxed(rbase + GICR_WAKER); if (enable ^ (bool)(val & GICR_WAKER_ChildrenAsleep)) break; diff --git a/drivers/irqchip/irq-jcore-aic.c b/drivers/irqchip/irq-jcore-aic.c index 84b01dec277d..033bccb41455 100644 --- a/drivers/irqchip/irq-jcore-aic.c +++ b/drivers/irqchip/irq-jcore-aic.c @@ -25,12 +25,30 @@ static struct irq_chip jcore_aic; +/* + * The J-Core AIC1 and AIC2 are cpu-local interrupt controllers and do + * not distinguish or use distinct irq number ranges for per-cpu event + * interrupts (timer, IPI). Since information to determine whether a + * particular irq number should be treated as per-cpu is not available + * at mapping time, we use a wrapper handler function which chooses + * the right handler at runtime based on whether IRQF_PERCPU was used + * when requesting the irq. + */ + +static void handle_jcore_irq(struct irq_desc *desc) +{ + if (irqd_is_per_cpu(irq_desc_get_irq_data(desc))) + handle_percpu_irq(desc); + else + handle_simple_irq(desc); +} + static int jcore_aic_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq) { struct irq_chip *aic = d->host_data; - irq_set_chip_and_handler(irq, aic, handle_simple_irq); + irq_set_chip_and_handler(irq, aic, handle_jcore_irq); return 0; }
[GIT PULL] irq fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: d102eb5c1ac5e6743b1c6d145c06a25d98ad1375 irqchip/gicv3: Handle loop timeout proper Three irqchip driver fixes. Thanks, Ingo --> Dan Carpenter (1): irqchip/gicv3: Handle loop timeout proper Noam Camus (1): irqchip/eznps: Acknowledge NPS_IPI before calling the handler Rich Felker (1): irqchip/jcore: Fix lost per-cpu interrupts drivers/irqchip/irq-eznps.c | 4 ++-- drivers/irqchip/irq-gic-v3.c| 2 +- drivers/irqchip/irq-jcore-aic.c | 20 +++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c index efbf0e4304b7..ebc2b0b15f67 100644 --- a/drivers/irqchip/irq-eznps.c +++ b/drivers/irqchip/irq-eznps.c @@ -85,7 +85,7 @@ static void nps400_irq_eoi_global(struct irq_data *irqd) nps_ack_gic(); } -static void nps400_irq_eoi(struct irq_data *irqd) +static void nps400_irq_ack(struct irq_data *irqd) { unsigned int __maybe_unused irq = irqd_to_hwirq(irqd); @@ -103,7 +103,7 @@ static struct irq_chip nps400_irq_chip_percpu = { .name = "NPS400 IC", .irq_mask = nps400_irq_mask, .irq_unmask = nps400_irq_unmask, - .irq_eoi= nps400_irq_eoi, + .irq_ack= nps400_irq_ack, }; static int nps400_irq_map(struct irq_domain *d, unsigned int virq, diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 9b81bd8b929c..19d642eae096 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -153,7 +153,7 @@ static void gic_enable_redist(bool enable) return; /* No PM support in this redistributor */ } - while (count--) { + while (--count) { val = readl_relaxed(rbase + GICR_WAKER); if (enable ^ (bool)(val & GICR_WAKER_ChildrenAsleep)) break; diff --git a/drivers/irqchip/irq-jcore-aic.c b/drivers/irqchip/irq-jcore-aic.c index 84b01dec277d..033bccb41455 100644 --- a/drivers/irqchip/irq-jcore-aic.c +++ b/drivers/irqchip/irq-jcore-aic.c @@ -25,12 +25,30 @@ static struct irq_chip jcore_aic; +/* + * The J-Core AIC1 and AIC2 are cpu-local interrupt controllers and do + * not distinguish or use distinct irq number ranges for per-cpu event + * interrupts (timer, IPI). Since information to determine whether a + * particular irq number should be treated as per-cpu is not available + * at mapping time, we use a wrapper handler function which chooses + * the right handler at runtime based on whether IRQF_PERCPU was used + * when requesting the irq. + */ + +static void handle_jcore_irq(struct irq_desc *desc) +{ + if (irqd_is_per_cpu(irq_desc_get_irq_data(desc))) + handle_percpu_irq(desc); + else + handle_simple_irq(desc); +} + static int jcore_aic_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq) { struct irq_chip *aic = d->host_data; - irq_set_chip_and_handler(irq, aic, handle_simple_irq); + irq_set_chip_and_handler(irq, aic, handle_jcore_irq); return 0; }
[GIT pull] irq fixes for 4.8
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Three fixes for irq core and irq chip drivers - Do not set the irq type if type is NONE. Fixes a boot regression on various SoCs - Use the proper cpu for setting up the GIC target list. Discovered by the cpumask debugging code. - A rather large fix for the MIPS-GIC so per cpu local interrupts work again. This was discovered late because the code falls back to slower timers which use normal device interrupts. Thanks, tglx --> James Morse (1): irqchip/gicv3: Silence noisy DEBUG_PER_CPU_MAPS warning Marc Zyngier (1): genirq: Skip chained interrupt trigger setup if type is IRQ_TYPE_NONE Paul Burton (1): irqchip/mips-gic: Fix local interrupts drivers/irqchip/irq-gic-v3.c | 7 +-- drivers/irqchip/irq-mips-gic.c | 105 - kernel/irq/chip.c | 8 +++- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index ede5672ab34d..da6c0ba61d4f 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -548,7 +548,7 @@ static int gic_starting_cpu(unsigned int cpu) static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, unsigned long cluster_id) { - int cpu = *base_cpu; + int next_cpu, cpu = *base_cpu; unsigned long mpidr = cpu_logical_map(cpu); u16 tlist = 0; @@ -562,9 +562,10 @@ static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, tlist |= 1 << (mpidr & 0xf); - cpu = cpumask_next(cpu, mask); - if (cpu >= nr_cpu_ids) + next_cpu = cpumask_next(cpu, mask); + if (next_cpu >= nr_cpu_ids) goto out; + cpu = next_cpu; mpidr = cpu_logical_map(cpu); diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 83f498393a7f..6185696405d5 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -638,27 +638,6 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq, if (!gic_local_irq_is_routable(intr)) return -EPERM; - /* -* HACK: These are all really percpu interrupts, but the rest -* of the MIPS kernel code does not use the percpu IRQ API for -* the CP0 timer and performance counter interrupts. -*/ - switch (intr) { - case GIC_LOCAL_INT_TIMER: - case GIC_LOCAL_INT_PERFCTR: - case GIC_LOCAL_INT_FDC: - irq_set_chip_and_handler(virq, -_all_vpes_local_irq_controller, -handle_percpu_irq); - break; - default: - irq_set_chip_and_handler(virq, -_local_irq_controller, -handle_percpu_devid_irq); - irq_set_percpu_devid(virq); - break; - } - spin_lock_irqsave(_lock, flags); for (i = 0; i < gic_vpes; i++) { u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin; @@ -724,16 +703,42 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, return 0; } -static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, - irq_hw_number_t hw) +static int gic_setup_dev_chip(struct irq_domain *d, unsigned int virq, + unsigned int hwirq) { - if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS) - return gic_local_irq_domain_map(d, virq, hw); + struct irq_chip *chip; + int err; + + if (hwirq >= GIC_SHARED_HWIRQ_BASE) { + err = irq_domain_set_hwirq_and_chip(d, virq, hwirq, + _level_irq_controller, + NULL); + } else { + switch (GIC_HWIRQ_TO_LOCAL(hwirq)) { + case GIC_LOCAL_INT_TIMER: + case GIC_LOCAL_INT_PERFCTR: + case GIC_LOCAL_INT_FDC: + /* +* HACK: These are all really percpu interrupts, but +* the rest of the MIPS kernel code does not use the +* percpu IRQ API for them. +*/ + chip = _all_vpes_local_irq_controller; + irq_set_handler(virq, handle_percpu_irq); + break; + + default: + chip = _local_irq_controller; + irq_set_handler(virq, handle_percpu_devid_irq); +
[GIT pull] irq fixes for 4.8
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Three fixes for irq core and irq chip drivers - Do not set the irq type if type is NONE. Fixes a boot regression on various SoCs - Use the proper cpu for setting up the GIC target list. Discovered by the cpumask debugging code. - A rather large fix for the MIPS-GIC so per cpu local interrupts work again. This was discovered late because the code falls back to slower timers which use normal device interrupts. Thanks, tglx --> James Morse (1): irqchip/gicv3: Silence noisy DEBUG_PER_CPU_MAPS warning Marc Zyngier (1): genirq: Skip chained interrupt trigger setup if type is IRQ_TYPE_NONE Paul Burton (1): irqchip/mips-gic: Fix local interrupts drivers/irqchip/irq-gic-v3.c | 7 +-- drivers/irqchip/irq-mips-gic.c | 105 - kernel/irq/chip.c | 8 +++- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index ede5672ab34d..da6c0ba61d4f 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -548,7 +548,7 @@ static int gic_starting_cpu(unsigned int cpu) static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, unsigned long cluster_id) { - int cpu = *base_cpu; + int next_cpu, cpu = *base_cpu; unsigned long mpidr = cpu_logical_map(cpu); u16 tlist = 0; @@ -562,9 +562,10 @@ static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, tlist |= 1 << (mpidr & 0xf); - cpu = cpumask_next(cpu, mask); - if (cpu >= nr_cpu_ids) + next_cpu = cpumask_next(cpu, mask); + if (next_cpu >= nr_cpu_ids) goto out; + cpu = next_cpu; mpidr = cpu_logical_map(cpu); diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 83f498393a7f..6185696405d5 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -638,27 +638,6 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq, if (!gic_local_irq_is_routable(intr)) return -EPERM; - /* -* HACK: These are all really percpu interrupts, but the rest -* of the MIPS kernel code does not use the percpu IRQ API for -* the CP0 timer and performance counter interrupts. -*/ - switch (intr) { - case GIC_LOCAL_INT_TIMER: - case GIC_LOCAL_INT_PERFCTR: - case GIC_LOCAL_INT_FDC: - irq_set_chip_and_handler(virq, -_all_vpes_local_irq_controller, -handle_percpu_irq); - break; - default: - irq_set_chip_and_handler(virq, -_local_irq_controller, -handle_percpu_devid_irq); - irq_set_percpu_devid(virq); - break; - } - spin_lock_irqsave(_lock, flags); for (i = 0; i < gic_vpes; i++) { u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin; @@ -724,16 +703,42 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, return 0; } -static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, - irq_hw_number_t hw) +static int gic_setup_dev_chip(struct irq_domain *d, unsigned int virq, + unsigned int hwirq) { - if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS) - return gic_local_irq_domain_map(d, virq, hw); + struct irq_chip *chip; + int err; + + if (hwirq >= GIC_SHARED_HWIRQ_BASE) { + err = irq_domain_set_hwirq_and_chip(d, virq, hwirq, + _level_irq_controller, + NULL); + } else { + switch (GIC_HWIRQ_TO_LOCAL(hwirq)) { + case GIC_LOCAL_INT_TIMER: + case GIC_LOCAL_INT_PERFCTR: + case GIC_LOCAL_INT_FDC: + /* +* HACK: These are all really percpu interrupts, but +* the rest of the MIPS kernel code does not use the +* percpu IRQ API for them. +*/ + chip = _all_vpes_local_irq_controller; + irq_set_handler(virq, handle_percpu_irq); + break; + + default: + chip = _local_irq_controller; + irq_set_handler(virq, handle_percpu_devid_irq); +
Re: [GIT pull] irq fixes for 4.8
On Sun, 18 Sep 2016, Linus Torvalds wrote: > On Sun, Sep 18, 2016 at 1:05 AM, Thomas Gleixnerwrote: > > > > Boris Brezillon (2): > > genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers > > This seems somewhat questionable. > > The non-irqsafe versions of these functions have specialized non-SMP > versions for them. The new ones don't. > > I pulled it, because I think it's actually the old versions that are > garbage (the locking should become a no-op on UP regardless - except > for the preemption issue which I don't see why it wouldn't be real), > but I think this is inconsistent and should be fixed (or a comment > added about why it is ok). Yes, it lacks a comment. The reason why the non save versions are empty is that these primitives are solely used in the irq chip hotpath functions. UP folks wanted to avoid the preempt disable/enable in these anyway interrupt disabled contexts. Thanks, tglx
Re: [GIT pull] irq fixes for 4.8
On Sun, 18 Sep 2016, Linus Torvalds wrote: > On Sun, Sep 18, 2016 at 1:05 AM, Thomas Gleixner wrote: > > > > Boris Brezillon (2): > > genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers > > This seems somewhat questionable. > > The non-irqsafe versions of these functions have specialized non-SMP > versions for them. The new ones don't. > > I pulled it, because I think it's actually the old versions that are > garbage (the locking should become a no-op on UP regardless - except > for the preemption issue which I don't see why it wouldn't be real), > but I think this is inconsistent and should be fixed (or a comment > added about why it is ok). Yes, it lacks a comment. The reason why the non save versions are empty is that these primitives are solely used in the irq chip hotpath functions. UP folks wanted to avoid the preempt disable/enable in these anyway interrupt disabled contexts. Thanks, tglx
Re: [GIT pull] irq fixes for 4.8
On Sun, Sep 18, 2016 at 1:05 AM, Thomas Gleixnerwrote: > > Boris Brezillon (2): > genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers This seems somewhat questionable. The non-irqsafe versions of these functions have specialized non-SMP versions for them. The new ones don't. I pulled it, because I think it's actually the old versions that are garbage (the locking should become a no-op on UP regardless - except for the preemption issue which I don't see why it wouldn't be real), but I think this is inconsistent and should be fixed (or a comment added about why it is ok). Linus
Re: [GIT pull] irq fixes for 4.8
On Sun, Sep 18, 2016 at 1:05 AM, Thomas Gleixner wrote: > > Boris Brezillon (2): > genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers This seems somewhat questionable. The non-irqsafe versions of these functions have specialized non-SMP versions for them. The new ones don't. I pulled it, because I think it's actually the old versions that are garbage (the locking should become a no-op on UP regardless - except for the preemption issue which I don't see why it wouldn't be real), but I think this is inconsistent and should be fixed (or a comment added about why it is ok). Linus
[GIT pull] irq fixes for 4.8
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Two patches from Boris which address a potential deadlock in the atmel irq chip driver. Thanks, tglx --> Boris Brezillon (2): genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers irqchip/atmel-aic: Fix potential deadlock in ->xlate() drivers/irqchip/irq-atmel-aic.c | 5 +++-- drivers/irqchip/irq-atmel-aic5.c | 5 +++-- include/linux/irq.h | 10 ++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-atmel-aic.c b/drivers/irqchip/irq-atmel-aic.c index 112e17c2768b..37f952dd9fc9 100644 --- a/drivers/irqchip/irq-atmel-aic.c +++ b/drivers/irqchip/irq-atmel-aic.c @@ -176,6 +176,7 @@ static int aic_irq_domain_xlate(struct irq_domain *d, { struct irq_domain_chip_generic *dgc = d->gc; struct irq_chip_generic *gc; + unsigned long flags; unsigned smr; int idx; int ret; @@ -194,11 +195,11 @@ static int aic_irq_domain_xlate(struct irq_domain *d, gc = dgc->gc[idx]; - irq_gc_lock(gc); + irq_gc_lock_irqsave(gc, flags); smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq)); aic_common_set_priority(intspec[2], ); irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq)); - irq_gc_unlock(gc); + irq_gc_unlock_irqrestore(gc, flags); return ret; } diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c index 4f0d068e1abe..2a624d87a035 100644 --- a/drivers/irqchip/irq-atmel-aic5.c +++ b/drivers/irqchip/irq-atmel-aic5.c @@ -258,6 +258,7 @@ static int aic5_irq_domain_xlate(struct irq_domain *d, unsigned int *out_type) { struct irq_chip_generic *bgc = irq_get_domain_generic_chip(d, 0); + unsigned long flags; unsigned smr; int ret; @@ -269,12 +270,12 @@ static int aic5_irq_domain_xlate(struct irq_domain *d, if (ret) return ret; - irq_gc_lock(bgc); + irq_gc_lock_irqsave(bgc, flags); irq_reg_writel(bgc, *out_hwirq, AT91_AIC5_SSR); smr = irq_reg_readl(bgc, AT91_AIC5_SMR); aic_common_set_priority(intspec[2], ); irq_reg_writel(bgc, smr, AT91_AIC5_SMR); - irq_gc_unlock(bgc); + irq_gc_unlock_irqrestore(bgc, flags); return ret; } diff --git a/include/linux/irq.h b/include/linux/irq.h index b52424eaa0ed..0ac26c892fe2 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -945,6 +945,16 @@ static inline void irq_gc_lock(struct irq_chip_generic *gc) { } static inline void irq_gc_unlock(struct irq_chip_generic *gc) { } #endif +/* + * The irqsave variants are for usage in non interrupt code. Do not use + * them in irq_chip callbacks. Use irq_gc_lock() instead. + */ +#define irq_gc_lock_irqsave(gc, flags) \ + raw_spin_lock_irqsave(&(gc)->lock, flags) + +#define irq_gc_unlock_irqrestore(gc, flags)\ + raw_spin_unlock_irqrestore(&(gc)->lock, flags) + static inline void irq_reg_writel(struct irq_chip_generic *gc, u32 val, int reg_offset) {
[GIT pull] irq fixes for 4.8
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Two patches from Boris which address a potential deadlock in the atmel irq chip driver. Thanks, tglx --> Boris Brezillon (2): genirq: Provide irq_gc_{lock_irqsave,unlock_irqrestore}() helpers irqchip/atmel-aic: Fix potential deadlock in ->xlate() drivers/irqchip/irq-atmel-aic.c | 5 +++-- drivers/irqchip/irq-atmel-aic5.c | 5 +++-- include/linux/irq.h | 10 ++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-atmel-aic.c b/drivers/irqchip/irq-atmel-aic.c index 112e17c2768b..37f952dd9fc9 100644 --- a/drivers/irqchip/irq-atmel-aic.c +++ b/drivers/irqchip/irq-atmel-aic.c @@ -176,6 +176,7 @@ static int aic_irq_domain_xlate(struct irq_domain *d, { struct irq_domain_chip_generic *dgc = d->gc; struct irq_chip_generic *gc; + unsigned long flags; unsigned smr; int idx; int ret; @@ -194,11 +195,11 @@ static int aic_irq_domain_xlate(struct irq_domain *d, gc = dgc->gc[idx]; - irq_gc_lock(gc); + irq_gc_lock_irqsave(gc, flags); smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq)); aic_common_set_priority(intspec[2], ); irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq)); - irq_gc_unlock(gc); + irq_gc_unlock_irqrestore(gc, flags); return ret; } diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c index 4f0d068e1abe..2a624d87a035 100644 --- a/drivers/irqchip/irq-atmel-aic5.c +++ b/drivers/irqchip/irq-atmel-aic5.c @@ -258,6 +258,7 @@ static int aic5_irq_domain_xlate(struct irq_domain *d, unsigned int *out_type) { struct irq_chip_generic *bgc = irq_get_domain_generic_chip(d, 0); + unsigned long flags; unsigned smr; int ret; @@ -269,12 +270,12 @@ static int aic5_irq_domain_xlate(struct irq_domain *d, if (ret) return ret; - irq_gc_lock(bgc); + irq_gc_lock_irqsave(bgc, flags); irq_reg_writel(bgc, *out_hwirq, AT91_AIC5_SSR); smr = irq_reg_readl(bgc, AT91_AIC5_SMR); aic_common_set_priority(intspec[2], ); irq_reg_writel(bgc, smr, AT91_AIC5_SMR); - irq_gc_unlock(bgc); + irq_gc_unlock_irqrestore(bgc, flags); return ret; } diff --git a/include/linux/irq.h b/include/linux/irq.h index b52424eaa0ed..0ac26c892fe2 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -945,6 +945,16 @@ static inline void irq_gc_lock(struct irq_chip_generic *gc) { } static inline void irq_gc_unlock(struct irq_chip_generic *gc) { } #endif +/* + * The irqsave variants are for usage in non interrupt code. Do not use + * them in irq_chip callbacks. Use irq_gc_lock() instead. + */ +#define irq_gc_lock_irqsave(gc, flags) \ + raw_spin_lock_irqsave(&(gc)->lock, flags) + +#define irq_gc_unlock_irqrestore(gc, flags)\ + raw_spin_unlock_irqrestore(&(gc)->lock, flags) + static inline void irq_reg_writel(struct irq_chip_generic *gc, u32 val, int reg_offset) {
[GIT pull] irq fixes for 4.8
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus This lot provides: - Plug a hotplug race in the new affinity infrastructure - A fix for the trigger type of chained interrupts - Plug a potential memory leak in the core code - A few fixes for ARM and MIPS GICs Thanks, tglx --> Christoph Hellwig (1): genirq/affinity: Use get/put_online_cpus around cpumask operations David Daney (1): irqchip/gicv3-its: Disable the ITS before initializing it Marc Zyngier (2): genirq: Correctly configure the trigger on chained interrupts irqchip/gic: Allow self-SGIs for SMP on UP configurations Paul Burton (2): irqchip/mips-gic: Cleanup chip and handler setup irqchip/mips-gic: Implement activate op for device domain Shawn Lin (1): genirq: Fix potential memleak when failing to get irq pm Sudeep Holla (1): irqchip/gicv3: Remove disabling redistributor and group1 non-secure interrupts drivers/irqchip/irq-gic-v3-its.c | 7 ++- drivers/irqchip/irq-gic-v3.c | 11 +-- drivers/irqchip/irq-gic.c| 7 +++ drivers/irqchip/irq-mips-gic.c | 18 ++ kernel/irq/affinity.c| 2 ++ kernel/irq/chip.c| 11 +++ kernel/irq/manage.c | 8 ++-- 7 files changed, 55 insertions(+), 9 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 7ceaba81efb4..36b9c28a5c91 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1545,7 +1545,12 @@ static int its_force_quiescent(void __iomem *base) u32 val; val = readl_relaxed(base + GITS_CTLR); - if (val & GITS_CTLR_QUIESCENT) + /* +* GIC architecture specification requires the ITS to be both +* disabled and quiescent for writes to GITS_BASER or +* GITS_CBASER to not have UNPREDICTABLE results. +*/ + if ((val & GITS_CTLR_QUIESCENT) && !(val & GITS_CTLR_ENABLE)) return 0; /* Disable the generation of all interrupts to this ITS */ diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 6fc56c3466b0..ede5672ab34d 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -667,13 +667,20 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, #endif #ifdef CONFIG_CPU_PM +/* Check whether it's single security state view */ +static bool gic_dist_security_disabled(void) +{ + return readl_relaxed(gic_data.dist_base + GICD_CTLR) & GICD_CTLR_DS; +} + static int gic_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd, void *v) { if (cmd == CPU_PM_EXIT) { - gic_enable_redist(true); + if (gic_dist_security_disabled()) + gic_enable_redist(true); gic_cpu_sys_reg_init(); - } else if (cmd == CPU_PM_ENTER) { + } else if (cmd == CPU_PM_ENTER && gic_dist_security_disabled()) { gic_write_grpen1(0); gic_enable_redist(false); } diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index c2cab572c511..390fac59c6bc 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -769,6 +769,13 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) int cpu; unsigned long flags, map = 0; + if (unlikely(nr_cpu_ids == 1)) { + /* Only one CPU? let's do a self-IPI... */ + writel_relaxed(2 << 24 | irq, + gic_data_dist_base(_data[0]) + GIC_DIST_SOFTINT); + return; + } + raw_spin_lock_irqsave(_controller_lock, flags); /* Convert our logical CPU mask into a physical one. */ diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index c5f33c3bd228..83f498393a7f 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -713,9 +713,6 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, unsigned long flags; int i; - irq_set_chip_and_handler(virq, _level_irq_controller, -handle_level_irq); - spin_lock_irqsave(_lock, flags); gic_map_to_pin(intr, gic_cpu_pin); gic_map_to_vpe(intr, mips_cm_vp_id(vpe)); @@ -732,6 +729,10 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, { if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS) return gic_local_irq_domain_map(d, virq, hw); + + irq_set_chip_and_handler(virq, _level_irq_controller, +handle_level_irq); + return gic_shared_irq_domain_map(d, virq, hw, 0); } @@ -771,11 +772,13 @@ static int
[GIT pull] irq fixes for 4.8
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus This lot provides: - Plug a hotplug race in the new affinity infrastructure - A fix for the trigger type of chained interrupts - Plug a potential memory leak in the core code - A few fixes for ARM and MIPS GICs Thanks, tglx --> Christoph Hellwig (1): genirq/affinity: Use get/put_online_cpus around cpumask operations David Daney (1): irqchip/gicv3-its: Disable the ITS before initializing it Marc Zyngier (2): genirq: Correctly configure the trigger on chained interrupts irqchip/gic: Allow self-SGIs for SMP on UP configurations Paul Burton (2): irqchip/mips-gic: Cleanup chip and handler setup irqchip/mips-gic: Implement activate op for device domain Shawn Lin (1): genirq: Fix potential memleak when failing to get irq pm Sudeep Holla (1): irqchip/gicv3: Remove disabling redistributor and group1 non-secure interrupts drivers/irqchip/irq-gic-v3-its.c | 7 ++- drivers/irqchip/irq-gic-v3.c | 11 +-- drivers/irqchip/irq-gic.c| 7 +++ drivers/irqchip/irq-mips-gic.c | 18 ++ kernel/irq/affinity.c| 2 ++ kernel/irq/chip.c| 11 +++ kernel/irq/manage.c | 8 ++-- 7 files changed, 55 insertions(+), 9 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 7ceaba81efb4..36b9c28a5c91 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1545,7 +1545,12 @@ static int its_force_quiescent(void __iomem *base) u32 val; val = readl_relaxed(base + GITS_CTLR); - if (val & GITS_CTLR_QUIESCENT) + /* +* GIC architecture specification requires the ITS to be both +* disabled and quiescent for writes to GITS_BASER or +* GITS_CBASER to not have UNPREDICTABLE results. +*/ + if ((val & GITS_CTLR_QUIESCENT) && !(val & GITS_CTLR_ENABLE)) return 0; /* Disable the generation of all interrupts to this ITS */ diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 6fc56c3466b0..ede5672ab34d 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -667,13 +667,20 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, #endif #ifdef CONFIG_CPU_PM +/* Check whether it's single security state view */ +static bool gic_dist_security_disabled(void) +{ + return readl_relaxed(gic_data.dist_base + GICD_CTLR) & GICD_CTLR_DS; +} + static int gic_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd, void *v) { if (cmd == CPU_PM_EXIT) { - gic_enable_redist(true); + if (gic_dist_security_disabled()) + gic_enable_redist(true); gic_cpu_sys_reg_init(); - } else if (cmd == CPU_PM_ENTER) { + } else if (cmd == CPU_PM_ENTER && gic_dist_security_disabled()) { gic_write_grpen1(0); gic_enable_redist(false); } diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index c2cab572c511..390fac59c6bc 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -769,6 +769,13 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) int cpu; unsigned long flags, map = 0; + if (unlikely(nr_cpu_ids == 1)) { + /* Only one CPU? let's do a self-IPI... */ + writel_relaxed(2 << 24 | irq, + gic_data_dist_base(_data[0]) + GIC_DIST_SOFTINT); + return; + } + raw_spin_lock_irqsave(_controller_lock, flags); /* Convert our logical CPU mask into a physical one. */ diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index c5f33c3bd228..83f498393a7f 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -713,9 +713,6 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, unsigned long flags; int i; - irq_set_chip_and_handler(virq, _level_irq_controller, -handle_level_irq); - spin_lock_irqsave(_lock, flags); gic_map_to_pin(intr, gic_cpu_pin); gic_map_to_vpe(intr, mips_cm_vp_id(vpe)); @@ -732,6 +729,10 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, { if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS) return gic_local_irq_domain_map(d, virq, hw); + + irq_set_chip_and_handler(virq, _level_irq_controller, +handle_level_irq); + return gic_shared_irq_domain_map(d, virq, hw, 0); } @@ -771,11 +772,13 @@ static int
[GIT PULL] irq fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 547aefc4db877e65245c3d95fcce703701bf3a0c irqchip/mips-gic: Match IPI IRQ domain by bus token only Two MIPS-GIC irqchip driver fixes to unbreak certain MIPS boards. Thanks, Ingo --> Paul Burton (2): irqchip/mips-gic: Map to VPs using HW VPNum irqchip/mips-gic: Match IPI IRQ domain by bus token only drivers/irqchip/irq-mips-gic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 8a4adbeb2b8c..70ed1d0151b8 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -718,7 +718,7 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, spin_lock_irqsave(_lock, flags); gic_map_to_pin(intr, gic_cpu_pin); - gic_map_to_vpe(intr, vpe); + gic_map_to_vpe(intr, mips_cm_vp_id(vpe)); for (i = 0; i < min(gic_vpes, NR_CPUS); i++) clear_bit(intr, pcpu_masks[i].pcpu_mask); set_bit(intr, pcpu_masks[vpe].pcpu_mask); @@ -959,7 +959,7 @@ int gic_ipi_domain_match(struct irq_domain *d, struct device_node *node, switch (bus_token) { case DOMAIN_BUS_IPI: is_ipi = d->bus_token == bus_token; - return to_of_node(d->fwnode) == node && is_ipi; + return (!node || to_of_node(d->fwnode) == node) && is_ipi; break; default: return 0;
[GIT PULL] irq fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 547aefc4db877e65245c3d95fcce703701bf3a0c irqchip/mips-gic: Match IPI IRQ domain by bus token only Two MIPS-GIC irqchip driver fixes to unbreak certain MIPS boards. Thanks, Ingo --> Paul Burton (2): irqchip/mips-gic: Map to VPs using HW VPNum irqchip/mips-gic: Match IPI IRQ domain by bus token only drivers/irqchip/irq-mips-gic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 8a4adbeb2b8c..70ed1d0151b8 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -718,7 +718,7 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, spin_lock_irqsave(_lock, flags); gic_map_to_pin(intr, gic_cpu_pin); - gic_map_to_vpe(intr, vpe); + gic_map_to_vpe(intr, mips_cm_vp_id(vpe)); for (i = 0; i < min(gic_vpes, NR_CPUS); i++) clear_bit(intr, pcpu_masks[i].pcpu_mask); set_bit(intr, pcpu_masks[vpe].pcpu_mask); @@ -959,7 +959,7 @@ int gic_ipi_domain_match(struct irq_domain *d, struct device_node *node, switch (bus_token) { case DOMAIN_BUS_IPI: is_ipi = d->bus_token == bus_token; - return to_of_node(d->fwnode) == node && is_ipi; + return (!node || to_of_node(d->fwnode) == node) && is_ipi; break; default: return 0;
[GIT PULL] irq fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 91951f980e521d8f7e92283735b99fb9f4b05d93 irqchip/mips-gic: Don't overrun pcpu_masks array A core irq affinity masks related fix and a MIPS irqchip driver fix. Thanks, Ingo --> Matt Redfearn (1): genirq: Dont allow affinity mask to be updated on IPIs Paul Burton (1): irqchip/mips-gic: Don't overrun pcpu_masks array drivers/irqchip/irq-mips-gic.c | 4 ++-- kernel/irq/ipi.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 94a30da0cfac..4dffccf532a2 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -467,7 +467,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, gic_map_to_vpe(irq, mips_cm_vp_id(cpumask_first())); /* Update the pcpu_masks */ - for (i = 0; i < gic_vpes; i++) + for (i = 0; i < min(gic_vpes, NR_CPUS); i++) clear_bit(irq, pcpu_masks[i].pcpu_mask); set_bit(irq, pcpu_masks[cpumask_first()].pcpu_mask); @@ -707,7 +707,7 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, spin_lock_irqsave(_lock, flags); gic_map_to_pin(intr, gic_cpu_pin); gic_map_to_vpe(intr, vpe); - for (i = 0; i < gic_vpes; i++) + for (i = 0; i < min(gic_vpes, NR_CPUS); i++) clear_bit(intr, pcpu_masks[i].pcpu_mask); set_bit(intr, pcpu_masks[vpe].pcpu_mask); spin_unlock_irqrestore(_lock, flags); diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c index c37f34b00a11..14777af8e097 100644 --- a/kernel/irq/ipi.c +++ b/kernel/irq/ipi.c @@ -94,6 +94,7 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain, data = irq_get_irq_data(virq + i); cpumask_copy(data->common->affinity, dest); data->common->ipi_offset = offset; + irq_set_status_flags(virq + i, IRQ_NO_BALANCING); } return virq;
[GIT PULL] irq fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 91951f980e521d8f7e92283735b99fb9f4b05d93 irqchip/mips-gic: Don't overrun pcpu_masks array A core irq affinity masks related fix and a MIPS irqchip driver fix. Thanks, Ingo --> Matt Redfearn (1): genirq: Dont allow affinity mask to be updated on IPIs Paul Burton (1): irqchip/mips-gic: Don't overrun pcpu_masks array drivers/irqchip/irq-mips-gic.c | 4 ++-- kernel/irq/ipi.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index 94a30da0cfac..4dffccf532a2 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -467,7 +467,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, gic_map_to_vpe(irq, mips_cm_vp_id(cpumask_first())); /* Update the pcpu_masks */ - for (i = 0; i < gic_vpes; i++) + for (i = 0; i < min(gic_vpes, NR_CPUS); i++) clear_bit(irq, pcpu_masks[i].pcpu_mask); set_bit(irq, pcpu_masks[cpumask_first()].pcpu_mask); @@ -707,7 +707,7 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, spin_lock_irqsave(_lock, flags); gic_map_to_pin(intr, gic_cpu_pin); gic_map_to_vpe(intr, vpe); - for (i = 0; i < gic_vpes; i++) + for (i = 0; i < min(gic_vpes, NR_CPUS); i++) clear_bit(intr, pcpu_masks[i].pcpu_mask); set_bit(intr, pcpu_masks[vpe].pcpu_mask); spin_unlock_irqrestore(_lock, flags); diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c index c37f34b00a11..14777af8e097 100644 --- a/kernel/irq/ipi.c +++ b/kernel/irq/ipi.c @@ -94,6 +94,7 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain, data = irq_get_irq_data(virq + i); cpumask_copy(data->common->affinity, dest); data->common->ipi_offset = offset; + irq_set_status_flags(virq + i, IRQ_NO_BALANCING); } return virq;
[GIT pull] irq fixes for 4.6
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A small set of fixes for the usual ARM/SOC irqchip drivers - A set of fixes for mbigen to handle multiple devices in a hardware module proper - A cleanup for the mbigen config option which was pointlessly user configurable. - A cleanup for tegra replacing open coded functionality by the proper core function The config cleanup touches arch/arm64/Kconfig.platforms to select the irq chip for the related platform. Thanks, tglx --> Axel Lin (1): irqchip/tegra: Switch to use irq_domain_free_irqs_common MaJun (4): irqchip/mbigen: Adjust DT bindings to handle multiple devices in a module irqchip/mbigen: Handle multiple device nodes in a mbigen module ARM64: Kconfig: Select mbigen interrupt controller on Hisilicon platform irqchip/mbigen: Make CONFIG_HISILICON_IRQ_MBIGEN a hidden option .../interrupt-controller/hisilicon,mbigen-v2.txt | 22 ++--- arch/arm64/Kconfig.platforms | 1 + drivers/irqchip/Kconfig| 14 drivers/irqchip/irq-mbigen.c | 38 ++ drivers/irqchip/irq-tegra.c| 14 +--- 5 files changed, 49 insertions(+), 40 deletions(-) diff --git a/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt b/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt index 720f7c92e9a1..3b2f4c43ad8d 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt @@ -21,6 +21,8 @@ Mbigen main node required properties: - reg: Specifies the base physical address and size of the Mbigen registers. +Mbigen sub node required properties: +-- - interrupt controller: Identifies the node as an interrupt controller - msi-parent: Specifies the MSI controller this mbigen use. @@ -45,13 +47,23 @@ Mbigen main node required properties: Examples: - mbigen_device_gmac:intc { + mbigen_chip_dsa { compatible = "hisilicon,mbigen-v2"; reg = <0x0 0xc008 0x0 0x1>; - interrupt-controller; - msi-parent = <_dsa 0x40b1c>; - num-pins = <9>; - #interrupt-cells = <2>; + + mbigen_gmac:intc_gmac { + interrupt-controller; + msi-parent = <_dsa 0x40b1c>; + num-pins = <9>; + #interrupt-cells = <2>; + }; + + mbigen_i2c:intc_i2c { + interrupt-controller; + msi-parent = <_dsa 0x40b0e>; + num-pins = <2>; + #interrupt-cells = <2>; + }; }; Devices connect to mbigen required properties: diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 21074f674bde..fdfd526871dc 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -37,6 +37,7 @@ config ARCH_LAYERSCAPE config ARCH_HISI bool "Hisilicon SoC Family" + select HISILICON_IRQ_MBIGEN help This enables support for Hisilicon ARMv8 SoC family diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 7e8c441ff2de..3e124793e224 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -32,14 +32,6 @@ config ARM_GIC_V3_ITS bool select PCI_MSI_IRQ_DOMAIN -config HISILICON_IRQ_MBIGEN - bool "Support mbigen interrupt controller" - default n - depends on ARM_GIC_V3 && ARM_GIC_V3_ITS && GENERIC_MSI_IRQ_DOMAIN - help -Enable the mbigen interrupt controller used on -Hisilicon platform. - config ARM_NVIC bool select IRQ_DOMAIN @@ -114,6 +106,12 @@ config DW_APB_ICTL select GENERIC_IRQ_CHIP select IRQ_DOMAIN +config HISILICON_IRQ_MBIGEN + bool + select ARM_GIC_V3 + select ARM_GIC_V3_ITS + select GENERIC_MSI_IRQ_DOMAIN + config IMGPDC_IRQ bool select GENERIC_IRQ_CHIP diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c index 4dd3eb8a40b3..d67baa231c13 100644 --- a/drivers/irqchip/irq-mbigen.c +++ b/drivers/irqchip/irq-mbigen.c @@ -239,8 +239,11 @@ static struct irq_domain_ops mbigen_domain_ops = { static int mbigen_device_probe(struct platform_device *pdev) { struct mbigen_device *mgn_chip; - struct resource *res; + struct platform_device *child; struct irq_domain *domain; +
[GIT pull] irq fixes for 4.6
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A small set of fixes for the usual ARM/SOC irqchip drivers - A set of fixes for mbigen to handle multiple devices in a hardware module proper - A cleanup for the mbigen config option which was pointlessly user configurable. - A cleanup for tegra replacing open coded functionality by the proper core function The config cleanup touches arch/arm64/Kconfig.platforms to select the irq chip for the related platform. Thanks, tglx --> Axel Lin (1): irqchip/tegra: Switch to use irq_domain_free_irqs_common MaJun (4): irqchip/mbigen: Adjust DT bindings to handle multiple devices in a module irqchip/mbigen: Handle multiple device nodes in a mbigen module ARM64: Kconfig: Select mbigen interrupt controller on Hisilicon platform irqchip/mbigen: Make CONFIG_HISILICON_IRQ_MBIGEN a hidden option .../interrupt-controller/hisilicon,mbigen-v2.txt | 22 ++--- arch/arm64/Kconfig.platforms | 1 + drivers/irqchip/Kconfig| 14 drivers/irqchip/irq-mbigen.c | 38 ++ drivers/irqchip/irq-tegra.c| 14 +--- 5 files changed, 49 insertions(+), 40 deletions(-) diff --git a/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt b/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt index 720f7c92e9a1..3b2f4c43ad8d 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt @@ -21,6 +21,8 @@ Mbigen main node required properties: - reg: Specifies the base physical address and size of the Mbigen registers. +Mbigen sub node required properties: +-- - interrupt controller: Identifies the node as an interrupt controller - msi-parent: Specifies the MSI controller this mbigen use. @@ -45,13 +47,23 @@ Mbigen main node required properties: Examples: - mbigen_device_gmac:intc { + mbigen_chip_dsa { compatible = "hisilicon,mbigen-v2"; reg = <0x0 0xc008 0x0 0x1>; - interrupt-controller; - msi-parent = <_dsa 0x40b1c>; - num-pins = <9>; - #interrupt-cells = <2>; + + mbigen_gmac:intc_gmac { + interrupt-controller; + msi-parent = <_dsa 0x40b1c>; + num-pins = <9>; + #interrupt-cells = <2>; + }; + + mbigen_i2c:intc_i2c { + interrupt-controller; + msi-parent = <_dsa 0x40b0e>; + num-pins = <2>; + #interrupt-cells = <2>; + }; }; Devices connect to mbigen required properties: diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 21074f674bde..fdfd526871dc 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -37,6 +37,7 @@ config ARCH_LAYERSCAPE config ARCH_HISI bool "Hisilicon SoC Family" + select HISILICON_IRQ_MBIGEN help This enables support for Hisilicon ARMv8 SoC family diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 7e8c441ff2de..3e124793e224 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -32,14 +32,6 @@ config ARM_GIC_V3_ITS bool select PCI_MSI_IRQ_DOMAIN -config HISILICON_IRQ_MBIGEN - bool "Support mbigen interrupt controller" - default n - depends on ARM_GIC_V3 && ARM_GIC_V3_ITS && GENERIC_MSI_IRQ_DOMAIN - help -Enable the mbigen interrupt controller used on -Hisilicon platform. - config ARM_NVIC bool select IRQ_DOMAIN @@ -114,6 +106,12 @@ config DW_APB_ICTL select GENERIC_IRQ_CHIP select IRQ_DOMAIN +config HISILICON_IRQ_MBIGEN + bool + select ARM_GIC_V3 + select ARM_GIC_V3_ITS + select GENERIC_MSI_IRQ_DOMAIN + config IMGPDC_IRQ bool select GENERIC_IRQ_CHIP diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c index 4dd3eb8a40b3..d67baa231c13 100644 --- a/drivers/irqchip/irq-mbigen.c +++ b/drivers/irqchip/irq-mbigen.c @@ -239,8 +239,11 @@ static struct irq_domain_ops mbigen_domain_ops = { static int mbigen_device_probe(struct platform_device *pdev) { struct mbigen_device *mgn_chip; - struct resource *res; + struct platform_device *child; struct irq_domain *domain; +
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: c5b635203032462603c503ecce91a7021c1ad44a irqchip/mxs: Add missing set_handle_irq() Mostly driver fixes, but also an irq core crash fix and a build fix. Thanks, Ingo --> Arnd Bergmann (1): irqchip/s3c24xx: Mark init_eint as __maybe_unused Marc Zyngier (3): irqdomain: Allow domain lookup with DOMAIN_BUS_WIRED token of: MSI: Simplify irqdomain lookup irqchip/gic-v3-its: Recompute the number of pages on page size change Milo Kim (1): irqchip/atmel-aic: Fix wrong bit operation for IRQ priority Oleksij Rempel (1): irqchip/mxs: Add missing set_handle_irq() Richard Weinberger (1): irqchip: Fix dependencies for archs w/o HAS_IOMEM Thomas Gleixner (1): genirq: Validate action before dereferencing it in handle_irq_event_percpu() Thomas Petazzoni (1): base: Export platform_msi_domain_[alloc,free]_irqs drivers/base/platform-msi.c| 2 ++ drivers/irqchip/Kconfig| 1 + drivers/irqchip/irq-atmel-aic-common.c | 2 +- drivers/irqchip/irq-gic-v3-its.c | 8 ++-- drivers/irqchip/irq-mxs.c | 1 + drivers/irqchip/irq-s3c24xx.c | 2 +- drivers/of/irq.c | 18 +++--- include/linux/irqdomain.h | 1 + kernel/irq/handle.c| 5 +++-- kernel/irq/irqdomain.c | 11 --- 10 files changed, 27 insertions(+), 24 deletions(-) diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c index 47c43386786b..279e53989374 100644 --- a/drivers/base/platform-msi.c +++ b/drivers/base/platform-msi.c @@ -284,6 +284,7 @@ int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec, return err; } +EXPORT_SYMBOL_GPL(platform_msi_domain_alloc_irqs); /** * platform_msi_domain_free_irqs - Free MSI interrupts for @dev @@ -301,6 +302,7 @@ void platform_msi_domain_free_irqs(struct device *dev) msi_domain_free_irqs(dev->msi_domain, dev); platform_msi_free_descs(dev, 0, MAX_DEV_MSIS); } +EXPORT_SYMBOL_GPL(platform_msi_domain_free_irqs); /** * platform_msi_get_host_data - Query the private data associated with diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 11fc2a27fa2e..90ab59107830 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -154,6 +154,7 @@ config TB10X_IRQC config TS4800_IRQ tristate "TS-4800 IRQ controller" select IRQ_DOMAIN + depends on HAS_IOMEM help Support for the TS-4800 FPGA IRQ controller diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c index b12a5d58546f..37199b9b2cfa 100644 --- a/drivers/irqchip/irq-atmel-aic-common.c +++ b/drivers/irqchip/irq-atmel-aic-common.c @@ -86,7 +86,7 @@ int aic_common_set_priority(int priority, unsigned *val) priority > AT91_AIC_IRQ_MAX_PRIORITY) return -EINVAL; - *val &= AT91_AIC_PRIOR; + *val &= ~AT91_AIC_PRIOR; *val |= priority; return 0; diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index e23d1d18f9d6..3447549fcc93 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -875,6 +875,7 @@ static int its_alloc_tables(const char *node_name, struct its_node *its) } alloc_size = (1 << order) * PAGE_SIZE; +retry_alloc_baser: alloc_pages = (alloc_size / psz); if (alloc_pages > GITS_BASER_PAGES_MAX) { alloc_pages = GITS_BASER_PAGES_MAX; @@ -938,13 +939,16 @@ static int its_alloc_tables(const char *node_name, struct its_node *its) * size and retry. If we reach 4K, then * something is horribly wrong... */ + free_pages((unsigned long)base, order); + its->tables[i] = NULL; + switch (psz) { case SZ_16K: psz = SZ_4K; - goto retry_baser; + goto retry_alloc_baser; case SZ_64K: psz = SZ_16K; - goto retry_baser; + goto retry_alloc_baser; } } diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c index c22e2d40cb30..efe50845939d 100644 --- a/drivers/irqchip/irq-mxs.c +++ b/drivers/irqchip/irq-mxs.c @@ -241,6 +241,7 @@ static int __init asm9260_of_init(struct device_node *np, writel(0, icoll_priv.intr + i); icoll_add_domain(np, ASM9260_NUM_IRQS); +
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: c5b635203032462603c503ecce91a7021c1ad44a irqchip/mxs: Add missing set_handle_irq() Mostly driver fixes, but also an irq core crash fix and a build fix. Thanks, Ingo --> Arnd Bergmann (1): irqchip/s3c24xx: Mark init_eint as __maybe_unused Marc Zyngier (3): irqdomain: Allow domain lookup with DOMAIN_BUS_WIRED token of: MSI: Simplify irqdomain lookup irqchip/gic-v3-its: Recompute the number of pages on page size change Milo Kim (1): irqchip/atmel-aic: Fix wrong bit operation for IRQ priority Oleksij Rempel (1): irqchip/mxs: Add missing set_handle_irq() Richard Weinberger (1): irqchip: Fix dependencies for archs w/o HAS_IOMEM Thomas Gleixner (1): genirq: Validate action before dereferencing it in handle_irq_event_percpu() Thomas Petazzoni (1): base: Export platform_msi_domain_[alloc,free]_irqs drivers/base/platform-msi.c| 2 ++ drivers/irqchip/Kconfig| 1 + drivers/irqchip/irq-atmel-aic-common.c | 2 +- drivers/irqchip/irq-gic-v3-its.c | 8 ++-- drivers/irqchip/irq-mxs.c | 1 + drivers/irqchip/irq-s3c24xx.c | 2 +- drivers/of/irq.c | 18 +++--- include/linux/irqdomain.h | 1 + kernel/irq/handle.c| 5 +++-- kernel/irq/irqdomain.c | 11 --- 10 files changed, 27 insertions(+), 24 deletions(-) diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c index 47c43386786b..279e53989374 100644 --- a/drivers/base/platform-msi.c +++ b/drivers/base/platform-msi.c @@ -284,6 +284,7 @@ int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec, return err; } +EXPORT_SYMBOL_GPL(platform_msi_domain_alloc_irqs); /** * platform_msi_domain_free_irqs - Free MSI interrupts for @dev @@ -301,6 +302,7 @@ void platform_msi_domain_free_irqs(struct device *dev) msi_domain_free_irqs(dev->msi_domain, dev); platform_msi_free_descs(dev, 0, MAX_DEV_MSIS); } +EXPORT_SYMBOL_GPL(platform_msi_domain_free_irqs); /** * platform_msi_get_host_data - Query the private data associated with diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 11fc2a27fa2e..90ab59107830 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -154,6 +154,7 @@ config TB10X_IRQC config TS4800_IRQ tristate "TS-4800 IRQ controller" select IRQ_DOMAIN + depends on HAS_IOMEM help Support for the TS-4800 FPGA IRQ controller diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c index b12a5d58546f..37199b9b2cfa 100644 --- a/drivers/irqchip/irq-atmel-aic-common.c +++ b/drivers/irqchip/irq-atmel-aic-common.c @@ -86,7 +86,7 @@ int aic_common_set_priority(int priority, unsigned *val) priority > AT91_AIC_IRQ_MAX_PRIORITY) return -EINVAL; - *val &= AT91_AIC_PRIOR; + *val &= ~AT91_AIC_PRIOR; *val |= priority; return 0; diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index e23d1d18f9d6..3447549fcc93 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -875,6 +875,7 @@ static int its_alloc_tables(const char *node_name, struct its_node *its) } alloc_size = (1 << order) * PAGE_SIZE; +retry_alloc_baser: alloc_pages = (alloc_size / psz); if (alloc_pages > GITS_BASER_PAGES_MAX) { alloc_pages = GITS_BASER_PAGES_MAX; @@ -938,13 +939,16 @@ static int its_alloc_tables(const char *node_name, struct its_node *its) * size and retry. If we reach 4K, then * something is horribly wrong... */ + free_pages((unsigned long)base, order); + its->tables[i] = NULL; + switch (psz) { case SZ_16K: psz = SZ_4K; - goto retry_baser; + goto retry_alloc_baser; case SZ_64K: psz = SZ_16K; - goto retry_baser; + goto retry_alloc_baser; } } diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c index c22e2d40cb30..efe50845939d 100644 --- a/drivers/irqchip/irq-mxs.c +++ b/drivers/irqchip/irq-mxs.c @@ -241,6 +241,7 @@ static int __init asm9260_of_init(struct device_node *np, writel(0, icoll_priv.intr + i); icoll_add_domain(np, ASM9260_NUM_IRQS); +
[GIT pull] irq fixes for 4.4
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Two trivial fixes which add missing header fileas and forward declarations so the code will compile even when the magic include chains are different. Thanks, tglx --> Marc Zyngier (2): irqchip/gic-v3: Add missing struct device_node declaration irqchip/gic-v3: Add missing include for barrier.h arch/arm/include/asm/arch_gicv3.h | 1 + arch/arm64/include/asm/arch_gicv3.h | 1 + include/linux/irqchip/arm-gic-v3.h | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h index 6607d976e07d..7da5503c0591 100644 --- a/arch/arm/include/asm/arch_gicv3.h +++ b/arch/arm/include/asm/arch_gicv3.h @@ -21,6 +21,7 @@ #ifndef __ASSEMBLY__ #include +#include #define __ACCESS_CP15(CRn, Op1, CRm, Op2) p15, Op1, %0, CRn, CRm, Op2 #define __ACCESS_CP15_64(Op1, CRm) p15, Op1, %Q0, %R0, CRm diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h index 030cdcb46c6b..2731d3b25ed2 100644 --- a/arch/arm64/include/asm/arch_gicv3.h +++ b/arch/arm64/include/asm/arch_gicv3.h @@ -77,6 +77,7 @@ #ifndef __ASSEMBLY__ #include +#include /* * Low-level accessors diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index c9ae0c6ec050..d5d798b35c1f 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -330,6 +330,7 @@ struct rdists { }; struct irq_domain; +struct device_node; int its_cpu_init(void); int its_init(struct device_node *node, struct rdists *rdists, struct irq_domain *domain); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 4.4
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Two trivial fixes which add missing header fileas and forward declarations so the code will compile even when the magic include chains are different. Thanks, tglx --> Marc Zyngier (2): irqchip/gic-v3: Add missing struct device_node declaration irqchip/gic-v3: Add missing include for barrier.h arch/arm/include/asm/arch_gicv3.h | 1 + arch/arm64/include/asm/arch_gicv3.h | 1 + include/linux/irqchip/arm-gic-v3.h | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h index 6607d976e07d..7da5503c0591 100644 --- a/arch/arm/include/asm/arch_gicv3.h +++ b/arch/arm/include/asm/arch_gicv3.h @@ -21,6 +21,7 @@ #ifndef __ASSEMBLY__ #include +#include #define __ACCESS_CP15(CRn, Op1, CRm, Op2) p15, Op1, %0, CRn, CRm, Op2 #define __ACCESS_CP15_64(Op1, CRm) p15, Op1, %Q0, %R0, CRm diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h index 030cdcb46c6b..2731d3b25ed2 100644 --- a/arch/arm64/include/asm/arch_gicv3.h +++ b/arch/arm64/include/asm/arch_gicv3.h @@ -77,6 +77,7 @@ #ifndef __ASSEMBLY__ #include +#include /* * Low-level accessors diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index c9ae0c6ec050..d5d798b35c1f 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -330,6 +330,7 @@ struct rdists { }; struct irq_domain; +struct device_node; int its_cpu_init(void); int its_init(struct device_node *node, struct rdists *rdists, struct irq_domain *domain); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 4.4
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Three fixes for the ARM GIC interrupt controller from Marc addressing various shortcomings versus boot initialization and suspend/resume. Thanks, tglx --> Marc Zyngier (3): irqchip/gic: Make sure all interrupts are deactivated at boot irqchip/gic: Clear enable bits before restoring them irqchip/gic: Add save/restore of the active state drivers/irqchip/irq-gic-common.c | 13 + drivers/irqchip/irq-gic.c| 38 -- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 44a077f3a4a2..f174ce0ca361 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -84,12 +84,15 @@ void __init gic_dist_config(void __iomem *base, int gic_irqs, writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i); /* -* Disable all interrupts. Leave the PPI and SGIs alone -* as they are enabled by redistributor registers. +* Deactivate and disable all SPIs. Leave the PPI and SGIs +* alone as they are in the redistributor registers on GICv3. */ - for (i = 32; i < gic_irqs; i += 32) + for (i = 32; i < gic_irqs; i += 32) { writel_relaxed(GICD_INT_EN_CLR_X32, - base + GIC_DIST_ENABLE_CLEAR + i / 8); + base + GIC_DIST_ACTIVE_CLEAR + i / 8); + writel_relaxed(GICD_INT_EN_CLR_X32, + base + GIC_DIST_ENABLE_CLEAR + i / 8); + } if (sync_access) sync_access(); @@ -102,7 +105,9 @@ void gic_cpu_config(void __iomem *base, void (*sync_access)(void)) /* * Deal with the banked PPI and SGI interrupts - disable all * PPI interrupts, ensure all SGI interrupts are enabled. +* Make sure everything is deactivated. */ + writel_relaxed(GICD_INT_EN_CLR_X32, base + GIC_DIST_ACTIVE_CLEAR); writel_relaxed(GICD_INT_EN_CLR_PPI, base + GIC_DIST_ENABLE_CLEAR); writel_relaxed(GICD_INT_EN_SET_SGI, base + GIC_DIST_ENABLE_SET); diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 515c823c1c95..abf2ffaed392 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -73,9 +73,11 @@ struct gic_chip_data { union gic_base cpu_base; #ifdef CONFIG_CPU_PM u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)]; + u32 saved_spi_active[DIV_ROUND_UP(1020, 32)]; u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)]; u32 saved_spi_target[DIV_ROUND_UP(1020, 4)]; u32 __percpu *saved_ppi_enable; + u32 __percpu *saved_ppi_active; u32 __percpu *saved_ppi_conf; #endif struct irq_domain *domain; @@ -566,6 +568,10 @@ static void gic_dist_save(unsigned int gic_nr) for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) gic_data[gic_nr].saved_spi_enable[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); + + for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) + gic_data[gic_nr].saved_spi_active[i] = + readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4); } /* @@ -604,9 +610,19 @@ static void gic_dist_restore(unsigned int gic_nr) writel_relaxed(gic_data[gic_nr].saved_spi_target[i], dist_base + GIC_DIST_TARGET + i * 4); - for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) + for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) { + writel_relaxed(GICD_INT_EN_CLR_X32, + dist_base + GIC_DIST_ENABLE_CLEAR + i * 4); writel_relaxed(gic_data[gic_nr].saved_spi_enable[i], dist_base + GIC_DIST_ENABLE_SET + i * 4); + } + + for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) { + writel_relaxed(GICD_INT_EN_CLR_X32, + dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4); + writel_relaxed(gic_data[gic_nr].saved_spi_active[i], + dist_base + GIC_DIST_ACTIVE_SET + i * 4); + } writel_relaxed(GICD_ENABLE, dist_base + GIC_DIST_CTRL); } @@ -631,6 +647,10 @@ static void gic_cpu_save(unsigned int gic_nr) for (i = 0; i < DIV_ROUND_UP(32, 32); i++) ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); + ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_active); + for (i = 0; i < DIV_ROUND_UP(32, 32); i++) + ptr[i] = readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4); + ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_conf); for (i = 0; i < DIV_ROUND_UP(32, 16); i++) ptr[i] =
[GIT pull] irq fixes for 4.4
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Three fixes for the ARM GIC interrupt controller from Marc addressing various shortcomings versus boot initialization and suspend/resume. Thanks, tglx --> Marc Zyngier (3): irqchip/gic: Make sure all interrupts are deactivated at boot irqchip/gic: Clear enable bits before restoring them irqchip/gic: Add save/restore of the active state drivers/irqchip/irq-gic-common.c | 13 + drivers/irqchip/irq-gic.c| 38 -- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 44a077f3a4a2..f174ce0ca361 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -84,12 +84,15 @@ void __init gic_dist_config(void __iomem *base, int gic_irqs, writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i); /* -* Disable all interrupts. Leave the PPI and SGIs alone -* as they are enabled by redistributor registers. +* Deactivate and disable all SPIs. Leave the PPI and SGIs +* alone as they are in the redistributor registers on GICv3. */ - for (i = 32; i < gic_irqs; i += 32) + for (i = 32; i < gic_irqs; i += 32) { writel_relaxed(GICD_INT_EN_CLR_X32, - base + GIC_DIST_ENABLE_CLEAR + i / 8); + base + GIC_DIST_ACTIVE_CLEAR + i / 8); + writel_relaxed(GICD_INT_EN_CLR_X32, + base + GIC_DIST_ENABLE_CLEAR + i / 8); + } if (sync_access) sync_access(); @@ -102,7 +105,9 @@ void gic_cpu_config(void __iomem *base, void (*sync_access)(void)) /* * Deal with the banked PPI and SGI interrupts - disable all * PPI interrupts, ensure all SGI interrupts are enabled. +* Make sure everything is deactivated. */ + writel_relaxed(GICD_INT_EN_CLR_X32, base + GIC_DIST_ACTIVE_CLEAR); writel_relaxed(GICD_INT_EN_CLR_PPI, base + GIC_DIST_ENABLE_CLEAR); writel_relaxed(GICD_INT_EN_SET_SGI, base + GIC_DIST_ENABLE_SET); diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 515c823c1c95..abf2ffaed392 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -73,9 +73,11 @@ struct gic_chip_data { union gic_base cpu_base; #ifdef CONFIG_CPU_PM u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)]; + u32 saved_spi_active[DIV_ROUND_UP(1020, 32)]; u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)]; u32 saved_spi_target[DIV_ROUND_UP(1020, 4)]; u32 __percpu *saved_ppi_enable; + u32 __percpu *saved_ppi_active; u32 __percpu *saved_ppi_conf; #endif struct irq_domain *domain; @@ -566,6 +568,10 @@ static void gic_dist_save(unsigned int gic_nr) for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) gic_data[gic_nr].saved_spi_enable[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); + + for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) + gic_data[gic_nr].saved_spi_active[i] = + readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4); } /* @@ -604,9 +610,19 @@ static void gic_dist_restore(unsigned int gic_nr) writel_relaxed(gic_data[gic_nr].saved_spi_target[i], dist_base + GIC_DIST_TARGET + i * 4); - for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) + for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) { + writel_relaxed(GICD_INT_EN_CLR_X32, + dist_base + GIC_DIST_ENABLE_CLEAR + i * 4); writel_relaxed(gic_data[gic_nr].saved_spi_enable[i], dist_base + GIC_DIST_ENABLE_SET + i * 4); + } + + for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) { + writel_relaxed(GICD_INT_EN_CLR_X32, + dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4); + writel_relaxed(gic_data[gic_nr].saved_spi_active[i], + dist_base + GIC_DIST_ACTIVE_SET + i * 4); + } writel_relaxed(GICD_ENABLE, dist_base + GIC_DIST_CTRL); } @@ -631,6 +647,10 @@ static void gic_cpu_save(unsigned int gic_nr) for (i = 0; i < DIV_ROUND_UP(32, 32); i++) ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); + ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_active); + for (i = 0; i < DIV_ROUND_UP(32, 32); i++) + ptr[i] = readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4); + ptr = raw_cpu_ptr(gic_data[gic_nr].saved_ppi_conf); for (i = 0; i < DIV_ROUND_UP(32, 16); i++) ptr[i] =
[GIT pull] irq fixes for 4.3
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus The last two one-liners for 4.3 from the irqchip space: - Regression fix for armada SoC which addresses the fallout from the set_irq_flags() cleanup - Add the missing propagation of the irq_set_type() callback to the parent interrupt controller of the tegra interrupt chip Thanks, tglx --> Lucas Stach (1): irqchip/tegra: Propagate IRQ type setting to parent Thomas Petazzoni (1): irqchip/armada-370-xp: Fix regression by clearing IRQ_NOAUTOEN drivers/irqchip/irq-armada-370-xp.c | 1 + drivers/irqchip/irq-tegra.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 655cb967a1f2..389318a3be82 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -317,6 +317,7 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h, handle_level_irq); } irq_set_probe(virq); + irq_clear_status_flags(virq, IRQ_NOAUTOEN); return 0; } diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c index 2fd89eb88f3a..fd88e687791a 100644 --- a/drivers/irqchip/irq-tegra.c +++ b/drivers/irqchip/irq-tegra.c @@ -214,6 +214,7 @@ static struct irq_chip tegra_ictlr_chip = { .irq_unmask = tegra_unmask, .irq_retrigger = tegra_retrigger, .irq_set_wake = tegra_set_wake, + .irq_set_type = irq_chip_set_type_parent, .flags = IRQCHIP_MASK_ON_SUSPEND, #ifdef CONFIG_SMP .irq_set_affinity = irq_chip_set_affinity_parent, -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 4.3
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus The last two one-liners for 4.3 from the irqchip space: - Regression fix for armada SoC which addresses the fallout from the set_irq_flags() cleanup - Add the missing propagation of the irq_set_type() callback to the parent interrupt controller of the tegra interrupt chip Thanks, tglx --> Lucas Stach (1): irqchip/tegra: Propagate IRQ type setting to parent Thomas Petazzoni (1): irqchip/armada-370-xp: Fix regression by clearing IRQ_NOAUTOEN drivers/irqchip/irq-armada-370-xp.c | 1 + drivers/irqchip/irq-tegra.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 655cb967a1f2..389318a3be82 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -317,6 +317,7 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h, handle_level_irq); } irq_set_probe(virq); + irq_clear_status_flags(virq, IRQ_NOAUTOEN); return 0; } diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c index 2fd89eb88f3a..fd88e687791a 100644 --- a/drivers/irqchip/irq-tegra.c +++ b/drivers/irqchip/irq-tegra.c @@ -214,6 +214,7 @@ static struct irq_chip tegra_ictlr_chip = { .irq_unmask = tegra_unmask, .irq_retrigger = tegra_retrigger, .irq_set_wake = tegra_set_wake, + .irq_set_type = irq_chip_set_type_parent, .flags = IRQCHIP_MASK_ON_SUSPEND, #ifdef CONFIG_SMP .irq_set_affinity = irq_chip_set_affinity_parent, -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 4.3
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus This update contains: - Fix for a long standing race affecting /proc/irq/NNN - One line fix for ARM GICV3-ITS counting the wrong data - Warning silencing in ARM GICV3-ITS. Another GCC trying to be overly clever issue. Thanks, tglx --> Ben Hutchings (1): genirq: Fix race in register_irq_proc() Marc Zyngier (2): irqchip/gic-v3-its: Silence warning when its_lpi_alloc_chunks gets inlined irqchip/gic-v3-its: Count additional LPIs for the aliased devices drivers/irqchip/irq-gic-v3-its-pci-msi.c | 2 +- drivers/irqchip/irq-gic-v3-its.c | 3 +++ kernel/irq/proc.c| 19 +-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its-pci-msi.c b/drivers/irqchip/irq-gic-v3-its-pci-msi.c index cf351c637464..a7c8c9ffbafd 100644 --- a/drivers/irqchip/irq-gic-v3-its-pci-msi.c +++ b/drivers/irqchip/irq-gic-v3-its-pci-msi.c @@ -62,7 +62,7 @@ static int its_get_pci_alias(struct pci_dev *pdev, u16 alias, void *data) dev_alias->dev_id = alias; if (pdev != dev_alias->pdev) - dev_alias->count += its_pci_msi_vec_count(dev_alias->pdev); + dev_alias->count += its_pci_msi_vec_count(pdev); return 0; } diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index ac7ae2b3cb83..25ceae9f7348 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -719,6 +719,9 @@ static unsigned long *its_lpi_alloc_chunks(int nr_irqs, int *base, int *nr_ids) out: spin_unlock(_lock); + if (!bitmap) + *base = *nr_ids = 0; + return bitmap; } diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index e3a8c9577ba6..a50ddc9417ff 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "internals.h" @@ -323,18 +324,29 @@ void register_handler_proc(unsigned int irq, struct irqaction *action) void register_irq_proc(unsigned int irq, struct irq_desc *desc) { + static DEFINE_MUTEX(register_lock); char name [MAX_NAMELEN]; - if (!root_irq_dir || (desc->irq_data.chip == _irq_chip) || desc->dir) + if (!root_irq_dir || (desc->irq_data.chip == _irq_chip)) return; + /* +* irq directories are registered only when a handler is +* added, not when the descriptor is created, so multiple +* tasks might try to register at the same time. +*/ + mutex_lock(_lock); + + if (desc->dir) + goto out_unlock; + memset(name, 0, MAX_NAMELEN); sprintf(name, "%d", irq); /* create /proc/irq/1234 */ desc->dir = proc_mkdir(name, root_irq_dir); if (!desc->dir) - return; + goto out_unlock; #ifdef CONFIG_SMP /* create /proc/irq//smp_affinity */ @@ -355,6 +367,9 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc) proc_create_data("spurious", 0444, desc->dir, _spurious_proc_fops, (void *)(long)irq); + +out_unlock: + mutex_unlock(_lock); } void unregister_irq_proc(unsigned int irq, struct irq_desc *desc) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 4.3
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus This update contains: - Fix for a long standing race affecting /proc/irq/NNN - One line fix for ARM GICV3-ITS counting the wrong data - Warning silencing in ARM GICV3-ITS. Another GCC trying to be overly clever issue. Thanks, tglx --> Ben Hutchings (1): genirq: Fix race in register_irq_proc() Marc Zyngier (2): irqchip/gic-v3-its: Silence warning when its_lpi_alloc_chunks gets inlined irqchip/gic-v3-its: Count additional LPIs for the aliased devices drivers/irqchip/irq-gic-v3-its-pci-msi.c | 2 +- drivers/irqchip/irq-gic-v3-its.c | 3 +++ kernel/irq/proc.c| 19 +-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its-pci-msi.c b/drivers/irqchip/irq-gic-v3-its-pci-msi.c index cf351c637464..a7c8c9ffbafd 100644 --- a/drivers/irqchip/irq-gic-v3-its-pci-msi.c +++ b/drivers/irqchip/irq-gic-v3-its-pci-msi.c @@ -62,7 +62,7 @@ static int its_get_pci_alias(struct pci_dev *pdev, u16 alias, void *data) dev_alias->dev_id = alias; if (pdev != dev_alias->pdev) - dev_alias->count += its_pci_msi_vec_count(dev_alias->pdev); + dev_alias->count += its_pci_msi_vec_count(pdev); return 0; } diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index ac7ae2b3cb83..25ceae9f7348 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -719,6 +719,9 @@ static unsigned long *its_lpi_alloc_chunks(int nr_irqs, int *base, int *nr_ids) out: spin_unlock(_lock); + if (!bitmap) + *base = *nr_ids = 0; + return bitmap; } diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index e3a8c9577ba6..a50ddc9417ff 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "internals.h" @@ -323,18 +324,29 @@ void register_handler_proc(unsigned int irq, struct irqaction *action) void register_irq_proc(unsigned int irq, struct irq_desc *desc) { + static DEFINE_MUTEX(register_lock); char name [MAX_NAMELEN]; - if (!root_irq_dir || (desc->irq_data.chip == _irq_chip) || desc->dir) + if (!root_irq_dir || (desc->irq_data.chip == _irq_chip)) return; + /* +* irq directories are registered only when a handler is +* added, not when the descriptor is created, so multiple +* tasks might try to register at the same time. +*/ + mutex_lock(_lock); + + if (desc->dir) + goto out_unlock; + memset(name, 0, MAX_NAMELEN); sprintf(name, "%d", irq); /* create /proc/irq/1234 */ desc->dir = proc_mkdir(name, root_irq_dir); if (!desc->dir) - return; + goto out_unlock; #ifdef CONFIG_SMP /* create /proc/irq//smp_affinity */ @@ -355,6 +367,9 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc) proc_create_data("spurious", 0444, desc->dir, _spurious_proc_fops, (void *)(long)irq); + +out_unlock: + mutex_unlock(_lock); } void unregister_irq_proc(unsigned int irq, struct irq_desc *desc) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 4.3
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A bugfix for the atmel aic5 irq chip driver which caches the wrong data and thereby breaking resume. Thanks, tglx --> Ludovic Desroches (1): irqchip/atmel-aic5: Use per chip mask caches in mask/unmask() drivers/irqchip/irq-atmel-aic5.c | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c index 9da9942ac83c..f6d680485bee 100644 --- a/drivers/irqchip/irq-atmel-aic5.c +++ b/drivers/irqchip/irq-atmel-aic5.c @@ -88,28 +88,36 @@ static void aic5_mask(struct irq_data *d) { struct irq_domain *domain = d->domain; struct irq_domain_chip_generic *dgc = domain->gc; - struct irq_chip_generic *gc = dgc->gc[0]; + struct irq_chip_generic *bgc = dgc->gc[0]; + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - /* Disable interrupt on AIC5 */ - irq_gc_lock(gc); + /* +* Disable interrupt on AIC5. We always take the lock of the +* first irq chip as all chips share the same registers. +*/ + irq_gc_lock(bgc); irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR); irq_reg_writel(gc, 1, AT91_AIC5_IDCR); gc->mask_cache &= ~d->mask; - irq_gc_unlock(gc); + irq_gc_unlock(bgc); } static void aic5_unmask(struct irq_data *d) { struct irq_domain *domain = d->domain; struct irq_domain_chip_generic *dgc = domain->gc; - struct irq_chip_generic *gc = dgc->gc[0]; + struct irq_chip_generic *bgc = dgc->gc[0]; + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - /* Enable interrupt on AIC5 */ - irq_gc_lock(gc); + /* +* Enable interrupt on AIC5. We always take the lock of the +* first irq chip as all chips share the same registers. +*/ + irq_gc_lock(bgc); irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR); irq_reg_writel(gc, 1, AT91_AIC5_IECR); gc->mask_cache |= d->mask; - irq_gc_unlock(gc); + irq_gc_unlock(bgc); } static int aic5_retrigger(struct irq_data *d) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 4.3
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A bugfix for the atmel aic5 irq chip driver which caches the wrong data and thereby breaking resume. Thanks, tglx --> Ludovic Desroches (1): irqchip/atmel-aic5: Use per chip mask caches in mask/unmask() drivers/irqchip/irq-atmel-aic5.c | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c index 9da9942ac83c..f6d680485bee 100644 --- a/drivers/irqchip/irq-atmel-aic5.c +++ b/drivers/irqchip/irq-atmel-aic5.c @@ -88,28 +88,36 @@ static void aic5_mask(struct irq_data *d) { struct irq_domain *domain = d->domain; struct irq_domain_chip_generic *dgc = domain->gc; - struct irq_chip_generic *gc = dgc->gc[0]; + struct irq_chip_generic *bgc = dgc->gc[0]; + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - /* Disable interrupt on AIC5 */ - irq_gc_lock(gc); + /* +* Disable interrupt on AIC5. We always take the lock of the +* first irq chip as all chips share the same registers. +*/ + irq_gc_lock(bgc); irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR); irq_reg_writel(gc, 1, AT91_AIC5_IDCR); gc->mask_cache &= ~d->mask; - irq_gc_unlock(gc); + irq_gc_unlock(bgc); } static void aic5_unmask(struct irq_data *d) { struct irq_domain *domain = d->domain; struct irq_domain_chip_generic *dgc = domain->gc; - struct irq_chip_generic *gc = dgc->gc[0]; + struct irq_chip_generic *bgc = dgc->gc[0]; + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - /* Enable interrupt on AIC5 */ - irq_gc_lock(gc); + /* +* Enable interrupt on AIC5. We always take the lock of the +* first irq chip as all chips share the same registers. +*/ + irq_gc_lock(bgc); irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR); irq_reg_writel(gc, 1, AT91_AIC5_IECR); gc->mask_cache |= d->mask; - irq_gc_unlock(gc); + irq_gc_unlock(bgc); } static int aic5_retrigger(struct irq_data *d) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 4.2
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A series of small fixlets for a regression visible on OMAP devices caused by the conversion of the OMAP interrupt chips to hierarchical interrupt domains. Mostly one liners on the driver side plus a small helper function in the core to avoid open coded mess in the drivers. Thanks, tglx --> Grygorii Strashko (6): genirq: Don't return ENOSYS in irq_chip_retrigger_hierarchy genirq: Introduce irq_chip_set_type_parent() helper irqchip/crossbar: Restore the irq_set_type() mechanism ARM: OMAP: wakeupgen: Restore the irq_set_type() mechanism irqchip/crossbar: Restore the mask on suspend behaviour irqchip/crossbar: Restore set_wake functionality arch/arm/mach-omap2/omap-wakeupgen.c | 1 + drivers/irqchip/irq-crossbar.c | 4 +++- include/linux/irq.h | 1 + kernel/irq/chip.c| 19 ++- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 8e52621b5a6b..e1d2e991d17a 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -392,6 +392,7 @@ static struct irq_chip wakeupgen_chip = { .irq_mask = wakeupgen_mask, .irq_unmask = wakeupgen_unmask, .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_set_type = irq_chip_set_type_parent, .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND, #ifdef CONFIG_SMP .irq_set_affinity = irq_chip_set_affinity_parent, diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index 692fe2bc8197..c12bb93334ff 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c @@ -68,7 +68,9 @@ static struct irq_chip crossbar_chip = { .irq_mask = irq_chip_mask_parent, .irq_unmask = irq_chip_unmask_parent, .irq_retrigger = irq_chip_retrigger_hierarchy, - .irq_set_wake = irq_chip_set_wake_parent, + .irq_set_type = irq_chip_set_type_parent, + .flags = IRQCHIP_MASK_ON_SUSPEND | + IRQCHIP_SKIP_SET_WAKE, #ifdef CONFIG_SMP .irq_set_affinity = irq_chip_set_affinity_parent, #endif diff --git a/include/linux/irq.h b/include/linux/irq.h index 92188b0225bb..51744bcf74ee 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -484,6 +484,7 @@ extern int irq_chip_set_affinity_parent(struct irq_data *data, extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on); extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info); +extern int irq_chip_set_type_parent(struct irq_data *data, unsigned int type); #endif /* Handling of unhandled and spurious interrupts: */ diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 27f4332c7f84..ae216824e8ca 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -985,6 +985,23 @@ int irq_chip_set_affinity_parent(struct irq_data *data, } /** + * irq_chip_set_type_parent - Set IRQ type on the parent interrupt + * @data: Pointer to interrupt specific data + * @type: IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h + * + * Conditional, as the underlying parent chip might not implement it. + */ +int irq_chip_set_type_parent(struct irq_data *data, unsigned int type) +{ + data = data->parent_data; + + if (data->chip->irq_set_type) + return data->chip->irq_set_type(data, type); + + return -ENOSYS; +} + +/** * irq_chip_retrigger_hierarchy - Retrigger an interrupt in hardware * @data: Pointer to interrupt specific data * @@ -997,7 +1014,7 @@ int irq_chip_retrigger_hierarchy(struct irq_data *data) if (data->chip && data->chip->irq_retrigger) return data->chip->irq_retrigger(data); - return -ENOSYS; + return 0; } /** -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 4.2
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A series of small fixlets for a regression visible on OMAP devices caused by the conversion of the OMAP interrupt chips to hierarchical interrupt domains. Mostly one liners on the driver side plus a small helper function in the core to avoid open coded mess in the drivers. Thanks, tglx -- Grygorii Strashko (6): genirq: Don't return ENOSYS in irq_chip_retrigger_hierarchy genirq: Introduce irq_chip_set_type_parent() helper irqchip/crossbar: Restore the irq_set_type() mechanism ARM: OMAP: wakeupgen: Restore the irq_set_type() mechanism irqchip/crossbar: Restore the mask on suspend behaviour irqchip/crossbar: Restore set_wake functionality arch/arm/mach-omap2/omap-wakeupgen.c | 1 + drivers/irqchip/irq-crossbar.c | 4 +++- include/linux/irq.h | 1 + kernel/irq/chip.c| 19 ++- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 8e52621b5a6b..e1d2e991d17a 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -392,6 +392,7 @@ static struct irq_chip wakeupgen_chip = { .irq_mask = wakeupgen_mask, .irq_unmask = wakeupgen_unmask, .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_set_type = irq_chip_set_type_parent, .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND, #ifdef CONFIG_SMP .irq_set_affinity = irq_chip_set_affinity_parent, diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index 692fe2bc8197..c12bb93334ff 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c @@ -68,7 +68,9 @@ static struct irq_chip crossbar_chip = { .irq_mask = irq_chip_mask_parent, .irq_unmask = irq_chip_unmask_parent, .irq_retrigger = irq_chip_retrigger_hierarchy, - .irq_set_wake = irq_chip_set_wake_parent, + .irq_set_type = irq_chip_set_type_parent, + .flags = IRQCHIP_MASK_ON_SUSPEND | + IRQCHIP_SKIP_SET_WAKE, #ifdef CONFIG_SMP .irq_set_affinity = irq_chip_set_affinity_parent, #endif diff --git a/include/linux/irq.h b/include/linux/irq.h index 92188b0225bb..51744bcf74ee 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -484,6 +484,7 @@ extern int irq_chip_set_affinity_parent(struct irq_data *data, extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on); extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info); +extern int irq_chip_set_type_parent(struct irq_data *data, unsigned int type); #endif /* Handling of unhandled and spurious interrupts: */ diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 27f4332c7f84..ae216824e8ca 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -985,6 +985,23 @@ int irq_chip_set_affinity_parent(struct irq_data *data, } /** + * irq_chip_set_type_parent - Set IRQ type on the parent interrupt + * @data: Pointer to interrupt specific data + * @type: IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h + * + * Conditional, as the underlying parent chip might not implement it. + */ +int irq_chip_set_type_parent(struct irq_data *data, unsigned int type) +{ + data = data-parent_data; + + if (data-chip-irq_set_type) + return data-chip-irq_set_type(data, type); + + return -ENOSYS; +} + +/** * irq_chip_retrigger_hierarchy - Retrigger an interrupt in hardware * @data: Pointer to interrupt specific data * @@ -997,7 +1014,7 @@ int irq_chip_retrigger_hierarchy(struct irq_data *data) if (data-chip data-chip-irq_retrigger) return data-chip-irq_retrigger(data); - return -ENOSYS; + return 0; } /** -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] irq fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 591e5bec13f15feb13fc445b6c9c59954711c4ac irqchip/gicv3-its: Fix mapping of LPIs to collections Misc irq fixes: - two driver fixes, - a Xen regression fix, - a nested irq thread crash fix. Thanks, Ingo --> Marc Zyngier (1): irqchip/gicv3-its: Fix mapping of LPIs to collections Thomas Gleixner (3): gpio/davinci: Fix race in installing chained irq handler genirq: Revert sparse irq locking around __cpu_up() and move it to x86 for now genirq: Prevent resend to interrupts marked IRQ_NESTED_THREAD arch/x86/kernel/smpboot.c| 11 drivers/gpio/gpio-davinci.c | 6 +-- drivers/irqchip/irq-gic-v3-its.c | 111 ++- kernel/cpu.c | 9 kernel/irq/resend.c | 18 +-- 5 files changed, 101 insertions(+), 54 deletions(-) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index d3010aa79daf..b1f3ed9c7a9e 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -992,8 +992,17 @@ int native_cpu_up(unsigned int cpu, struct task_struct *tidle) common_cpu_up(cpu, tidle); + /* +* We have to walk the irq descriptors to setup the vector +* space for the cpu which comes online. Prevent irq +* alloc/free across the bringup. +*/ + irq_lock_sparse(); + err = do_boot_cpu(apicid, cpu, tidle); + if (err) { + irq_unlock_sparse(); pr_err("do_boot_cpu failed(%d) to wakeup CPU#%u\n", err, cpu); return -EIO; } @@ -1011,6 +1020,8 @@ int native_cpu_up(unsigned int cpu, struct task_struct *tidle) touch_nmi_watchdog(); } + irq_unlock_sparse(); + return 0; } diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index c5e05c82d67c..c246ac3dda7c 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -578,15 +578,13 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) writel_relaxed(~0, >clr_falling); writel_relaxed(~0, >clr_rising); - /* set up all irqs in this bank */ - irq_set_chained_handler(bank_irq, gpio_irq_handler); - /* * Each chip handles 32 gpios, and each irq bank consists of 16 * gpio irqs. Pass the irq bank's corresponding controller to * the chained irq handler. */ - irq_set_handler_data(bank_irq, [gpio / 32]); + irq_set_chained_handler_and_data(bank_irq, gpio_irq_handler, +[gpio / 32]); binten |= BIT(bank); } diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 1b7e155869f6..c00e2db351ba 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -75,6 +75,13 @@ struct its_node { #define ITS_ITT_ALIGN SZ_256 +struct event_lpi_map { + unsigned long *lpi_map; + u16 *col_map; + irq_hw_number_t lpi_base; + int nr_lpis; +}; + /* * The ITS view of a device - belongs to an ITS, a collection, owns an * interrupt translation table, and a list of interrupts. @@ -82,11 +89,8 @@ struct its_node { struct its_device { struct list_headentry; struct its_node *its; - struct its_collection *collection; + struct event_lpi_mapevent_map; void*itt; - unsigned long *lpi_map; - irq_hw_number_t lpi_base; - int nr_lpis; u32 nr_ites; u32 device_id; }; @@ -99,6 +103,14 @@ static struct rdists *gic_rdists; #define gic_data_rdist() (raw_cpu_ptr(gic_rdists->rdist)) #define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base) +static struct its_collection *dev_event_to_col(struct its_device *its_dev, + u32 event) +{ + struct its_node *its = its_dev->its; + + return its->collections + its_dev->event_map.col_map[event]; +} + /* * ITS command descriptors - parameters to be encoded in a command * block. @@ -134,7 +146,7 @@ struct its_cmd_desc { struct { struct its_device *dev; struct its_collection *col; - u32 id; + u32 event_id; } its_movi_cmd; struct { @@ -241,7 +253,7 @@ static struct its_collection *its_build_mapd_cmd(struct its_cmd_block *cmd, its_fixup_cmd(cmd);
[GIT PULL] irq fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: 591e5bec13f15feb13fc445b6c9c59954711c4ac irqchip/gicv3-its: Fix mapping of LPIs to collections Misc irq fixes: - two driver fixes, - a Xen regression fix, - a nested irq thread crash fix. Thanks, Ingo -- Marc Zyngier (1): irqchip/gicv3-its: Fix mapping of LPIs to collections Thomas Gleixner (3): gpio/davinci: Fix race in installing chained irq handler genirq: Revert sparse irq locking around __cpu_up() and move it to x86 for now genirq: Prevent resend to interrupts marked IRQ_NESTED_THREAD arch/x86/kernel/smpboot.c| 11 drivers/gpio/gpio-davinci.c | 6 +-- drivers/irqchip/irq-gic-v3-its.c | 111 ++- kernel/cpu.c | 9 kernel/irq/resend.c | 18 +-- 5 files changed, 101 insertions(+), 54 deletions(-) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index d3010aa79daf..b1f3ed9c7a9e 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -992,8 +992,17 @@ int native_cpu_up(unsigned int cpu, struct task_struct *tidle) common_cpu_up(cpu, tidle); + /* +* We have to walk the irq descriptors to setup the vector +* space for the cpu which comes online. Prevent irq +* alloc/free across the bringup. +*/ + irq_lock_sparse(); + err = do_boot_cpu(apicid, cpu, tidle); + if (err) { + irq_unlock_sparse(); pr_err(do_boot_cpu failed(%d) to wakeup CPU#%u\n, err, cpu); return -EIO; } @@ -1011,6 +1020,8 @@ int native_cpu_up(unsigned int cpu, struct task_struct *tidle) touch_nmi_watchdog(); } + irq_unlock_sparse(); + return 0; } diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index c5e05c82d67c..c246ac3dda7c 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -578,15 +578,13 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) writel_relaxed(~0, g-clr_falling); writel_relaxed(~0, g-clr_rising); - /* set up all irqs in this bank */ - irq_set_chained_handler(bank_irq, gpio_irq_handler); - /* * Each chip handles 32 gpios, and each irq bank consists of 16 * gpio irqs. Pass the irq bank's corresponding controller to * the chained irq handler. */ - irq_set_handler_data(bank_irq, chips[gpio / 32]); + irq_set_chained_handler_and_data(bank_irq, gpio_irq_handler, +chips[gpio / 32]); binten |= BIT(bank); } diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 1b7e155869f6..c00e2db351ba 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -75,6 +75,13 @@ struct its_node { #define ITS_ITT_ALIGN SZ_256 +struct event_lpi_map { + unsigned long *lpi_map; + u16 *col_map; + irq_hw_number_t lpi_base; + int nr_lpis; +}; + /* * The ITS view of a device - belongs to an ITS, a collection, owns an * interrupt translation table, and a list of interrupts. @@ -82,11 +89,8 @@ struct its_node { struct its_device { struct list_headentry; struct its_node *its; - struct its_collection *collection; + struct event_lpi_mapevent_map; void*itt; - unsigned long *lpi_map; - irq_hw_number_t lpi_base; - int nr_lpis; u32 nr_ites; u32 device_id; }; @@ -99,6 +103,14 @@ static struct rdists *gic_rdists; #define gic_data_rdist() (raw_cpu_ptr(gic_rdists-rdist)) #define gic_data_rdist_rd_base() (gic_data_rdist()-rd_base) +static struct its_collection *dev_event_to_col(struct its_device *its_dev, + u32 event) +{ + struct its_node *its = its_dev-its; + + return its-collections + its_dev-event_map.col_map[event]; +} + /* * ITS command descriptors - parameters to be encoded in a command * block. @@ -134,7 +146,7 @@ struct its_cmd_desc { struct { struct its_device *dev; struct its_collection *col; - u32 id; + u32 event_id; } its_movi_cmd; struct { @@ -241,7 +253,7 @@ static struct its_collection *its_build_mapd_cmd(struct its_cmd_block *cmd,
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: d97eb8966c91f2c9d05f0a22eb89ed5b76d966d1 x86/irq: Check for valid irq descriptor in check_irq_vectors_for_cpu_disable() Two x86 irq related fixes: a hotplug crash fix and an ACPI IRQ registry fix. Thanks, Ingo --> Jiang Liu (1): x86/irq: Fix regression caused by commit b568b8601f05 Joerg Roedel (1): x86/irq: Check for valid irq descriptor in check_irq_vectors_for_cpu_disable() arch/x86/kernel/acpi/boot.c | 5 + arch/x86/kernel/irq.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index a18fff361c7f..8b5916342902 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -613,6 +613,11 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) { int rc, irq, trigger, polarity; + if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { + *irqp = gsi; + return 0; + } + rc = acpi_get_override_irq(gsi, , ); if (rc == 0) { trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 705ef8d48e2d..67b1cbe0093a 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -302,6 +302,9 @@ int check_irq_vectors_for_cpu_disable(void) irq = __this_cpu_read(vector_irq[vector]); if (irq >= 0) { desc = irq_to_desc(irq); + if (!desc) + continue; + data = irq_desc_get_irq_data(desc); cpumask_copy(_new, data->affinity); cpu_clear(this_cpu, affinity_new); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT PULL] IRQ fixes
Linus, Please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus # HEAD: d97eb8966c91f2c9d05f0a22eb89ed5b76d966d1 x86/irq: Check for valid irq descriptor in check_irq_vectors_for_cpu_disable() Two x86 irq related fixes: a hotplug crash fix and an ACPI IRQ registry fix. Thanks, Ingo -- Jiang Liu (1): x86/irq: Fix regression caused by commit b568b8601f05 Joerg Roedel (1): x86/irq: Check for valid irq descriptor in check_irq_vectors_for_cpu_disable() arch/x86/kernel/acpi/boot.c | 5 + arch/x86/kernel/irq.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index a18fff361c7f..8b5916342902 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -613,6 +613,11 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) { int rc, irq, trigger, polarity; + if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { + *irqp = gsi; + return 0; + } + rc = acpi_get_override_irq(gsi, trigger, polarity); if (rc == 0) { trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 705ef8d48e2d..67b1cbe0093a 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -302,6 +302,9 @@ int check_irq_vectors_for_cpu_disable(void) irq = __this_cpu_read(vector_irq[vector]); if (irq = 0) { desc = irq_to_desc(irq); + if (!desc) + continue; + data = irq_desc_get_irq_data(desc); cpumask_copy(affinity_new, data-affinity); cpu_clear(this_cpu, affinity_new); -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 3.19
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus >From the irqchip departement you get: - Regression fix for omap-intc - Regression fix for atmel-aic-common - Functional correctness fix for hip04 - Type mismatch fix for gic-v3-its - Proper error pointer check for mtd-sysirq Mostly one and two liners except for the omap regression fix which is slightly larger than desired. Thanks, tglx --> Felipe Balbi (1): irqchip: omap-intc: Fix legacy DMA regression Gavin Li (1): irqchip: atmel-aic-common: Prevent clobbering of priority when changing IRQ type Wang Long (1): irqchip: hip04: Initialize hip04_cpu_map to 0x Will Deacon (1): irqchip: gic-v3-its: Fix use of max with decimal constant Yingjoe Chen (1): irqchip: mtk-sysirq: Use IS_ERR() instead of NULL pointer check drivers/irqchip/irq-atmel-aic-common.c | 4 ++-- drivers/irqchip/irq-gic-v3-its.c | 2 +- drivers/irqchip/irq-hip04.c| 2 +- drivers/irqchip/irq-mtk-sysirq.c | 4 ++-- drivers/irqchip/irq-omap-intc.c| 26 +- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c index d111ac779c40..63cd031b2c28 100644 --- a/drivers/irqchip/irq-atmel-aic-common.c +++ b/drivers/irqchip/irq-atmel-aic-common.c @@ -28,7 +28,7 @@ #define AT91_AIC_IRQ_MIN_PRIORITY 0 #define AT91_AIC_IRQ_MAX_PRIORITY 7 -#define AT91_AIC_SRCTYPE GENMASK(7, 6) +#define AT91_AIC_SRCTYPE GENMASK(6, 5) #define AT91_AIC_SRCTYPE_LOW (0 << 5) #define AT91_AIC_SRCTYPE_FALLING (1 << 5) #define AT91_AIC_SRCTYPE_HIGH (2 << 5) @@ -74,7 +74,7 @@ int aic_common_set_type(struct irq_data *d, unsigned type, unsigned *val) return -EINVAL; } - *val &= AT91_AIC_SRCTYPE; + *val &= ~AT91_AIC_SRCTYPE; *val |= aic_type; return 0; diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 86e4684adeb1..d8996bdf0f61 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1053,7 +1053,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, * of two entries. No, the architecture doesn't let you * express an ITT with a single entry. */ - nr_ites = max(2, roundup_pow_of_two(nvecs)); + nr_ites = max(2UL, roundup_pow_of_two(nvecs)); sz = nr_ites * its->ite_size; sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; itt = kmalloc(sz, GFP_KERNEL); diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c index 29b8f21b74d0..6bc2deb73d53 100644 --- a/drivers/irqchip/irq-hip04.c +++ b/drivers/irqchip/irq-hip04.c @@ -381,7 +381,7 @@ hip04_of_init(struct device_node *node, struct device_node *parent) * It will be refined as each CPU probes its ID. */ for (i = 0; i < NR_HIP04_CPU_IF; i++) - hip04_cpu_map[i] = 0xff; + hip04_cpu_map[i] = 0x; /* * Find out how many interrupts are supported. diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c index 7e342df6a62f..0b0d2c00a2df 100644 --- a/drivers/irqchip/irq-mtk-sysirq.c +++ b/drivers/irqchip/irq-mtk-sysirq.c @@ -137,9 +137,9 @@ static int __init mtk_sysirq_of_init(struct device_node *node, return -ENOMEM; chip_data->intpol_base = of_io_request_and_map(node, 0, "intpol"); - if (!chip_data->intpol_base) { + if (IS_ERR(chip_data->intpol_base)) { pr_err("mtk_sysirq: unable to map sysirq register\n"); - ret = -ENOMEM; + ret = PTR_ERR(chip_data->intpol_base); goto out_free; } diff --git a/drivers/irqchip/irq-omap-intc.c b/drivers/irqchip/irq-omap-intc.c index 28718d3e8281..c03f140acbae 100644 --- a/drivers/irqchip/irq-omap-intc.c +++ b/drivers/irqchip/irq-omap-intc.c @@ -263,7 +263,7 @@ static int __init omap_init_irq_of(struct device_node *node) return ret; } -static int __init omap_init_irq_legacy(u32 base) +static int __init omap_init_irq_legacy(u32 base, struct device_node *node) { int j, irq_base; @@ -277,7 +277,7 @@ static int __init omap_init_irq_legacy(u32 base) irq_base = 0; } - domain = irq_domain_add_legacy(NULL, omap_nr_irqs, irq_base, 0, + domain = irq_domain_add_legacy(node, omap_nr_irqs, irq_base, 0, _domain_simple_ops, NULL); omap_irq_soft_reset(); @@ -301,10 +301,26 @@ static int __init omap_init_irq(u32 base, struct device_node *node) { int ret; - if (node) + /* +* FIXME legacy OMAP DMA driver sitting under
[GIT pull] irq fixes for 3.19
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus From the irqchip departement you get: - Regression fix for omap-intc - Regression fix for atmel-aic-common - Functional correctness fix for hip04 - Type mismatch fix for gic-v3-its - Proper error pointer check for mtd-sysirq Mostly one and two liners except for the omap regression fix which is slightly larger than desired. Thanks, tglx -- Felipe Balbi (1): irqchip: omap-intc: Fix legacy DMA regression Gavin Li (1): irqchip: atmel-aic-common: Prevent clobbering of priority when changing IRQ type Wang Long (1): irqchip: hip04: Initialize hip04_cpu_map to 0x Will Deacon (1): irqchip: gic-v3-its: Fix use of max with decimal constant Yingjoe Chen (1): irqchip: mtk-sysirq: Use IS_ERR() instead of NULL pointer check drivers/irqchip/irq-atmel-aic-common.c | 4 ++-- drivers/irqchip/irq-gic-v3-its.c | 2 +- drivers/irqchip/irq-hip04.c| 2 +- drivers/irqchip/irq-mtk-sysirq.c | 4 ++-- drivers/irqchip/irq-omap-intc.c| 26 +- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c index d111ac779c40..63cd031b2c28 100644 --- a/drivers/irqchip/irq-atmel-aic-common.c +++ b/drivers/irqchip/irq-atmel-aic-common.c @@ -28,7 +28,7 @@ #define AT91_AIC_IRQ_MIN_PRIORITY 0 #define AT91_AIC_IRQ_MAX_PRIORITY 7 -#define AT91_AIC_SRCTYPE GENMASK(7, 6) +#define AT91_AIC_SRCTYPE GENMASK(6, 5) #define AT91_AIC_SRCTYPE_LOW (0 5) #define AT91_AIC_SRCTYPE_FALLING (1 5) #define AT91_AIC_SRCTYPE_HIGH (2 5) @@ -74,7 +74,7 @@ int aic_common_set_type(struct irq_data *d, unsigned type, unsigned *val) return -EINVAL; } - *val = AT91_AIC_SRCTYPE; + *val = ~AT91_AIC_SRCTYPE; *val |= aic_type; return 0; diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 86e4684adeb1..d8996bdf0f61 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1053,7 +1053,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, * of two entries. No, the architecture doesn't let you * express an ITT with a single entry. */ - nr_ites = max(2, roundup_pow_of_two(nvecs)); + nr_ites = max(2UL, roundup_pow_of_two(nvecs)); sz = nr_ites * its-ite_size; sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; itt = kmalloc(sz, GFP_KERNEL); diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c index 29b8f21b74d0..6bc2deb73d53 100644 --- a/drivers/irqchip/irq-hip04.c +++ b/drivers/irqchip/irq-hip04.c @@ -381,7 +381,7 @@ hip04_of_init(struct device_node *node, struct device_node *parent) * It will be refined as each CPU probes its ID. */ for (i = 0; i NR_HIP04_CPU_IF; i++) - hip04_cpu_map[i] = 0xff; + hip04_cpu_map[i] = 0x; /* * Find out how many interrupts are supported. diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c index 7e342df6a62f..0b0d2c00a2df 100644 --- a/drivers/irqchip/irq-mtk-sysirq.c +++ b/drivers/irqchip/irq-mtk-sysirq.c @@ -137,9 +137,9 @@ static int __init mtk_sysirq_of_init(struct device_node *node, return -ENOMEM; chip_data-intpol_base = of_io_request_and_map(node, 0, intpol); - if (!chip_data-intpol_base) { + if (IS_ERR(chip_data-intpol_base)) { pr_err(mtk_sysirq: unable to map sysirq register\n); - ret = -ENOMEM; + ret = PTR_ERR(chip_data-intpol_base); goto out_free; } diff --git a/drivers/irqchip/irq-omap-intc.c b/drivers/irqchip/irq-omap-intc.c index 28718d3e8281..c03f140acbae 100644 --- a/drivers/irqchip/irq-omap-intc.c +++ b/drivers/irqchip/irq-omap-intc.c @@ -263,7 +263,7 @@ static int __init omap_init_irq_of(struct device_node *node) return ret; } -static int __init omap_init_irq_legacy(u32 base) +static int __init omap_init_irq_legacy(u32 base, struct device_node *node) { int j, irq_base; @@ -277,7 +277,7 @@ static int __init omap_init_irq_legacy(u32 base) irq_base = 0; } - domain = irq_domain_add_legacy(NULL, omap_nr_irqs, irq_base, 0, + domain = irq_domain_add_legacy(node, omap_nr_irqs, irq_base, 0, irq_domain_simple_ops, NULL); omap_irq_soft_reset(); @@ -301,10 +301,26 @@ static int __init omap_init_irq(u32 base, struct device_node *node) { int ret; - if (node) + /* +* FIXME legacy OMAP DMA driver sitting under arch/arm/plat-omap/dma.c +*
[GIT pull] irq fixes for 3.17
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Another pile of ARM specific irq chip fixlets: - Off by one bugs in the crossbar driver - Missing annotations - A bunch of "make it compile" updates I pulled the lot today from Jason, but it has been in -next for at least a week. Thanks, tglx --> Dan Carpenter (1): irqchip: crossbar: Off by one bugs in init Mark Brown (2): irqchip: gic-v3: Only define gic_peek_irq() when building SMP irqchip: gic-v3: Tag all low level accessors __maybe_unused Naveen Krishna Chatradhi (1): irqchip: exynos-combiner: Fix compilation error on ARM64 Will Deacon (2): irqchip: gic: Make gic_default_routable_irq_domain_ops static irqchip: gic-v3: Declare rdist as __percpu pointer to __iomem pointer drivers/irqchip/exynos-combiner.c | 1 + drivers/irqchip/irq-crossbar.c| 4 ++-- drivers/irqchip/irq-gic-v3.c | 38 +++--- drivers/irqchip/irq-gic.c | 2 +- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c index f8636a650cf6..5945223b73fa 100644 --- a/drivers/irqchip/exynos-combiner.c +++ b/drivers/irqchip/exynos-combiner.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index 85c2985d8bcb..bbbaf5de65d2 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c @@ -220,7 +220,7 @@ static int __init crossbar_of_init(struct device_node *node) of_property_read_u32_index(node, "ti,irqs-reserved", i, ); - if (entry > max) { + if (entry >= max) { pr_err("Invalid reserved entry\n"); ret = -EINVAL; goto err_irq_map; @@ -238,7 +238,7 @@ static int __init crossbar_of_init(struct device_node *node) of_property_read_u32_index(node, "ti,irqs-skip", i, ); - if (entry > max) { + if (entry >= max) { pr_err("Invalid skip entry\n"); ret = -EINVAL; goto err_irq_map; diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 57eaa5a0b1e3..a0698b4f0303 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -36,7 +36,7 @@ struct gic_chip_data { void __iomem*dist_base; void __iomem**redist_base; - void __percpu __iomem **rdist; + void __iomem * __percpu *rdist; struct irq_domain *domain; u64 redist_stride; u32 redist_regions; @@ -104,7 +104,7 @@ static void gic_redist_wait_for_rwp(void) } /* Low level accessors */ -static u64 gic_read_iar(void) +static u64 __maybe_unused gic_read_iar(void) { u64 irqstat; @@ -112,24 +112,24 @@ static u64 gic_read_iar(void) return irqstat; } -static void gic_write_pmr(u64 val) +static void __maybe_unused gic_write_pmr(u64 val) { asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val)); } -static void gic_write_ctlr(u64 val) +static void __maybe_unused gic_write_ctlr(u64 val) { asm volatile("msr_s " __stringify(ICC_CTLR_EL1) ", %0" : : "r" (val)); isb(); } -static void gic_write_grpen1(u64 val) +static void __maybe_unused gic_write_grpen1(u64 val) { asm volatile("msr_s " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" (val)); isb(); } -static void gic_write_sgi1r(u64 val) +static void __maybe_unused gic_write_sgi1r(u64 val) { asm volatile("msr_s " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val)); } @@ -200,19 +200,6 @@ static void gic_poke_irq(struct irq_data *d, u32 offset) rwp_wait(); } -static int gic_peek_irq(struct irq_data *d, u32 offset) -{ - u32 mask = 1 << (gic_irq(d) % 32); - void __iomem *base; - - if (gic_irq_in_rdist(d)) - base = gic_data_rdist_sgi_base(); - else - base = gic_data.dist_base; - - return !!(readl_relaxed(base + offset + (gic_irq(d) / 32) * 4) & mask); -} - static void gic_mask_irq(struct irq_data *d) { gic_poke_irq(d, GICD_ICENABLER); @@ -401,6 +388,19 @@ static void gic_cpu_init(void) } #ifdef CONFIG_SMP +static int gic_peek_irq(struct irq_data *d, u32 offset) +{ + u32 mask = 1 << (gic_irq(d) % 32); + void __iomem *base; + + if
[GIT pull] irq fixes for 3.17
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus Another pile of ARM specific irq chip fixlets: - Off by one bugs in the crossbar driver - Missing annotations - A bunch of make it compile updates I pulled the lot today from Jason, but it has been in -next for at least a week. Thanks, tglx -- Dan Carpenter (1): irqchip: crossbar: Off by one bugs in init Mark Brown (2): irqchip: gic-v3: Only define gic_peek_irq() when building SMP irqchip: gic-v3: Tag all low level accessors __maybe_unused Naveen Krishna Chatradhi (1): irqchip: exynos-combiner: Fix compilation error on ARM64 Will Deacon (2): irqchip: gic: Make gic_default_routable_irq_domain_ops static irqchip: gic-v3: Declare rdist as __percpu pointer to __iomem pointer drivers/irqchip/exynos-combiner.c | 1 + drivers/irqchip/irq-crossbar.c| 4 ++-- drivers/irqchip/irq-gic-v3.c | 38 +++--- drivers/irqchip/irq-gic.c | 2 +- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c index f8636a650cf6..5945223b73fa 100644 --- a/drivers/irqchip/exynos-combiner.c +++ b/drivers/irqchip/exynos-combiner.c @@ -15,6 +15,7 @@ #include linux/slab.h #include linux/irqdomain.h #include linux/irqchip/chained_irq.h +#include linux/interrupt.h #include linux/of_address.h #include linux/of_irq.h diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index 85c2985d8bcb..bbbaf5de65d2 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c @@ -220,7 +220,7 @@ static int __init crossbar_of_init(struct device_node *node) of_property_read_u32_index(node, ti,irqs-reserved, i, entry); - if (entry max) { + if (entry = max) { pr_err(Invalid reserved entry\n); ret = -EINVAL; goto err_irq_map; @@ -238,7 +238,7 @@ static int __init crossbar_of_init(struct device_node *node) of_property_read_u32_index(node, ti,irqs-skip, i, entry); - if (entry max) { + if (entry = max) { pr_err(Invalid skip entry\n); ret = -EINVAL; goto err_irq_map; diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 57eaa5a0b1e3..a0698b4f0303 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -36,7 +36,7 @@ struct gic_chip_data { void __iomem*dist_base; void __iomem**redist_base; - void __percpu __iomem **rdist; + void __iomem * __percpu *rdist; struct irq_domain *domain; u64 redist_stride; u32 redist_regions; @@ -104,7 +104,7 @@ static void gic_redist_wait_for_rwp(void) } /* Low level accessors */ -static u64 gic_read_iar(void) +static u64 __maybe_unused gic_read_iar(void) { u64 irqstat; @@ -112,24 +112,24 @@ static u64 gic_read_iar(void) return irqstat; } -static void gic_write_pmr(u64 val) +static void __maybe_unused gic_write_pmr(u64 val) { asm volatile(msr_s __stringify(ICC_PMR_EL1) , %0 : : r (val)); } -static void gic_write_ctlr(u64 val) +static void __maybe_unused gic_write_ctlr(u64 val) { asm volatile(msr_s __stringify(ICC_CTLR_EL1) , %0 : : r (val)); isb(); } -static void gic_write_grpen1(u64 val) +static void __maybe_unused gic_write_grpen1(u64 val) { asm volatile(msr_s __stringify(ICC_GRPEN1_EL1) , %0 : : r (val)); isb(); } -static void gic_write_sgi1r(u64 val) +static void __maybe_unused gic_write_sgi1r(u64 val) { asm volatile(msr_s __stringify(ICC_SGI1R_EL1) , %0 : : r (val)); } @@ -200,19 +200,6 @@ static void gic_poke_irq(struct irq_data *d, u32 offset) rwp_wait(); } -static int gic_peek_irq(struct irq_data *d, u32 offset) -{ - u32 mask = 1 (gic_irq(d) % 32); - void __iomem *base; - - if (gic_irq_in_rdist(d)) - base = gic_data_rdist_sgi_base(); - else - base = gic_data.dist_base; - - return !!(readl_relaxed(base + offset + (gic_irq(d) / 32) * 4) mask); -} - static void gic_mask_irq(struct irq_data *d) { gic_poke_irq(d, GICD_ICENABLER); @@ -401,6 +388,19 @@ static void gic_cpu_init(void) } #ifdef CONFIG_SMP +static int gic_peek_irq(struct irq_data *d, u32 offset) +{ +
[GIT pull] irq fixes for 3.15
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A slighlty large fix for a subtle issue in the CPU hotplug code of certain ARM SoCs, where the not yet online cpu needs to setup the cpu local timer and needs to set the interrupt affinity to itself. Setting interrupt affinity to a not online cpu is prohibited and therefor the timer interrupt ends up on the wrong cpu, which leads to nasty complications. The SoC folks tried to hack around that in the SoC code in some more than nasty ways. The proper solution is to have a way to enforce the affinity setting to a not online cpu. The core patch to the genirq code provides that facility and the follow up patches make use of it in the GIC interrupt controller and the exynos timer driver. The change to the core code has no implications to existing users, except for the rename of the locked function and therefor the necessary fixup in mips/cavium. Aside of that, no runtime impact is possible, as none of the existing interrupt chips implements anything which depends on the force argument of the irq_set_affinity() callback. Thanks, tglx --> Krzysztof Kozlowski (1): clocksource: Exynos_mct: Register clock event after request_irq() Thomas Gleixner (3): genirq: Allow forcing cpu affinity of interrupts irqchip: Gic: Support forced affinity setting clocksource: Exynos_mct: Use irq_force_affinity() in cpu bringup arch/mips/cavium-octeon/octeon-irq.c |2 +- drivers/clocksource/exynos_mct.c | 12 +++- drivers/irqchip/irq-gic.c|8 ++-- include/linux/interrupt.h| 35 +- include/linux/irq.h |3 ++- kernel/irq/manage.c | 17 ++--- 6 files changed, 52 insertions(+), 25 deletions(-) diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index c2bb4f8..3aa5b46 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -635,7 +635,7 @@ static void octeon_irq_cpu_offline_ciu(struct irq_data *data) cpumask_clear(_affinity); cpumask_set_cpu(cpumask_first(cpu_online_mask), _affinity); } - __irq_set_affinity_locked(data, _affinity); + irq_set_affinity_locked(data, _affinity, false); } static int octeon_irq_ciu_set_affinity(struct irq_data *data, diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index a6ee6d7..acf5a32 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -416,8 +416,6 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) evt->set_mode = exynos4_tick_set_mode; evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; evt->rating = 450; - clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1), - 0xf, 0x7fff); exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET); @@ -430,9 +428,12 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) evt->irq); return -EIO; } + irq_force_affinity(mct_irqs[MCT_L0_IRQ + cpu], cpumask_of(cpu)); } else { enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); } + clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1), + 0xf, 0x7fff); return 0; } @@ -450,7 +451,6 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { struct mct_clock_event_device *mevt; - unsigned int cpu; /* * Grab cpu pointer in each case to avoid spurious @@ -461,12 +461,6 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, mevt = this_cpu_ptr(_mct_tick); exynos4_local_timer_setup(>evt); break; - case CPU_ONLINE: - cpu = (unsigned long)hcpu; - if (mct_int_type == MCT_INT_SPI) - irq_set_affinity(mct_irqs[MCT_L0_IRQ + cpu], - cpumask_of(cpu)); - break; case CPU_DYING: mevt = this_cpu_ptr(_mct_tick); exynos4_local_timer_stop(>evt); diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 4300b66..57d165e 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -246,10 +246,14 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force) { void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); - unsigned
[GIT pull] irq fixes for 3.15
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A slighlty large fix for a subtle issue in the CPU hotplug code of certain ARM SoCs, where the not yet online cpu needs to setup the cpu local timer and needs to set the interrupt affinity to itself. Setting interrupt affinity to a not online cpu is prohibited and therefor the timer interrupt ends up on the wrong cpu, which leads to nasty complications. The SoC folks tried to hack around that in the SoC code in some more than nasty ways. The proper solution is to have a way to enforce the affinity setting to a not online cpu. The core patch to the genirq code provides that facility and the follow up patches make use of it in the GIC interrupt controller and the exynos timer driver. The change to the core code has no implications to existing users, except for the rename of the locked function and therefor the necessary fixup in mips/cavium. Aside of that, no runtime impact is possible, as none of the existing interrupt chips implements anything which depends on the force argument of the irq_set_affinity() callback. Thanks, tglx -- Krzysztof Kozlowski (1): clocksource: Exynos_mct: Register clock event after request_irq() Thomas Gleixner (3): genirq: Allow forcing cpu affinity of interrupts irqchip: Gic: Support forced affinity setting clocksource: Exynos_mct: Use irq_force_affinity() in cpu bringup arch/mips/cavium-octeon/octeon-irq.c |2 +- drivers/clocksource/exynos_mct.c | 12 +++- drivers/irqchip/irq-gic.c|8 ++-- include/linux/interrupt.h| 35 +- include/linux/irq.h |3 ++- kernel/irq/manage.c | 17 ++--- 6 files changed, 52 insertions(+), 25 deletions(-) diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index c2bb4f8..3aa5b46 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -635,7 +635,7 @@ static void octeon_irq_cpu_offline_ciu(struct irq_data *data) cpumask_clear(new_affinity); cpumask_set_cpu(cpumask_first(cpu_online_mask), new_affinity); } - __irq_set_affinity_locked(data, new_affinity); + irq_set_affinity_locked(data, new_affinity, false); } static int octeon_irq_ciu_set_affinity(struct irq_data *data, diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index a6ee6d7..acf5a32 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -416,8 +416,6 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) evt-set_mode = exynos4_tick_set_mode; evt-features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; evt-rating = 450; - clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1), - 0xf, 0x7fff); exynos4_mct_write(TICK_BASE_CNT, mevt-base + MCT_L_TCNTB_OFFSET); @@ -430,9 +428,12 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) evt-irq); return -EIO; } + irq_force_affinity(mct_irqs[MCT_L0_IRQ + cpu], cpumask_of(cpu)); } else { enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); } + clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1), + 0xf, 0x7fff); return 0; } @@ -450,7 +451,6 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { struct mct_clock_event_device *mevt; - unsigned int cpu; /* * Grab cpu pointer in each case to avoid spurious @@ -461,12 +461,6 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, mevt = this_cpu_ptr(percpu_mct_tick); exynos4_local_timer_setup(mevt-evt); break; - case CPU_ONLINE: - cpu = (unsigned long)hcpu; - if (mct_int_type == MCT_INT_SPI) - irq_set_affinity(mct_irqs[MCT_L0_IRQ + cpu], - cpumask_of(cpu)); - break; case CPU_DYING: mevt = this_cpu_ptr(percpu_mct_tick); exynos4_local_timer_stop(mevt-evt); diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 4300b66..57d165e 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -246,10 +246,14 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force) { void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d)
[GIT pull] irq fixes for 3.14
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus We present you herewith: * Another four fixlets to tame the ARM orion irq chip Thanks, tglx --> Andrew Lunn (1): irqchip: orion: Fix getting generic chip pointer. Sebastian Hesselbarth (3): irqchip: orion: clear bridge cause register on init irqchip: orion: use handle_edge_irq on bridge irqs irqchip: orion: clear stale interrupts in irq_startup drivers/irqchip/irq-orion.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c index e51d400..8e41be6 100644 --- a/drivers/irqchip/irq-orion.c +++ b/drivers/irqchip/irq-orion.c @@ -111,7 +111,8 @@ IRQCHIP_DECLARE(orion_intc, "marvell,orion-intc", orion_irq_init); static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) { struct irq_domain *d = irq_get_handler_data(irq); - struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, irq); + + struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, 0); u32 stat = readl_relaxed(gc->reg_base + ORION_BRIDGE_IRQ_CAUSE) & gc->mask_cache; @@ -123,6 +124,19 @@ static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) } } +/* + * Bridge IRQ_CAUSE is asserted regardless of IRQ_MASK register. + * To avoid interrupt events on stale irqs, we clear them before unmask. + */ +static unsigned int orion_bridge_irq_startup(struct irq_data *d) +{ + struct irq_chip_type *ct = irq_data_get_chip_type(d); + + ct->chip.irq_ack(d); + ct->chip.irq_unmask(d); + return 0; +} + static int __init orion_bridge_irq_init(struct device_node *np, struct device_node *parent) { @@ -143,7 +157,7 @@ static int __init orion_bridge_irq_init(struct device_node *np, } ret = irq_alloc_domain_generic_chips(domain, nrirqs, 1, np->name, -handle_level_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); +handle_edge_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); if (ret) { pr_err("%s: unable to alloc irq domain gc\n", np->name); return ret; @@ -176,12 +190,14 @@ static int __init orion_bridge_irq_init(struct device_node *np, gc->chip_types[0].regs.ack = ORION_BRIDGE_IRQ_CAUSE; gc->chip_types[0].regs.mask = ORION_BRIDGE_IRQ_MASK; + gc->chip_types[0].chip.irq_startup = orion_bridge_irq_startup; gc->chip_types[0].chip.irq_ack = irq_gc_ack_clr_bit; gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; - /* mask all interrupts */ + /* mask and clear all interrupts */ writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK); + writel(0, gc->reg_base + ORION_BRIDGE_IRQ_CAUSE); irq_set_handler_data(irq, domain); irq_set_chained_handler(irq, orion_bridge_irq_handler); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 3.14
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus We present you herewith: * Another four fixlets to tame the ARM orion irq chip Thanks, tglx -- Andrew Lunn (1): irqchip: orion: Fix getting generic chip pointer. Sebastian Hesselbarth (3): irqchip: orion: clear bridge cause register on init irqchip: orion: use handle_edge_irq on bridge irqs irqchip: orion: clear stale interrupts in irq_startup drivers/irqchip/irq-orion.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c index e51d400..8e41be6 100644 --- a/drivers/irqchip/irq-orion.c +++ b/drivers/irqchip/irq-orion.c @@ -111,7 +111,8 @@ IRQCHIP_DECLARE(orion_intc, marvell,orion-intc, orion_irq_init); static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) { struct irq_domain *d = irq_get_handler_data(irq); - struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, irq); + + struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, 0); u32 stat = readl_relaxed(gc-reg_base + ORION_BRIDGE_IRQ_CAUSE) gc-mask_cache; @@ -123,6 +124,19 @@ static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) } } +/* + * Bridge IRQ_CAUSE is asserted regardless of IRQ_MASK register. + * To avoid interrupt events on stale irqs, we clear them before unmask. + */ +static unsigned int orion_bridge_irq_startup(struct irq_data *d) +{ + struct irq_chip_type *ct = irq_data_get_chip_type(d); + + ct-chip.irq_ack(d); + ct-chip.irq_unmask(d); + return 0; +} + static int __init orion_bridge_irq_init(struct device_node *np, struct device_node *parent) { @@ -143,7 +157,7 @@ static int __init orion_bridge_irq_init(struct device_node *np, } ret = irq_alloc_domain_generic_chips(domain, nrirqs, 1, np-name, -handle_level_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); +handle_edge_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); if (ret) { pr_err(%s: unable to alloc irq domain gc\n, np-name); return ret; @@ -176,12 +190,14 @@ static int __init orion_bridge_irq_init(struct device_node *np, gc-chip_types[0].regs.ack = ORION_BRIDGE_IRQ_CAUSE; gc-chip_types[0].regs.mask = ORION_BRIDGE_IRQ_MASK; + gc-chip_types[0].chip.irq_startup = orion_bridge_irq_startup; gc-chip_types[0].chip.irq_ack = irq_gc_ack_clr_bit; gc-chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; gc-chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; - /* mask all interrupts */ + /* mask and clear all interrupts */ writel(0, gc-reg_base + ORION_BRIDGE_IRQ_MASK); + writel(0, gc-reg_base + ORION_BRIDGE_IRQ_CAUSE); irq_set_handler_data(irq, domain); irq_set_chained_handler(irq, orion_bridge_irq_handler); -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT Pull] irq fixes for 3.14
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A trivial oneliner adding the missing Kconfig dependency curing build failures which have been discovered by several build robots. Thanks, tglx --> Nitin A Kamble (1): genirq: Generic irq chip requires IRQ_DOMAIN kernel/irq/Kconfig |1 + 1 file changed, 1 insertion(+) diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index 4a1fef0..07cbdfe 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig @@ -40,6 +40,7 @@ config IRQ_EDGE_EOI_HANDLER # Generic configurable interrupt chip implementation config GENERIC_IRQ_CHIP bool + select IRQ_DOMAIN # Generic irq_domain hw <--> linux irq number translation config IRQ_DOMAIN -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT Pull] irq fixes for 3.14
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus A trivial oneliner adding the missing Kconfig dependency curing build failures which have been discovered by several build robots. Thanks, tglx -- Nitin A Kamble (1): genirq: Generic irq chip requires IRQ_DOMAIN kernel/irq/Kconfig |1 + 1 file changed, 1 insertion(+) diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index 4a1fef0..07cbdfe 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig @@ -40,6 +40,7 @@ config IRQ_EDGE_EOI_HANDLER # Generic configurable interrupt chip implementation config GENERIC_IRQ_CHIP bool + select IRQ_DOMAIN # Generic irq_domain hw -- linux irq number translation config IRQ_DOMAIN -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 3.13
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus * Correction of fuzzy and fragile IRQ_RETVAL macro * IRQ related resume fix affecting only XEN * ARM/GIC fix for chained GIC controllers Thanks, tglx --> Geert Uytterhoeven (1): genirq: Correct fuzzy and fragile IRQ_RETVAL() definition Laxman Dewangan (1): irq: Enable all irqs unconditionally in irq_resume Mark Rutland (1): irqchip: Gic: fix boot for chained gics drivers/irqchip/irq-gic.c |9 + include/linux/irqreturn.h |2 +- kernel/irq/pm.c |2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index d0e9480..e219a5bf 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -814,12 +814,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, if (WARN_ON(!gic->domain)) return; + if (gic_nr == 0) { #ifdef CONFIG_SMP - set_smp_cross_call(gic_raise_softirq); - register_cpu_notifier(_cpu_notifier); + set_smp_cross_call(gic_raise_softirq); + register_cpu_notifier(_cpu_notifier); #endif - - set_handle_irq(gic_handle_irq); + set_handle_irq(gic_handle_irq); + } gic_chip.flags |= gic_arch_extn.flags; gic_dist_init(gic); diff --git a/include/linux/irqreturn.h b/include/linux/irqreturn.h index 714ba08..e374e36 100644 --- a/include/linux/irqreturn.h +++ b/include/linux/irqreturn.h @@ -14,6 +14,6 @@ enum irqreturn { }; typedef enum irqreturn irqreturn_t; -#define IRQ_RETVAL(x) ((x) != IRQ_NONE) +#define IRQ_RETVAL(x) ((x) ? IRQ_HANDLED : IRQ_NONE) #endif diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c index cb228bf..abcd6ca 100644 --- a/kernel/irq/pm.c +++ b/kernel/irq/pm.c @@ -50,7 +50,7 @@ static void resume_irqs(bool want_early) bool is_early = desc->action && desc->action->flags & IRQF_EARLY_RESUME; - if (is_early != want_early) + if (!is_early && want_early) continue; raw_spin_lock_irqsave(>lock, flags); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 3.13
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus * Correction of fuzzy and fragile IRQ_RETVAL macro * IRQ related resume fix affecting only XEN * ARM/GIC fix for chained GIC controllers Thanks, tglx -- Geert Uytterhoeven (1): genirq: Correct fuzzy and fragile IRQ_RETVAL() definition Laxman Dewangan (1): irq: Enable all irqs unconditionally in irq_resume Mark Rutland (1): irqchip: Gic: fix boot for chained gics drivers/irqchip/irq-gic.c |9 + include/linux/irqreturn.h |2 +- kernel/irq/pm.c |2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index d0e9480..e219a5bf 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -814,12 +814,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, if (WARN_ON(!gic-domain)) return; + if (gic_nr == 0) { #ifdef CONFIG_SMP - set_smp_cross_call(gic_raise_softirq); - register_cpu_notifier(gic_cpu_notifier); + set_smp_cross_call(gic_raise_softirq); + register_cpu_notifier(gic_cpu_notifier); #endif - - set_handle_irq(gic_handle_irq); + set_handle_irq(gic_handle_irq); + } gic_chip.flags |= gic_arch_extn.flags; gic_dist_init(gic); diff --git a/include/linux/irqreturn.h b/include/linux/irqreturn.h index 714ba08..e374e36 100644 --- a/include/linux/irqreturn.h +++ b/include/linux/irqreturn.h @@ -14,6 +14,6 @@ enum irqreturn { }; typedef enum irqreturn irqreturn_t; -#define IRQ_RETVAL(x) ((x) != IRQ_NONE) +#define IRQ_RETVAL(x) ((x) ? IRQ_HANDLED : IRQ_NONE) #endif diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c index cb228bf..abcd6ca 100644 --- a/kernel/irq/pm.c +++ b/kernel/irq/pm.c @@ -50,7 +50,7 @@ static void resume_irqs(bool want_early) bool is_early = desc-action desc-action-flags IRQF_EARLY_RESUME; - if (is_early != want_early) + if (!is_early want_early) continue; raw_spin_lock_irqsave(desc-lock, flags); -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 3.9
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus * Single bugfix for a wrong return value, which prevents the calling function to invoke the software fallback. Thanks, tglx --> Abhijeet Dharmapurikar (1): irqchip: gic: fix irq_trigger return drivers/irqchip/irq-gic.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index a32e0d5..fc6aebf 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -236,7 +236,8 @@ static int gic_retrigger(struct irq_data *d) if (gic_arch_extn.irq_retrigger) return gic_arch_extn.irq_retrigger(d); - return -ENXIO; + /* the genirq layer expects 0 if we can't retrigger in hardware */ + return 0; } #ifdef CONFIG_SMP -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[GIT pull] irq fixes for 3.9
Linus, please pull the latest irq-urgent-for-linus git tree from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-urgent-for-linus * Single bugfix for a wrong return value, which prevents the calling function to invoke the software fallback. Thanks, tglx -- Abhijeet Dharmapurikar (1): irqchip: gic: fix irq_trigger return drivers/irqchip/irq-gic.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index a32e0d5..fc6aebf 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -236,7 +236,8 @@ static int gic_retrigger(struct irq_data *d) if (gic_arch_extn.irq_retrigger) return gic_arch_extn.irq_retrigger(d); - return -ENXIO; + /* the genirq layer expects 0 if we can't retrigger in hardware */ + return 0; } #ifdef CONFIG_SMP -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/