struct proc_dir_entry;
 struct msi_desc;
 
+/**
+ * struct irq_data - per irq and irq chip data passed down to chip functions
+ * @irq:               interrupt number
+ * @node:              node index useful for balancing
+ * @chip:              low level interrupt hardware access
+ * @handler_data:      per-IRQ data for the irq_chip methods
+ * @chip_data:         platform-specific per-chip private data for the chip
+ *                     methods, to allow shared chip implementations
+ * @msi_desc:          MSI descriptor
+ * @affinity:          IRQ affinity on SMP
+ * @irq_2_iommu:       iommu with this irq
+ *
+ * The fields here need to overlay the ones in irq_desc until we
+ * cleaned up the direct references and switched everything over to
+ * irq_data.
+ */
+struct irq_data {
+       unsigned int            irq;
+       unsigned int            node;
+       struct irq_chip         *chip;
+       void                    *handler_data;
+       void                    *chip_data;
+       struct msi_desc         *msi_desc;
+#ifdef CONFIG_SMP
+       cpumask_var_t           affinity;
+#endif
+#ifdef CONFIG_INTR_REMAP
+       struct irq_2_iommu      *irq_2_iommu;
+#endif
+};
+
 /**
  * struct irq_chip - hardware interrupt chip descriptor
  *
 struct irq_2_iommu;
 /**
  * struct irq_desc - interrupt descriptor
- * @irq:               interrupt number for this descriptor
+ * @irq_data:          per irq and chip data passed down to chip functions
  * @timer_rand_state:  pointer to timer rand state struct
  * @kstat_irqs:                irq stats per cpu
- * @irq_2_iommu:       iommu with this irq
  * @handle_irq:                highlevel irq-events handler [if NULL, __do_IRQ()]
- * @chip:              low level interrupt hardware access
- * @msi_desc:          MSI descriptor
- * @handler_data:      per-IRQ data for the irq_chip methods
- * @chip_data:         platform-specific per-chip private data for the chip
- *                     methods, to allow shared chip implementations
  * @action:            the irq action chain
  * @status:            status information
  * @depth:             disable-depth, for nested irq_disable() calls
  * @last_unhandled:    aging timer for unhandled count
  * @irqs_unhandled:    stats field for spurious unhandled interrupts
  * @lock:              locking for SMP
- * @affinity:          IRQ affinity on SMP
- * @node:              node index useful for balancing
  * @pending_mask:      pending rebalanced interrupts
  * @threads_active:    number of irqaction threads currently running
  * @wait_for_threads:  wait queue for sync_irq to wait for threaded handlers
  * @name:              flow handler name for /proc/interrupts output
  */
 struct irq_desc {
-       unsigned int            irq;
-       struct timer_rand_state *timer_rand_state;
-       unsigned int            *kstat_irqs;
+
+       /*
+        * This union will go away, once we fixed the direct access to
+        * irq_desc all over the place. The direct fields are a 1:1
+        * overlay of irq_data.
+        */
+       union {
+               struct irq_data         irq_data;
+               struct {
+                       unsigned int            irq;
+                       unsigned int            node;
+                       struct irq_chip         *chip;
+                       void                    *handler_data;
+                       void                    *chip_data;
+                       struct msi_desc         *msi_desc;
+#ifdef CONFIG_SMP
+                       cpumask_var_t           affinity;
+#endif
 #ifdef CONFIG_INTR_REMAP
-       struct irq_2_iommu      *irq_2_iommu;
+                       struct irq_2_iommu      *irq_2_iommu;
 #endif
+               };
+       };
+       struct timer_rand_state *timer_rand_state;
+       unsigned int            *kstat_irqs;
        irq_flow_handler_t      handle_irq;
-       struct irq_chip         *chip;
-       struct msi_desc         *msi_desc;
-       void                    *handler_data;
-       void                    *chip_data;
        struct irqaction        *action;        /* IRQ action list */
        unsigned int            status;         /* IRQ status */
 
        unsigned int            irqs_unhandled;
        raw_spinlock_t          lock;
 #ifdef CONFIG_SMP
-       cpumask_var_t           affinity;
        const struct cpumask    *affinity_hint;
-       unsigned int            node;
 #ifdef CONFIG_GENERIC_PENDING_IRQ
        cpumask_var_t           pending_mask;
 #endif
 extern int set_irq_type(unsigned int irq, unsigned int type);
 extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
 
-#define get_irq_chip(irq)      (irq_to_desc(irq)->chip)
-#define get_irq_chip_data(irq) (irq_to_desc(irq)->chip_data)
-#define get_irq_data(irq)      (irq_to_desc(irq)->handler_data)
-#define get_irq_msi(irq)       (irq_to_desc(irq)->msi_desc)
+#define get_irq_chip(irq)      (irq_to_desc(irq)->irq_data.chip)
+#define get_irq_chip_data(irq) (irq_to_desc(irq)->irq_data.chip_data)
+#define get_irq_data(irq)      (irq_to_desc(irq)->irq_data.handler_data)
+#define get_irq_msi(irq)       (irq_to_desc(irq)->irq_data.msi_desc)
 
-#define get_irq_desc_chip(desc)                ((desc)->chip)
-#define get_irq_desc_chip_data(desc)   ((desc)->chip_data)
-#define get_irq_desc_data(desc)                ((desc)->handler_data)
-#define get_irq_desc_msi(desc)         ((desc)->msi_desc)
+#define get_irq_desc_chip(desc)                ((desc)->irq_data.chip)
+#define get_irq_desc_chip_data(desc)   ((desc)->irq_data.chip_data)
+#define get_irq_desc_data(desc)                ((desc)->irq_data.handler_data)
+#define get_irq_desc_msi(desc)         ((desc)->irq_data.msi_desc)
 
 #endif /* CONFIG_GENERIC_HARDIRQS */
 
 
 #ifdef CONFIG_SPARSE_IRQ
 
 static struct irq_desc irq_desc_init = {
-       .irq        = -1,
-       .status     = IRQ_DISABLED,
-       .chip       = &no_irq_chip,
-       .handle_irq = handle_bad_irq,
-       .depth      = 1,
-       .lock       = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
+       .status         = IRQ_DISABLED,
+       .handle_irq     = handle_bad_irq,
+       .depth          = 1,
+       .lock           = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
 };
 
 void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
        memcpy(desc, &irq_desc_init, sizeof(struct irq_desc));
 
        raw_spin_lock_init(&desc->lock);
-       desc->irq = irq;
+       desc->irq_data.irq = irq;
 #ifdef CONFIG_SMP
        desc->node = node;
 #endif
 
 static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = {
        [0 ... NR_IRQS_LEGACY-1] = {
-               .irq        = -1,
-               .status     = IRQ_DISABLED,
-               .chip       = &no_irq_chip,
-               .handle_irq = handle_bad_irq,
-               .depth      = 1,
-               .lock       = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
+               .status         = IRQ_DISABLED,
+               .handle_irq     = handle_bad_irq,
+               .depth          = 1,
+               .lock           = __RAW_SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
        }
 };
 
        kstat_irqs_legacy = kzalloc_node(NR_IRQS_LEGACY * nr_cpu_ids *
                                          sizeof(int), GFP_NOWAIT, node);
 
+       irq_desc_init.irq_data.chip = &no_irq_chip;
+
        for (i = 0; i < legacy_count; i++) {
-               desc[i].irq = i;
+               desc[i].irq_data.irq = i;
+               desc[i].irq_data.chip = &no_irq_chip;
 #ifdef CONFIG_SMP
                desc[i].node = node;
 #endif
 
 struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
        [0 ... NR_IRQS-1] = {
-               .status = IRQ_DISABLED,
-               .chip = &no_irq_chip,
-               .handle_irq = handle_bad_irq,
-               .depth = 1,
-               .lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
+               .status         = IRQ_DISABLED,
+               .handle_irq     = handle_bad_irq,
+               .depth          = 1,
+               .lock           = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
        }
 };
 
        count = ARRAY_SIZE(irq_desc);
 
        for (i = 0; i < count; i++) {
-               desc[i].irq = i;
+               desc[i].irq_data.irq = i;
+               desc[i].irq_data.chip = &no_irq_chip;
                alloc_desc_masks(&desc[i], 0, true);
                init_desc_masks(&desc[i]);
                desc[i].kstat_irqs = kstat_irqs_all[i];