irqchip: gic: Drop support for gic_arch_extn
[firefly-linux-kernel-4.4.55.git] / drivers / irqchip / irq-gic.c
index 471e1cdc193365dce99dcb53e3c8b21a388e0faa..dd989148e689c648362ad0b7ff8d53271df129b0 100644 (file)
@@ -80,19 +80,6 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock);
 #define NR_GIC_CPU_IF 8
 static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
 
-/*
- * Supported arch specific GIC irq extension.
- * Default make them NULL.
- */
-struct irq_chip gic_arch_extn = {
-       .irq_eoi        = NULL,
-       .irq_mask       = NULL,
-       .irq_unmask     = NULL,
-       .irq_retrigger  = NULL,
-       .irq_set_type   = NULL,
-       .irq_set_wake   = NULL,
-};
-
 #ifndef MAX_GIC_NR
 #define MAX_GIC_NR     1
 #endif
@@ -151,47 +138,86 @@ static inline unsigned int gic_irq(struct irq_data *d)
 /*
  * Routines to acknowledge, disable and enable interrupts
  */
-static void gic_mask_irq(struct irq_data *d)
+static void gic_poke_irq(struct irq_data *d, u32 offset)
 {
        u32 mask = 1 << (gic_irq(d) % 32);
-       unsigned long flags;
-
-       raw_spin_lock_irqsave(&irq_controller_lock, flags);
-       writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4);
-       if (gic_arch_extn.irq_mask)
-               gic_arch_extn.irq_mask(d);
-       raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
+       writel_relaxed(mask, gic_dist_base(d) + offset + (gic_irq(d) / 32) * 4);
 }
 
-static void gic_unmask_irq(struct irq_data *d)
+static int gic_peek_irq(struct irq_data *d, u32 offset)
 {
        u32 mask = 1 << (gic_irq(d) % 32);
-       unsigned long flags;
+       return !!(readl_relaxed(gic_dist_base(d) + offset + (gic_irq(d) / 32) * 4) & mask);
+}
 
-       raw_spin_lock_irqsave(&irq_controller_lock, flags);
-       if (gic_arch_extn.irq_unmask)
-               gic_arch_extn.irq_unmask(d);
-       writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
-       raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
+static void gic_mask_irq(struct irq_data *d)
+{
+       gic_poke_irq(d, GIC_DIST_ENABLE_CLEAR);
+}
+
+static void gic_unmask_irq(struct irq_data *d)
+{
+       gic_poke_irq(d, GIC_DIST_ENABLE_SET);
 }
 
 static void gic_eoi_irq(struct irq_data *d)
 {
-       if (gic_arch_extn.irq_eoi) {
-               raw_spin_lock(&irq_controller_lock);
-               gic_arch_extn.irq_eoi(d);
-               raw_spin_unlock(&irq_controller_lock);
+       writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
+}
+
+static int gic_irq_set_irqchip_state(struct irq_data *d,
+                                    enum irqchip_irq_state which, bool val)
+{
+       u32 reg;
+
+       switch (which) {
+       case IRQCHIP_STATE_PENDING:
+               reg = val ? GIC_DIST_PENDING_SET : GIC_DIST_PENDING_CLEAR;
+               break;
+
+       case IRQCHIP_STATE_ACTIVE:
+               reg = val ? GIC_DIST_ACTIVE_SET : GIC_DIST_ACTIVE_CLEAR;
+               break;
+
+       case IRQCHIP_STATE_MASKED:
+               reg = val ? GIC_DIST_ENABLE_CLEAR : GIC_DIST_ENABLE_SET;
+               break;
+
+       default:
+               return -EINVAL;
        }
 
-       writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
+       gic_poke_irq(d, reg);
+       return 0;
+}
+
+static int gic_irq_get_irqchip_state(struct irq_data *d,
+                                     enum irqchip_irq_state which, bool *val)
+{
+       switch (which) {
+       case IRQCHIP_STATE_PENDING:
+               *val = gic_peek_irq(d, GIC_DIST_PENDING_SET);
+               break;
+
+       case IRQCHIP_STATE_ACTIVE:
+               *val = gic_peek_irq(d, GIC_DIST_ACTIVE_SET);
+               break;
+
+       case IRQCHIP_STATE_MASKED:
+               *val = !gic_peek_irq(d, GIC_DIST_ENABLE_SET);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
 }
 
 static int gic_set_type(struct irq_data *d, unsigned int type)
 {
        void __iomem *base = gic_dist_base(d);
        unsigned int gicirq = gic_irq(d);
-       unsigned long flags;
-       int ret;
 
        /* Interrupt configuration for SGIs can't be changed */
        if (gicirq < 16)
@@ -202,25 +228,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
                            type != IRQ_TYPE_EDGE_RISING)
                return -EINVAL;
 
-       raw_spin_lock_irqsave(&irq_controller_lock, flags);
-
-       if (gic_arch_extn.irq_set_type)
-               gic_arch_extn.irq_set_type(d, type);
-
-       ret = gic_configure_irq(gicirq, type, base, NULL);
-
-       raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
-
-       return ret;
-}
-
-static int gic_retrigger(struct irq_data *d)
-{
-       if (gic_arch_extn.irq_retrigger)
-               return gic_arch_extn.irq_retrigger(d);
-
-       /* the genirq layer expects 0 if we can't retrigger in hardware */
-       return 0;
+       return gic_configure_irq(gicirq, type, base, NULL);
 }
 
 #ifdef CONFIG_SMP
@@ -251,21 +259,6 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 }
 #endif
 
