]> Pileus Git - ~andy/linux/blobdiff - include/linux/irq.h
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[~andy/linux] / include / linux / irq.h
index a71dd18639fb2b6df331ae81c63ca8d88fe9866c..8b4538446636da5fca09de70d5e6ea33c5fac28c 100644 (file)
@@ -59,6 +59,7 @@ typedef       void (*irq_preflow_handler_t)(struct irq_data *data);
  * IRQ_NOPROBE                 - Interrupt cannot be probed by autoprobing
  * IRQ_NOREQUEST               - Interrupt cannot be requested via
  *                               request_irq()
+ * IRQ_NOTHREAD                        - Interrupt cannot be threaded
  * IRQ_NOAUTOEN                        - Interrupt is not automatically enabled in
  *                               request/setup_irq()
  * IRQ_NO_BALANCING            - Interrupt cannot be balanced (affinity set)
@@ -85,6 +86,7 @@ enum {
        IRQ_NO_BALANCING        = (1 << 13),
        IRQ_MOVE_PCNTXT         = (1 << 14),
        IRQ_NESTED_THREAD       = (1 << 15),
+       IRQ_NOTHREAD            = (1 << 16),
 };
 
 #define IRQF_MODIFY_MASK       \
@@ -278,6 +280,9 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
  * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips
  * @irq_cpu_online:    configure an interrupt source for a secondary CPU
  * @irq_cpu_offline:   un-configure an interrupt source for a secondary CPU
+ * @irq_suspend:       function called from core code on suspend once per chip
+ * @irq_resume:                function called from core code on resume once per chip
+ * @irq_pm_shutdown:   function called from core code on shutdown once per chip
  * @irq_print_chip:    optional to print special chip info in show_interrupts
  * @flags:             chip specific flags
  *
@@ -307,6 +312,10 @@ struct irq_chip {
        void            (*irq_cpu_online)(struct irq_data *data);
        void            (*irq_cpu_offline)(struct irq_data *data);
 
+       void            (*irq_suspend)(struct irq_data *data);
+       void            (*irq_resume)(struct irq_data *data);
+       void            (*irq_pm_shutdown)(struct irq_data *data);
+
        void            (*irq_print_chip)(struct irq_data *data, struct seq_file *p);
 
        unsigned long   flags;
@@ -422,7 +431,7 @@ irq_set_handler(unsigned int irq, irq_flow_handler_t handle)
 /*
  * Set a highlevel chained flow handler for a given IRQ.
  * (a chained handler is automatically enabled and set to
- *  IRQ_NOREQUEST and IRQ_NOPROBE)
+ *  IRQ_NOREQUEST, IRQ_NOPROBE, and IRQ_NOTHREAD)
  */
 static inline void
 irq_set_chained_handler(unsigned int irq, irq_flow_handler_t handle)
@@ -452,6 +461,16 @@ static inline void irq_set_probe(unsigned int irq)
        irq_modify_status(irq, IRQ_NOPROBE, 0);
 }
 
+static inline void irq_set_nothread(unsigned int irq)
+{
+       irq_modify_status(irq, 0, IRQ_NOTHREAD);
+}
+
+static inline void irq_set_thread(unsigned int irq)
+{
+       irq_modify_status(irq, IRQ_NOTHREAD, 0);
+}
+
 static inline void irq_set_nested_thread(unsigned int irq, bool nest)
 {
        if (nest)
@@ -556,6 +575,145 @@ static inline int irq_reserve_irq(unsigned int irq)
        return irq_reserve_irqs(irq, 1);
 }
 
