Merge branch 'irq/for-gpio' into irq/core
authorThomas Gleixner <tglx@linutronix.de>
Fri, 18 Aug 2017 09:22:27 +0000 (11:22 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 18 Aug 2017 09:22:27 +0000 (11:22 +0200)
Merge the flow handlers and irq domain extensions which are in a separate
branch so they can be consumed by the gpio folks.

17 files changed:
arch/arm/mach-hisi/Kconfig
arch/metag/Kconfig
drivers/irqchip/Kconfig
drivers/irqchip/irq-armada-370-xp.c
drivers/irqchip/irq-bcm6345-l1.c
drivers/irqchip/irq-bcm7038-l1.c
drivers/irqchip/irq-gic-v3-its.c
drivers/irqchip/irq-gic-v3.c
drivers/irqchip/irq-gic.c
drivers/irqchip/irq-hip04.c
drivers/irqchip/irq-metag-ext.c
drivers/irqchip/irq-mips-gic.c
drivers/irqchip/irq-xtensa-mx.c
include/linux/irq.h
kernel/irq/debugfs.c
kernel/irq/internals.h
kernel/irq/proc.c

index a3b091a4d344a43d2a903b5ffaaa672bf742db4a..65a048fa08ec72dbe4b5635853ea0a72c8a6c594 100644 (file)
@@ -39,6 +39,7 @@ config ARCH_HIP04
        select HAVE_ARM_ARCH_TIMER
        select MCPM if SMP
        select MCPM_QUAD_CLUSTER if SMP
+       select GENERIC_IRQ_EFFECTIVE_AFF_MASK
        help
          Support for Hisilicon HiP04 SoC family
 
index 5b7a45d99cfbfd5397554b399a6ec2bd8e4b5582..7d8b322e5101d7bd00835be59db1d494be164ad8 100644 (file)
@@ -26,6 +26,7 @@ config METAG
        select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_UNDERSCORE_SYMBOL_PREFIX
        select IRQ_DOMAIN
+       select GENERIC_IRQ_EFFECTIVE_AFF_MASK
        select MODULES_USE_ELF_RELA
        select OF
        select OF_EARLY_FLATTREE
index f1fd5f44d1d45920514b2777addecb53e753feda..1139de9da21a86aa18e51ed5d98126ffa8c39703 100644 (file)
@@ -7,6 +7,7 @@ config ARM_GIC
        select IRQ_DOMAIN
        select IRQ_DOMAIN_HIERARCHY
        select MULTI_IRQ_HANDLER
+       select GENERIC_IRQ_EFFECTIVE_AFF_MASK
 
 config ARM_GIC_PM
        bool
@@ -34,6 +35,7 @@ config ARM_GIC_V3
        select MULTI_IRQ_HANDLER
        select IRQ_DOMAIN_HIERARCHY
        select PARTITION_PERCPU
+       select GENERIC_IRQ_EFFECTIVE_AFF_MASK
 
 config ARM_GIC_V3_ITS
        bool
@@ -64,6 +66,7 @@ config ARMADA_370_XP_IRQ
        bool
        select GENERIC_IRQ_CHIP
        select PCI_MSI if PCI
+       select GENERIC_IRQ_EFFECTIVE_AFF_MASK
 
 config ALPINE_MSI
        bool
@@ -93,11 +96,13 @@ config BCM6345_L1_IRQ
        bool
        select GENERIC_IRQ_CHIP
        select IRQ_DOMAIN
+       select GENERIC_IRQ_EFFECTIVE_AFF_MASK
 
 config BCM7038_L1_IRQ
        bool
        select GENERIC_IRQ_CHIP
        select IRQ_DOMAIN
+       select GENERIC_IRQ_EFFECTIVE_AFF_MASK
 
 config BCM7120_L2_IRQ
        bool
@@ -136,6 +141,7 @@ config IRQ_MIPS_CPU
        select GENERIC_IRQ_IPI if SYS_SUPPORTS_MULTITHREADING
        select IRQ_DOMAIN
        select IRQ_DOMAIN_HIERARCHY if GENERIC_IRQ_IPI
+       select GENERIC_IRQ_EFFECTIVE_AFF_MASK
 
 config CLPS711X_IRQCHIP
        bool
@@ -217,6 +223,7 @@ config VERSATILE_FPGA_IRQ_NR
 config XTENSA_MX
        bool
        select IRQ_DOMAIN
+       select GENERIC_IRQ_EFFECTIVE_AFF_MASK
 
 config XILINX_INTC
        bool
index b207b2c3aa5558efc0e4542e0b42309b681daf26..eb815676c0882c9edae29cbe1c7bb0ec4026a918 100644 (file)
@@ -330,6 +330,8 @@ static int armada_xp_set_affinity(struct irq_data *d,
        writel(reg, main_int_base + ARMADA_370_XP_INT_SOURCE_CTL(hwirq));
        raw_spin_unlock(&irq_controller_lock);
 
+       irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
        return IRQ_SET_MASK_OK;
 }
 #endif
@@ -363,6 +365,7 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
        } else {
                irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip,
                                        handle_level_irq);
