struct module;
 struct irq_desc;
 struct irq_data;
+struct msi_msg;
 typedef        void (*irq_flow_handler_t)(unsigned int irq,
                                            struct irq_desc *desc);
 typedef        void (*irq_preflow_handler_t)(struct irq_data *data);
  *                             any other callback related to this irq
  * @irq_release_resources:     optional to release resources acquired with
  *                             irq_request_resources
+ * @irq_compose_msi_msg:       optional to compose message content for MSI
  * @flags:             chip specific flags
  */
 struct irq_chip {
        int             (*irq_request_resources)(struct irq_data *data);
        void            (*irq_release_resources)(struct irq_data *data);
 
+       void            (*irq_compose_msi_msg)(struct irq_data *data, struct msi_msg *msg);
+
        unsigned long   flags;
 };
 
 extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_nested_irq(unsigned int irq);
 
+extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg);
 #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
 extern void irq_chip_ack_parent(struct irq_data *data);
 extern int irq_chip_retrigger_hierarchy(struct irq_data *data);
 
        return -ENOSYS;
 }
 #endif
+
+/**
+ * irq_chip_compose_msi_msg - Componse msi message for a irq chip
+ * @data:      Pointer to interrupt specific data
+ * @msg:       Pointer to the MSI message
+ *
+ * For hierarchical domains we find the first chip in the hierarchy
+ * which implements the irq_compose_msi_msg callback. For non
+ * hierarchical we use the top level chip.
+ */
+int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+{
+       struct irq_data *pos = NULL;
+
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+       for (; data; data = data->parent_data)
+#endif
+               if (data->chip && data->chip->irq_compose_msi_msg)
+                       pos = data;
+       if (!pos)
+               return -ENOSYS;
+
+       pos->chip->irq_compose_msi_msg(pos, msg);
+
+       return 0;
+}