+#ifndef irq_reg_writel
+# define irq_reg_writel(val, addr)     writel(val, addr)
+#endif
+#ifndef irq_reg_readl
+# define irq_reg_readl(addr)           readl(addr)
+#endif
+
+/**
+ * struct irq_chip_regs - register offsets for struct irq_gci
+ * @enable:    Enable register offset to reg_base
+ * @disable:   Disable register offset to reg_base
+ * @mask:      Mask register offset to reg_base
+ * @ack:       Ack register offset to reg_base
+ * @eoi:       Eoi register offset to reg_base
+ * @type:      Type configuration register offset to reg_base
+ * @polarity:  Polarity configuration register offset to reg_base
+ */
+struct irq_chip_regs {
+       unsigned long           enable;
+       unsigned long           disable;
+       unsigned long           mask;
+       unsigned long           ack;
+       unsigned long           eoi;
+       unsigned long           type;
+       unsigned long           polarity;
+};
+
+/**
+ * struct irq_chip_type - Generic interrupt chip instance for a flow type
+ * @chip:              The real interrupt chip which provides the callbacks
+ * @regs:              Register offsets for this chip
+ * @handler:           Flow handler associated with this chip
+ * @type:              Chip can handle these flow types
+ *
+ * A irq_generic_chip can have several instances of irq_chip_type when
+ * it requires different functions and register offsets for different
+ * flow types.
+ */
+struct irq_chip_type {
+       struct irq_chip         chip;
+       struct irq_chip_regs    regs;
+       irq_flow_handler_t      handler;
+       u32                     type;
+};
+
+/**
+ * struct irq_chip_generic - Generic irq chip data structure
+ * @lock:              Lock to protect register and cache data access
+ * @reg_base:          Register base address (virtual)
+ * @irq_base:          Interrupt base nr for this chip
+ * @irq_cnt:           Number of interrupts handled by this chip
+ * @mask_cache:                Cached mask register
+ * @type_cache:                Cached type register
+ * @polarity_cache:    Cached polarity register
+ * @wake_enabled:      Interrupt can wakeup from suspend
+ * @wake_active:       Interrupt is marked as an wakeup from suspend source
+ * @num_ct:            Number of available irq_chip_type instances (usually 1)
+ * @private:           Private data for non generic chip callbacks
+ * @list:              List head for keeping track of instances
+ * @chip_types:                Array of interrupt irq_chip_types
+ *
+ * Note, that irq_chip_generic can have multiple irq_chip_type
+ * implementations which can be associated to a particular irq line of
+ * an irq_chip_generic instance. That allows to share and protect
+ * state in an irq_chip_generic instance when we need to implement
+ * different flow mechanisms (level/edge) for it.
+ */
+struct irq_chip_generic {
+       raw_spinlock_t          lock;
+       void __iomem            *reg_base;
+       unsigned int            irq_base;
+       unsigned int            irq_cnt;
+       u32                     mask_cache;
+       u32                     type_cache;
+       u32                     polarity_cache;
+       u32                     wake_enabled;
+       u32                     wake_active;
+       unsigned int            num_ct;
+       void                    *private;
+       struct list_head        list;
+       struct irq_chip_type    chip_types[0];
+};
+
+/**
+ * enum irq_gc_flags - Initialization flags for generic irq chips
+ * @IRQ_GC_INIT_MASK_CACHE:    Initialize the mask_cache by reading mask reg
+ * @IRQ_GC_INIT_NESTED_LOCK:   Set the lock class of the irqs to nested for
+ *                             irq chips which need to call irq_set_wake() on
+ *                             the parent irq. Usually GPIO implementations
+ */
+enum irq_gc_flags {
+       IRQ_GC_INIT_MASK_CACHE          = 1 << 0,
+       IRQ_GC_INIT_NESTED_LOCK         = 1 << 1,
+};
+
+/* Generic chip callback functions */
+void irq_gc_noop(struct irq_data *d);
+void irq_gc_mask_disable_reg(struct irq_data *d);
+void irq_gc_mask_set_bit(struct irq_data *d);
+void irq_gc_mask_clr_bit(struct irq_data *d);
+void irq_gc_unmask_enable_reg(struct irq_data *d);
+void irq_gc_ack(struct irq_data *d);
+void irq_gc_mask_disable_reg_and_ack(struct irq_data *d);
+void irq_gc_eoi(struct irq_data *d);
+int irq_gc_set_wake(struct irq_data *d, unsigned int on);
+
+/* Setup functions for irq_chip_generic */
+struct irq_chip_generic *
+irq_alloc_generic_chip(const char *name, int nr_ct, unsigned int irq_base,
+                      void __iomem *reg_base, irq_flow_handler_t handler);
+void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk,
+                           enum irq_gc_flags flags, unsigned int clr,
+                           unsigned int set);
+int irq_setup_alt_chip(struct irq_data *d, unsigned int type);
+void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk,
+                            unsigned int clr, unsigned int set);
+
+static inline struct irq_chip_type *irq_data_get_chip_type(struct irq_data *d)
+{
+       return container_of(d->chip, struct irq_chip_type, chip);
+}
+
+#define IRQ_MSK(n) (u32)((n) < 32 ? ((1 << (n)) - 1) : UINT_MAX)
+
+#ifdef CONFIG_SMP
+static inline void irq_gc_lock(struct irq_chip_generic *gc)
+{
+       raw_spin_lock(&gc->lock);
+}
+
+static inline void irq_gc_unlock(struct irq_chip_generic *gc)
+{
+       raw_spin_unlock(&gc->lock);
+}
+#else
+static inline void irq_gc_lock(struct irq_chip_generic *gc) { }
+static inline void irq_gc_unlock(struct irq_chip_generic *gc) { }
+#endif
+
 #endif /* CONFIG_GENERIC_HARDIRQS */
 
 #endif /* !CONFIG_S390 */