+               irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq)));
        }
        irq_set_probe(virq);
 
index daa4ae89e466edea622c36bbf02ec6b987444be1..43f8abe40878a21ed8e2e5cded86a3257e526161 100644 (file)
@@ -231,6 +231,8 @@ static int bcm6345_l1_set_affinity(struct irq_data *d,
        }
        raw_spin_unlock_irqrestore(&intc->lock, flags);
 
+       irq_data_update_effective_affinity(d, cpumask_of(new_cpu));
+
        return IRQ_SET_MASK_OK_NOCOPY;
 }
 
@@ -291,6 +293,7 @@ static int bcm6345_l1_map(struct irq_domain *d, unsigned int virq,
        irq_set_chip_and_handler(virq,
                &bcm6345_l1_irq_chip, handle_percpu_irq);
        irq_set_chip_data(virq, d->host_data);
+       irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq)));
        return 0;
 }
 
index c2662a1bfdd3746c36114c36ab810af85507aa22..55cfb986225be79386b3d6487b953ff63ca4ab59 100644 (file)
@@ -212,6 +212,8 @@ static int bcm7038_l1_set_affinity(struct irq_data *d,
                __bcm7038_l1_unmask(d, first_cpu);
 
        raw_spin_unlock_irqrestore(&intc->lock, flags);
+       irq_data_update_effective_affinity(d, cpumask_of(first_cpu));
+
        return 0;
 }
 
@@ -299,6 +301,7 @@ static int bcm7038_l1_map(struct irq_domain *d, unsigned int virq,
 {
        irq_set_chip_and_handler(virq, &bcm7038_l1_irq_chip, handle_level_irq);
        irq_set_chip_data(virq, d->host_data);
+       irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq)));
        return 0;
 }
 
index 68932873eebc0c3d14caa00b048d0c961e765a98..22e228500357e35f1dc5ecab0f4da0c8893e7112 100644 (file)
@@ -649,6 +649,7 @@ static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
                target_col = &its_dev->its->collections[cpu];
                its_send_movi(its_dev, target_col, id);
                its_dev->event_map.col_map[id] = cpu;
+               irq_data_update_effective_affinity(d, cpumask_of(cpu));
        }
 
        return IRQ_SET_MASK_OK_DONE;
@@ -1481,6 +1482,7 @@ static int its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 
                irq_domain_set_hwirq_and_chip(domain, virq + i,
                                              hwirq, &its_irq_chip, its_dev);
+               irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq + i)));
                pr_debug("ID:%d pID:%d vID:%d\n",
                         (int)(hwirq - its_dev->event_map.lpi_base),
                         (int) hwirq, virq + i);
@@ -1495,13 +1497,16 @@ static void its_irq_domain_activate(struct irq_domain *domain,
        struct its_device *its_dev = irq_data_get_irq_chip_data(d);
        u32 event = its_get_event_id(d);
        const struct cpumask *cpu_mask = cpu_online_mask;
+       int cpu;
 
        /* get the cpu_mask of local node */
        if (its_dev->its->numa_node >= 0)
                cpu_mask = cpumask_of_node(its_dev->its->numa_node);
 
        /* Bind the LPI to the first possible CPU */
-       its_dev->event_map.col_map[event] = cpumask_first(cpu_mask);
+       cpu = cpumask_first(cpu_mask);
+       its_dev->event_map.col_map[event] = cpu;
+       irq_data_update_effective_affinity(d, cpumask_of(cpu));
 
        /* Map the GIC IRQ and event to the device */
        its_send_mapti(its_dev, d->hwirq, event);
index dbffb7ab62033b346ca7fc3b3468d6bcb3a19a63..511c290c4a26a0f07cb0bb5a1ea5ecd31b0226f7 100644 (file)
@@ -670,6 +670,8 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
        else
                gic_dist_wait_for_rwp();
 
+       irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
        return IRQ_SET_MASK_OK_DONE;
 }
 #else
