]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/irqchip/irq-mips-gic.c
Merge branches 'pm-core', 'pm-qos', 'pm-domains' and 'pm-opp'
[linux.git] / drivers / irqchip / irq-mips-gic.c
index 6185696405d5b64181a28d671b6797743768b9f1..11d12bccc4e7f10d72fa41f5464ed4d6b6f02a5f 100644 (file)
@@ -152,12 +152,12 @@ static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
 }
 
 #ifdef CONFIG_CLKSRC_MIPS_GIC
-cycle_t gic_read_count(void)
+u64 gic_read_count(void)
 {
        unsigned int hi, hi2, lo;
 
        if (mips_cm_is64)
-               return (cycle_t)gic_read(GIC_REG(SHARED, GIC_SH_COUNTER));
+               return (u64)gic_read(GIC_REG(SHARED, GIC_SH_COUNTER));
 
        do {
                hi = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
@@ -165,7 +165,7 @@ cycle_t gic_read_count(void)
                hi2 = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
        } while (hi2 != hi);
 
-       return (((cycle_t) hi) << 32) + lo;
+       return (((u64) hi) << 32) + lo;
 }
 
 unsigned int gic_get_count_width(void)
@@ -179,7 +179,7 @@ unsigned int gic_get_count_width(void)
        return bits;
 }
 
-void gic_write_compare(cycle_t cnt)
+void gic_write_compare(u64 cnt)
 {
        if (mips_cm_is64) {
                gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE), cnt);
@@ -191,7 +191,7 @@ void gic_write_compare(cycle_t cnt)
        }
 }
 
-void gic_write_cpu_compare(cycle_t cnt, int cpu)
+void gic_write_cpu_compare(u64 cnt, int cpu)
 {
        unsigned long flags;
 
@@ -211,17 +211,17 @@ void gic_write_cpu_compare(cycle_t cnt, int cpu)
        local_irq_restore(flags);
 }
 
-cycle_t gic_read_compare(void)
+u64 gic_read_compare(void)
 {
        unsigned int hi, lo;
 
        if (mips_cm_is64)
-               return (cycle_t)gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE));
+               return (u64)gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE));
 
        hi = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI));
        lo = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO));
 
-       return (((cycle_t) hi) << 32) + lo;
+       return (((u64) hi) << 32) + lo;
 }
 
 void gic_start_count(void)
@@ -371,18 +371,13 @@ static void gic_handle_shared_int(bool chained)
        bitmap_and(pending, pending, intrmask, gic_shared_intrs);
        bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs);
 
-       intr = find_first_bit(pending, gic_shared_intrs);
-       while (intr != gic_shared_intrs) {
+       for_each_set_bit(intr, pending, gic_shared_intrs) {
                virq = irq_linear_revmap(gic_irq_domain,
                                         GIC_SHARED_TO_HWIRQ(intr));
                if (chained)
                        generic_handle_irq(virq);
                else
                        do_IRQ(virq);
-
-               /* go to next pending bit */
-               bitmap_clear(pending, intr, 1);
-               intr = find_first_bit(pending, gic_shared_intrs);
        }
 }
 
@@ -518,18 +513,13 @@ static void gic_handle_local_int(bool chained)
 
        bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS);
 
-       intr = find_first_bit(&pending, GIC_NUM_LOCAL_INTRS);
-       while (intr != GIC_NUM_LOCAL_INTRS) {
+       for_each_set_bit(intr, &pending, GIC_NUM_LOCAL_INTRS) {
                virq = irq_linear_revmap(gic_irq_domain,
                                         GIC_LOCAL_TO_HWIRQ(intr));
                if (chained)
                        generic_handle_irq(virq);
                else
                        do_IRQ(virq);
-
-               /* go to next pending bit */
-               bitmap_clear(&pending, intr, 1);
-               intr = find_first_bit(&pending, GIC_NUM_LOCAL_INTRS);
        }
 }
 
@@ -978,6 +968,34 @@ static struct irq_domain_ops gic_ipi_domain_ops = {
        .match = gic_ipi_domain_match,
 };
 
+static void __init gic_map_single_int(struct device_node *node,
+                                     unsigned int irq)
+{
+       unsigned int linux_irq;
+       struct irq_fwspec local_int_fwspec = {
+               .fwnode         = &node->fwnode,
+               .param_count    = 3,
+               .param          = {
+                       [0]     = GIC_LOCAL,
+                       [1]     = irq,
+                       [2]     = IRQ_TYPE_NONE,
+               },
+       };
+
+       if (!gic_local_irq_is_routable(irq))
+               return;
+
+       linux_irq = irq_create_fwspec_mapping(&local_int_fwspec);
+       WARN_ON(!linux_irq);
+}
+
+static void __init gic_map_interrupts(struct device_node *node)
+{
+       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_FDC);
+}
+
 static void __init __gic_init(unsigned long gic_base_addr,
                              unsigned long gic_addrspace_size,
                              unsigned int cpu_vec, unsigned int irqbase,
@@ -1077,6 +1095,7 @@ static void __init __gic_init(unsigned long gic_base_addr,
        }
 
        gic_basic_init();
+       gic_map_interrupts(node);
 }
 
 void __init gic_init(unsigned long gic_base_addr,