linux/include/linux/msi.h
<<
>>
Prefs
   1#ifndef LINUX_MSI_H
   2#define LINUX_MSI_H
   3
   4#include <linux/kobject.h>
   5#include <linux/list.h>
   6
   7struct msi_msg {
   8        u32     address_lo;     /* low 32 bits of msi message address */
   9        u32     address_hi;     /* high 32 bits of msi message address */
  10        u32     data;           /* 16 bits of msi message data */
  11};
  12
  13extern int pci_msi_ignore_mask;
  14/* Helper functions */
  15struct irq_data;
  16struct msi_desc;
  17void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
  18void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);
  19
  20struct msi_desc {
  21        struct {
  22                __u8    is_msix : 1;
  23                __u8    multiple: 3;    /* log2 num of messages allocated */
  24                __u8    multi_cap : 3;  /* log2 num of messages supported */
  25                __u8    maskbit : 1;    /* mask-pending bit supported ? */
  26                __u8    is_64   : 1;    /* Address size: 0=32bit 1=64bit */
  27                __u16   entry_nr;       /* specific enabled entry */
  28                unsigned default_irq;   /* default pre-assigned irq */
  29        } msi_attrib;
  30
  31        u32 masked;                     /* mask bits */
  32        unsigned int irq;
  33        unsigned int nvec_used;         /* number of messages */
  34        struct list_head list;
  35
  36        union {
  37                void __iomem *mask_base;
  38                u8 mask_pos;
  39        };
  40        struct pci_dev *dev;
  41
  42        /* Last set MSI message */
  43        struct msi_msg msg;
  44};
  45
  46/* Helpers to hide struct msi_desc implementation details */
  47#define msi_desc_to_dev(desc)           (&(desc)->dev.dev)
  48#define dev_to_msi_list(dev)            (&to_pci_dev((dev))->msi_list)
  49#define first_msi_entry(dev)            \
  50        list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list)
  51#define for_each_msi_entry(desc, dev)   \
  52        list_for_each_entry((desc), dev_to_msi_list((dev)), list)
  53
  54#ifdef CONFIG_PCI_MSI
  55#define first_pci_msi_entry(pdev)       first_msi_entry(&(pdev)->dev)
  56#define for_each_pci_msi_entry(desc, pdev)      \
  57        for_each_msi_entry((desc), &(pdev)->dev)
  58
  59static inline struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
  60{
  61        return desc->dev;
  62}
  63#endif /* CONFIG_PCI_MSI */
  64
  65void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
  66void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
  67void pci_write_msi_msg(unsigned int irq, struct msi_msg *msg);
  68
  69u32 __pci_msix_desc_mask_irq(struct msi_desc *desc, u32 flag);
  70u32 __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag);
  71void pci_msi_mask_irq(struct irq_data *data);
  72void pci_msi_unmask_irq(struct irq_data *data);
  73
  74/* Conversion helpers. Should be removed after merging */
  75static inline void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
  76{
  77        __pci_write_msi_msg(entry, msg);
  78}
  79static inline void write_msi_msg(int irq, struct msi_msg *msg)
  80{
  81        pci_write_msi_msg(irq, msg);
  82}
  83static inline void mask_msi_irq(struct irq_data *data)
  84{
  85        pci_msi_mask_irq(data);
  86}
  87static inline void unmask_msi_irq(struct irq_data *data)
  88{
  89        pci_msi_unmask_irq(data);
  90}
  91
  92/*
  93 * The arch hooks to setup up msi irqs. Those functions are
  94 * implemented as weak symbols so that they /can/ be overriden by
  95 * architecture specific code if needed.
  96 */
  97int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc);
  98void arch_teardown_msi_irq(unsigned int irq);
  99int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
 100void arch_teardown_msi_irqs(struct pci_dev *dev);
 101void arch_restore_msi_irqs(struct pci_dev *dev);
 102
 103void default_teardown_msi_irqs(struct pci_dev *dev);
 104void default_restore_msi_irqs(struct pci_dev *dev);
 105
 106struct msi_controller {
 107        struct module *owner;
 108        struct device *dev;
 109        struct device_node *of_node;
 110        struct list_head list;
 111#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
 112        struct irq_domain *domain;
 113#endif
 114
 115        int (*setup_irq)(struct msi_controller *chip, struct pci_dev *dev,
 116                         struct msi_desc *desc);
 117        void (*teardown_irq)(struct msi_controller *chip, unsigned int irq);
 118};
 119
 120#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
 121
 122#include <linux/irqhandler.h>
 123#include <asm/msi.h>
 124
 125struct irq_domain;
 126struct irq_chip;
 127struct device_node;
 128struct msi_domain_info;
 129
 130/**
 131 * struct msi_domain_ops - MSI interrupt domain callbacks
 132 * @get_hwirq:          Retrieve the resulting hw irq number
 133 * @msi_init:           Domain specific init function for MSI interrupts
 134 * @msi_free:           Domain specific function to free a MSI interrupts
 135 * @msi_check:          Callback for verification of the domain/info/dev data
 136 * @msi_prepare:        Prepare the allocation of the interrupts in the domain
 137 * @msi_finish:         Optional callbacl to finalize the allocation
 138 * @set_desc:           Set the msi descriptor for an interrupt
 139 * @handle_error:       Optional error handler if the allocation fails
 140 *
 141 * @get_hwirq, @msi_init and @msi_free are callbacks used by
 142 * msi_create_irq_domain() and related interfaces
 143 *
 144 * @msi_check, @msi_prepare, @msi_finish, @set_desc and @handle_error
 145 * are callbacks used by msi_irq_domain_alloc_irqs() and related
 146 * interfaces which are based on msi_desc.
 147 */
 148struct msi_domain_ops {
 149        irq_hw_number_t (*get_hwirq)(struct msi_domain_info *info,
 150                                     msi_alloc_info_t *arg);
 151        int             (*msi_init)(struct irq_domain *domain,
 152                                    struct msi_domain_info *info,
 153                                    unsigned int virq, irq_hw_number_t hwirq,
 154                                    msi_alloc_info_t *arg);
 155        void            (*msi_free)(struct irq_domain *domain,
 156                                    struct msi_domain_info *info,
 157                                    unsigned int virq);
 158        int             (*msi_check)(struct irq_domain *domain,
 159                                     struct msi_domain_info *info,
 160                                     struct device *dev);
 161        int             (*msi_prepare)(struct irq_domain *domain,
 162                                       struct device *dev, int nvec,
 163                                       msi_alloc_info_t *arg);
 164        void            (*msi_finish)(msi_alloc_info_t *arg, int retval);
 165        void            (*set_desc)(msi_alloc_info_t *arg,
 166                                    struct msi_desc *desc);
 167        int             (*handle_error)(struct irq_domain *domain,
 168                                        struct msi_desc *desc, int error);
 169};
 170
 171/**
 172 * struct msi_domain_info - MSI interrupt domain data
 173 * @flags:              Flags to decribe features and capabilities
 174 * @ops:                The callback data structure
 175 * @chip:               Optional: associated interrupt chip
 176 * @chip_data:          Optional: associated interrupt chip data
 177 * @handler:            Optional: associated interrupt flow handler
 178 * @handler_data:       Optional: associated interrupt flow handler data
 179 * @handler_name:       Optional: associated interrupt flow handler name
 180 * @data:               Optional: domain specific data
 181 */
 182struct msi_domain_info {
 183        u32                     flags;
 184        struct msi_domain_ops   *ops;
 185        struct irq_chip         *chip;
 186        void                    *chip_data;
 187        irq_flow_handler_t      handler;
 188        void                    *handler_data;
 189        const char              *handler_name;
 190        void                    *data;
 191};
 192
 193/* Flags for msi_domain_info */
 194enum {
 195        /*
 196         * Init non implemented ops callbacks with default MSI domain
 197         * callbacks.
 198         */
 199        MSI_FLAG_USE_DEF_DOM_OPS        = (1 << 0),
 200        /*
 201         * Init non implemented chip callbacks with default MSI chip
 202         * callbacks.
 203         */
 204        MSI_FLAG_USE_DEF_CHIP_OPS       = (1 << 1),
 205        /* Build identity map between hwirq and irq */
 206        MSI_FLAG_IDENTITY_MAP           = (1 << 2),
 207        /* Support multiple PCI MSI interrupts */
 208        MSI_FLAG_MULTI_PCI_MSI          = (1 << 3),
 209        /* Support PCI MSIX interrupts */
 210        MSI_FLAG_PCI_MSIX               = (1 << 4),
 211};
 212
 213int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,
 214                            bool force);
 215
 216struct irq_domain *msi_create_irq_domain(struct device_node *of_node,
 217                                         struct msi_domain_info *info,
 218                                         struct irq_domain *parent);
 219int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
 220                          int nvec);
 221void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev);
 222struct msi_domain_info *msi_get_domain_info(struct irq_domain *domain);
 223
 224#endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */
 225
 226#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
 227void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg);
 228struct irq_domain *pci_msi_create_irq_domain(struct device_node *node,
 229                                             struct msi_domain_info *info,
 230                                             struct irq_domain *parent);
 231int pci_msi_domain_alloc_irqs(struct irq_domain *domain, struct pci_dev *dev,
 232                              int nvec, int type);
 233void pci_msi_domain_free_irqs(struct irq_domain *domain, struct pci_dev *dev);
 234struct irq_domain *pci_msi_create_default_irq_domain(struct device_node *node,
 235                 struct msi_domain_info *info, struct irq_domain *parent);
 236
 237irq_hw_number_t pci_msi_domain_calc_hwirq(struct pci_dev *dev,
 238                                          struct msi_desc *desc);
 239int pci_msi_domain_check_cap(struct irq_domain *domain,
 240                             struct msi_domain_info *info, struct device *dev);
 241#endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */
 242
 243#endif /* LINUX_MSI_H */
 244