@@ -768,6 +770,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
                irq_domain_set_info(d, irq, hw, chip, d->host_data,
                                    handle_fasteoi_irq, NULL, NULL);
                irq_set_probe(irq);
+               irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
        }
        /* LPIs */
        if (hw >= 8192 && hw < GIC_ID_NR) {
index 1b1df4f770bdefe0a16e0109624801f8af90f1f7..20dd2ba3d6038a2ee27bd6ad459c74aa99696a8e 100644 (file)
@@ -344,6 +344,8 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
        writel_relaxed(val | bit, reg);
        gic_unlock_irqrestore(flags);
 
+       irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
        return IRQ_SET_MASK_OK_DONE;
 }
 #endif
@@ -966,6 +968,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
                irq_domain_set_info(d, irq, hw, &gic->chip, d->host_data,
                                    handle_fasteoi_irq, NULL, NULL);
                irq_set_probe(irq);
+               irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
        }
        return 0;
 }
index c1b4ee955dbef6e05092efd36e4658ee7d91df4f..5b4fd2f4e5f88d6e71ba8f4e5d1d375487468613 100644 (file)
@@ -165,6 +165,8 @@ static int hip04_irq_set_affinity(struct irq_data *d,
        writel_relaxed(val | bit, reg);
        raw_spin_unlock(&irq_controller_lock);
 
+       irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
        return IRQ_SET_MASK_OK;
 }
 #endif
@@ -312,6 +314,7 @@ static int hip04_irq_domain_map(struct irq_domain *d, unsigned int irq,
                irq_set_chip_and_handler(irq, &hip04_irq_chip,
                                         handle_fasteoi_irq);
                irq_set_probe(irq);
+               irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
        }
        irq_set_chip_data(irq, d->host_data);
        return 0;
index 0cdd923d153539abc9697b8a78ae7af32101f0b6..be7216bfb8dd7373d3bda856bf2a737090b7c0f9 100644 (file)
@@ -518,6 +518,8 @@ static int meta_intc_set_affinity(struct irq_data *data,
 
        metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR2(thread)), vec_addr);
 
+       irq_data_update_effective_affinity(data, cpumask_of(cpu));
+
        return 0;
 }
 #else
@@ -578,6 +580,8 @@ static int meta_intc_map(struct irq_domain *d, unsigned int irq,
        else
                irq_set_chip_and_handler(irq, &meta_intc_edge_chip,
                                         handle_edge_irq);
+
+       irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
        return 0;
 }
 
index 6ab1d3afec02b39f4d8b26e9e30c280b316de156..6461380ff1a4954d33c3b7efb10a7ebba5de7fa4 100644 (file)
@@ -445,24 +445,27 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
        unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
        cpumask_t       tmp = CPU_MASK_NONE;
        unsigned long   flags;
-       int             i;
+       int             i, cpu;
 
        cpumask_and(&tmp, cpumask, cpu_online_mask);
        if (cpumask_empty(&tmp))
                return -EINVAL;
 
+       cpu = cpumask_first(&tmp);
+
        /* Assumption : cpumask refers to a single CPU */
        spin_lock_irqsave(&gic_lock, flags);
 
        /* Re-route this IRQ */
-       gic_map_to_vpe(irq, mips_cm_vp_id(cpumask_first(&tmp)));
+       gic_map_to_vpe(irq, mips_cm_vp_id(cpu));
 
        /* Update the pcpu_masks */
        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(&tmp)].pcpu_mask);
+       set_bit(irq, pcpu_masks[cpu].pcpu_mask);
 
        cpumask_copy(irq_data_get_affinity_mask(d), cpumask);
+       irq_data_update_effective_affinity(d, cpumask_of(cpu));
        spin_unlock_irqrestore(&gic_lock, flags);
 
        return IRQ_SET_MASK_OK_NOCOPY;
@@ -716,6 +719,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
                if (err)
                        return err;
 
+               irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq)));
                return gic_shared_irq_domain_map(d, virq, hwirq, 0);
        }
 
index 72a391e01011c8356474765cde4ab18d2f997f10..a15a9510c90439b11072fe5cc88f6f4656414388 100644 (file)
@@ -32,6 +32,7 @@ static int xtensa_mx_irq_map(struct irq_domain *d, unsigned int irq,
                irq_set_status_flags(irq, IRQ_LEVEL);
                return 0;
        }
+       irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
        return xtensa_irq_map(d, irq, hw);
 }
 