-#ifdef CONFIG_PM
-static int gic_set_wake(struct irq_data *d, unsigned int on)
-{
-       int ret = -ENXIO;
-
-       if (gic_arch_extn.irq_set_wake)
-               ret = gic_arch_extn.irq_set_wake(d, on);
-
-       return ret;
-}
-
-#else
-#define gic_set_wake   NULL
-#endif
-
 static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
 {
        u32 irqstat, irqnr;
@@ -324,11 +317,11 @@ static struct irq_chip gic_chip = {
        .irq_unmask             = gic_unmask_irq,
        .irq_eoi                = gic_eoi_irq,
        .irq_set_type           = gic_set_type,
-       .irq_retrigger          = gic_retrigger,
 #ifdef CONFIG_SMP
        .irq_set_affinity       = gic_set_affinity,
 #endif
-       .irq_set_wake           = gic_set_wake,
+       .irq_get_irqchip_state  = gic_irq_get_irqchip_state,
+       .irq_set_irqchip_state  = gic_irq_set_irqchip_state,
 };
 
 void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
@@ -353,7 +346,7 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic)
                        break;
        }
 
-       if (!mask)
+       if (!mask && num_possible_cpus() > 1)
                pr_crit("GIC CPU mask not found - kernel will fail to boot.\n");
 
        return mask;
@@ -802,15 +795,12 @@ 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);
                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-
-               gic_routable_irq_domain_ops->map(d, irq, hw);
        }
        return 0;
 }
 
 static void gic_irq_domain_unmap(struct irq_domain *d, unsigned int irq)
 {
-       gic_routable_irq_domain_ops->unmap(d, irq);
 }
 
 static int gic_irq_domain_xlate(struct irq_domain *d,
@@ -829,16 +819,8 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
        *out_hwirq = intspec[1] + 16;
 
        /* For SPIs, we need to add 16 more to get the GIC irq ID number */
-       if (!intspec[0]) {
-               ret = gic_routable_irq_domain_ops->xlate(d, controller,
-                                                        intspec,
-                                                        intsize,
-                                                        out_hwirq,
-                                                        out_type);
-
-               if (IS_ERR_VALUE(ret))
-                       return ret;
-       }
+       if (!intspec[0])
+               *out_hwirq += 16;
 
        *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
 
@@ -895,37 +877,11 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
        .xlate = gic_irq_domain_xlate,
 };
 
-/* Default functions for routable irq domain */
-static int gic_routable_irq_domain_map(struct irq_domain *d, unsigned int irq,
-                             irq_hw_number_t hw)
+void gic_set_irqchip_flags(unsigned long flags)
 {
-       return 0;
+       gic_chip.flags |= flags;
 }
 
-static void gic_routable_irq_domain_unmap(struct irq_domain *d,
-                                         unsigned int irq)
-{
-}
-
-static int gic_routable_irq_domain_xlate(struct irq_domain *d,
-                               struct device_node *controller,
-                               const u32 *intspec, unsigned int intsize,
-                               unsigned long *out_hwirq,
-                               unsigned int *out_type)
-{
-       *out_hwirq += 16;
-       return 0;
-}
-
-static const struct irq_domain_ops gic_default_routable_irq_domain_ops = {
-       .map = gic_routable_irq_domain_map,
-       .unmap = gic_routable_irq_domain_unmap,
-       .xlate = gic_routable_irq_domain_xlate,
-};
-
-const struct irq_domain_ops *gic_routable_irq_domain_ops =
-                                       &gic_default_routable_irq_domain_ops;
-
 void __init gic_init_bases(unsigned int gic_nr, int irq_start,
                           void __iomem *dist_base, void __iomem *cpu_base,
                           u32 percpu_offset, struct device_node *node)
@@ -933,7 +889,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
        irq_hw_number_t hwirq_base;
        struct gic_chip_data *gic;
        int gic_irqs, irq_base, i;
-       int nr_routable_irqs;
 
        BUG_ON(gic_nr >= MAX_GIC_NR);
 
@@ -989,15 +944,9 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
        gic->gic_irqs = gic_irqs;
 
        if (node) {             /* DT case */
-               const struct irq_domain_ops *ops = &gic_irq_domain_hierarchy_ops;
-
-               if (!of_property_read_u32(node, "arm,routable-irqs",
-                                         &nr_routable_irqs)) {
-                       ops = &gic_irq_domain_ops;
-                       gic_irqs = nr_routable_irqs;
-               }
-
-               gic->domain = irq_domain_add_linear(node, gic_irqs, ops, gic);
+               gic->domain = irq_domain_add_linear(node, gic_irqs,
+                                                   &gic_irq_domain_hierarchy_ops,
+                                                   gic);
        } else {                /* Non-DT case */
                /*
                 * For primary GICs, skip over SGIs.
@@ -1036,7 +985,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
                set_handle_irq(gic_handle_irq);
        }
 
-       gic_chip.flags |= gic_arch_extn.flags;
        gic_dist_init(gic);
        gic_cpu_init(gic);
        gic_pm_init(gic);