@@ -121,9 +122,12 @@ static int xtensa_mx_irq_retrigger(struct irq_data *d)
 static int xtensa_mx_irq_set_affinity(struct irq_data *d,
                const struct cpumask *dest, bool force)
 {
-       unsigned mask = 1u << cpumask_any_and(dest, cpu_online_mask);
+       int cpu = cpumask_any_and(dest, cpu_online_mask);
+       unsigned mask = 1u << cpu;
 
        set_er(mask, MIROUT(d->hwirq - HW_IRQ_MX_BASE));
+       irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
        return 0;
 
 }
index d4728bf6a537c802073592fcd6e440ccc628509e..b99a784635ff5801c20fce3a187a12cc4358660a 100644 (file)
@@ -783,7 +783,10 @@ 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)
 {
-       return d->common->effective_affinity;
+       if (!cpumask_empty(d->common->effective_affinity))
+               return d->common->effective_affinity;
+
+       return d->common->affinity;
 }
 static inline void irq_data_update_effective_affinity(struct irq_data *d,
                                                      const struct cpumask *m)
index 4d384edc0c64eb1807cf3f8056c2607c58053ab1..c3fdb36dec304956650082efc63bed95f37ff56c 100644 (file)
@@ -5,6 +5,7 @@
  */
 #include <linux/irqdomain.h>
 #include <linux/irq.h>
+#include <linux/uaccess.h>
 
 #include "internals.h"
 
@@ -171,8 +172,55 @@ static int irq_debug_open(struct inode *inode, struct file *file)
        return single_open(file, irq_debug_show, inode->i_private);
 }
 
+static ssize_t irq_debug_write(struct file *file, const char __user *user_buf,
+                              size_t count, loff_t *ppos)
+{
+       struct irq_desc *desc = file_inode(file)->i_private;
+       char buf[8] = { 0, };
+       size_t size;
+
+       size = min(sizeof(buf) - 1, count);
+       if (copy_from_user(buf, user_buf, size))
+               return -EFAULT;
+
+       if (!strncmp(buf, "trigger", size)) {
+               unsigned long flags;
+               int err;
+
+               /* Try the HW interface first */
+               err = irq_set_irqchip_state(irq_desc_get_irq(desc),
+                                           IRQCHIP_STATE_PENDING, true);
+               if (!err)
+                       return count;
+
+               /*
+                * Otherwise, try to inject via the resend interface,
+                * which may or may not succeed.
+                */
+               chip_bus_lock(desc);
+               raw_spin_lock_irqsave(&desc->lock, flags);
+
+               if (irq_settings_is_level(desc)) {
+                       /* Can't do level, sorry */
+                       err = -EINVAL;
+               } else {
+                       desc->istate |= IRQS_PENDING;
+                       check_irq_resend(desc);
+                       err = 0;
+               }
+
+               raw_spin_unlock_irqrestore(&desc->lock, flags);
+               chip_bus_sync_unlock(desc);
+
+               return err ? err : count;
+       }
+
+       return count;
+}
+
 static const struct file_operations dfs_irq_ops = {
        .open           = irq_debug_open,
+       .write          = irq_debug_write,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
@@ -186,7 +234,7 @@ void irq_add_debugfs_entry(unsigned int irq, struct irq_desc *desc)
                return;
 
        sprintf(name, "%d", irq);
-       desc->debugfs_file = debugfs_create_file(name, 0444, irq_dir, desc,
+       desc->debugfs_file = debugfs_create_file(name, 0644, irq_dir, desc,
                                                 &dfs_irq_ops);
 }
 
index a2c48058354c871803eb9650db60acc0e7cb4b13..a4aa39009f0d50d5be26e32b768bc2a2ff9c1f27 100644 (file)
@@ -151,7 +151,7 @@ static inline void chip_bus_sync_unlock(struct irq_desc *desc)
 #define IRQ_GET_DESC_CHECK_PERCPU      (_IRQ_DESC_CHECK | _IRQ_DESC_PERCPU)
 
 #define for_each_action_of_desc(desc, act)                     \
-       for (act = desc->act; act; act = act->next)
+       for (act = desc->action; act; act = act->next)
 
 struct irq_desc *
 __irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus,
index 7f9642a1e2670154002b42e62a77913dcf6366f2..0534781724d05f7c285977511acf11875df91d8c 100644 (file)
@@ -61,7 +61,7 @@ static int show_irq_affinity(int type, struct seq_file *m)
        case EFFECTIVE:
        case EFFECTIVE_LIST:
 #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
-               mask = desc->irq_common_data.effective_affinity;
+               mask = irq_data_get_effective_affinity_mask(&desc->irq_data);
                break;
 #else
                return -EINVAL;