brintos

brintos / linux-shallow public Read only

0
0
Text · 21.9 KiB · b10093c Raw
672 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef LINUX_MSI_H3#define LINUX_MSI_H4 5/*6 * This header file contains MSI data structures and functions which are7 * only relevant for:8 *	- Interrupt core code9 *	- PCI/MSI core code10 *	- MSI interrupt domain implementations11 *	- IOMMU, low level VFIO, NTB and other justified exceptions12 *	  dealing with low level MSI details.13 *14 * Regular device drivers have no business with any of these functions and15 * especially storing MSI descriptor pointers in random code is considered16 * abuse.17 *18 * Device driver relevant functions are available in <linux/msi_api.h>19 */20 21#include <linux/irqdomain_defs.h>22#include <linux/cpumask_types.h>23#include <linux/msi_api.h>24#include <linux/irq.h>25 26#include <asm/msi.h>27 28/* Dummy shadow structures if an architecture does not define them */29#ifndef arch_msi_msg_addr_lo30typedef struct arch_msi_msg_addr_lo {31	u32	address_lo;32} __attribute__ ((packed)) arch_msi_msg_addr_lo_t;33#endif34 35#ifndef arch_msi_msg_addr_hi36typedef struct arch_msi_msg_addr_hi {37	u32	address_hi;38} __attribute__ ((packed)) arch_msi_msg_addr_hi_t;39#endif40 41#ifndef arch_msi_msg_data42typedef struct arch_msi_msg_data {43	u32	data;44} __attribute__ ((packed)) arch_msi_msg_data_t;45#endif46 47#ifndef arch_is_isolated_msi48#define arch_is_isolated_msi() false49#endif50 51/**52 * msi_msg - Representation of a MSI message53 * @address_lo:		Low 32 bits of msi message address54 * @arch_addrlo:	Architecture specific shadow of @address_lo55 * @address_hi:		High 32 bits of msi message address56 *			(only used when device supports it)57 * @arch_addrhi:	Architecture specific shadow of @address_hi58 * @data:		MSI message data (usually 16 bits)59 * @arch_data:		Architecture specific shadow of @data60 */61struct msi_msg {62	union {63		u32			address_lo;64		arch_msi_msg_addr_lo_t	arch_addr_lo;65	};66	union {67		u32			address_hi;68		arch_msi_msg_addr_hi_t	arch_addr_hi;69	};70	union {71		u32			data;72		arch_msi_msg_data_t	arch_data;73	};74};75 76extern int pci_msi_ignore_mask;77/* Helper functions */78struct msi_desc;79struct pci_dev;80struct device_attribute;81struct irq_domain;82struct irq_affinity_desc;83 84void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);85#ifdef CONFIG_GENERIC_MSI_IRQ86void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);87#else88static inline void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg) { }89#endif90 91typedef void (*irq_write_msi_msg_t)(struct msi_desc *desc,92				    struct msi_msg *msg);93 94/**95 * pci_msi_desc - PCI/MSI specific MSI descriptor data96 *97 * @msi_mask:	[PCI MSI]   MSI cached mask bits98 * @msix_ctrl:	[PCI MSI-X] MSI-X cached per vector control bits99 * @is_msix:	[PCI MSI/X] True if MSI-X100 * @multiple:	[PCI MSI/X] log2 num of messages allocated101 * @multi_cap:	[PCI MSI/X] log2 num of messages supported102 * @can_mask:	[PCI MSI/X] Masking supported?103 * @is_64:	[PCI MSI/X] Address size: 0=32bit 1=64bit104 * @default_irq:[PCI MSI/X] The default pre-assigned non-MSI irq105 * @mask_pos:	[PCI MSI]   Mask register position106 * @mask_base:	[PCI MSI-X] Mask register base address107 */108struct pci_msi_desc {109	union {110		u32 msi_mask;111		u32 msix_ctrl;112	};113	struct {114		u8	is_msix		: 1;115		u8	multiple	: 3;116		u8	multi_cap	: 3;117		u8	can_mask	: 1;118		u8	is_64		: 1;119		u8	is_virtual	: 1;120		unsigned default_irq;121	} msi_attrib;122	union {123		u8	mask_pos;124		void __iomem *mask_base;125	};126};127 128/**129 * union msi_domain_cookie - Opaque MSI domain specific data130 * @value:	u64 value store131 * @ptr:	Pointer to domain specific data132 * @iobase:	Domain specific IOmem pointer133 *134 * The content of this data is implementation defined and used by the MSI135 * domain to store domain specific information which is requried for136 * interrupt chip callbacks.137 */138union msi_domain_cookie {139	u64	value;140	void	*ptr;141	void	__iomem *iobase;142};143 144/**145 * struct msi_desc_data - Generic MSI descriptor data146 * @dcookie:	Cookie for MSI domain specific data which is required147 *		for irq_chip callbacks148 * @icookie:	Cookie for the MSI interrupt instance provided by149 *		the usage site to the allocation function150 *151 * The content of this data is implementation defined, e.g. PCI/IMS152 * implementations define the meaning of the data. The MSI core ignores153 * this data completely.154 */155struct msi_desc_data {156	union msi_domain_cookie		dcookie;157	union msi_instance_cookie	icookie;158};159 160#define MSI_MAX_INDEX		((unsigned int)USHRT_MAX)161 162/**163 * struct msi_desc - Descriptor structure for MSI based interrupts164 * @irq:	The base interrupt number165 * @nvec_used:	The number of vectors used166 * @dev:	Pointer to the device which uses this descriptor167 * @msg:	The last set MSI message cached for reuse168 * @affinity:	Optional pointer to a cpu affinity mask for this descriptor169 * @sysfs_attr:	Pointer to sysfs device attribute170 *171 * @write_msi_msg:	Callback that may be called when the MSI message172 *			address or data changes173 * @write_msi_msg_data:	Data parameter for the callback.174 *175 * @msi_index:	Index of the msi descriptor176 * @pci:	PCI specific msi descriptor data177 * @data:	Generic MSI descriptor data178 */179struct msi_desc {180	/* Shared device/bus type independent data */181	unsigned int			irq;182	unsigned int			nvec_used;183	struct device			*dev;184	struct msi_msg			msg;185	struct irq_affinity_desc	*affinity;186#ifdef CONFIG_IRQ_MSI_IOMMU187	const void			*iommu_cookie;188#endif189#ifdef CONFIG_SYSFS190	struct device_attribute		*sysfs_attrs;191#endif192 193	void (*write_msi_msg)(struct msi_desc *entry, void *data);194	void *write_msi_msg_data;195 196	u16				msi_index;197	union {198		struct pci_msi_desc	pci;199		struct msi_desc_data	data;200	};201};202 203/*204 * Filter values for the MSI descriptor iterators and accessor functions.205 */206enum msi_desc_filter {207	/* All descriptors */208	MSI_DESC_ALL,209	/* Descriptors which have no interrupt associated */210	MSI_DESC_NOTASSOCIATED,211	/* Descriptors which have an interrupt associated */212	MSI_DESC_ASSOCIATED,213};214 215 216/**217 * struct msi_dev_domain - The internals of MSI domain info per device218 * @store:		Xarray for storing MSI descriptor pointers219 * @irqdomain:		Pointer to a per device interrupt domain220 */221struct msi_dev_domain {222	struct xarray		store;223	struct irq_domain	*domain;224};225 226int msi_setup_device_data(struct device *dev);227 228void msi_lock_descs(struct device *dev);229void msi_unlock_descs(struct device *dev);230 231struct msi_desc *msi_domain_first_desc(struct device *dev, unsigned int domid,232				       enum msi_desc_filter filter);233 234/**235 * msi_first_desc - Get the first MSI descriptor of the default irqdomain236 * @dev:	Device to operate on237 * @filter:	Descriptor state filter238 *239 * Must be called with the MSI descriptor mutex held, i.e. msi_lock_descs()240 * must be invoked before the call.241 *242 * Return: Pointer to the first MSI descriptor matching the search243 *	   criteria, NULL if none found.244 */245static inline struct msi_desc *msi_first_desc(struct device *dev,246					      enum msi_desc_filter filter)247{248	return msi_domain_first_desc(dev, MSI_DEFAULT_DOMAIN, filter);249}250 251struct msi_desc *msi_next_desc(struct device *dev, unsigned int domid,252			       enum msi_desc_filter filter);253 254/**255 * msi_domain_for_each_desc - Iterate the MSI descriptors in a specific domain256 *257 * @desc:	struct msi_desc pointer used as iterator258 * @dev:	struct device pointer - device to iterate259 * @domid:	The id of the interrupt domain which should be walked.260 * @filter:	Filter for descriptor selection261 *262 * Notes:263 *  - The loop must be protected with a msi_lock_descs()/msi_unlock_descs()264 *    pair.265 *  - It is safe to remove a retrieved MSI descriptor in the loop.266 */267#define msi_domain_for_each_desc(desc, dev, domid, filter)			\268	for ((desc) = msi_domain_first_desc((dev), (domid), (filter)); (desc);	\269	     (desc) = msi_next_desc((dev), (domid), (filter)))270 271/**272 * msi_for_each_desc - Iterate the MSI descriptors in the default irqdomain273 *274 * @desc:	struct msi_desc pointer used as iterator275 * @dev:	struct device pointer - device to iterate276 * @filter:	Filter for descriptor selection277 *278 * Notes:279 *  - The loop must be protected with a msi_lock_descs()/msi_unlock_descs()280 *    pair.281 *  - It is safe to remove a retrieved MSI descriptor in the loop.282 */283#define msi_for_each_desc(desc, dev, filter)					\284	msi_domain_for_each_desc((desc), (dev), MSI_DEFAULT_DOMAIN, (filter))285 286#define msi_desc_to_dev(desc)		((desc)->dev)287 288#ifdef CONFIG_IRQ_MSI_IOMMU289static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc)290{291	return desc->iommu_cookie;292}293 294static inline void msi_desc_set_iommu_cookie(struct msi_desc *desc,295					     const void *iommu_cookie)296{297	desc->iommu_cookie = iommu_cookie;298}299#else300static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc)301{302	return NULL;303}304 305static inline void msi_desc_set_iommu_cookie(struct msi_desc *desc,306					     const void *iommu_cookie)307{308}309#endif310 311int msi_domain_insert_msi_desc(struct device *dev, unsigned int domid,312			       struct msi_desc *init_desc);313/**314 * msi_insert_msi_desc - Allocate and initialize a MSI descriptor in the315 *			 default irqdomain and insert it at @init_desc->msi_index316 * @dev:	Pointer to the device for which the descriptor is allocated317 * @init_desc:	Pointer to an MSI descriptor to initialize the new descriptor318 *319 * Return: 0 on success or an appropriate failure code.320 */321static inline int msi_insert_msi_desc(struct device *dev, struct msi_desc *init_desc)322{323	return msi_domain_insert_msi_desc(dev, MSI_DEFAULT_DOMAIN, init_desc);324}325 326void msi_domain_free_msi_descs_range(struct device *dev, unsigned int domid,327				     unsigned int first, unsigned int last);328 329/**330 * msi_free_msi_descs_range - Free a range of MSI descriptors of a device331 *			      in the default irqdomain332 *333 * @dev:	Device for which to free the descriptors334 * @first:	Index to start freeing from (inclusive)335 * @last:	Last index to be freed (inclusive)336 */337static inline void msi_free_msi_descs_range(struct device *dev, unsigned int first,338					    unsigned int last)339{340	msi_domain_free_msi_descs_range(dev, MSI_DEFAULT_DOMAIN, first, last);341}342 343/**344 * msi_free_msi_descs - Free all MSI descriptors of a device in the default irqdomain345 * @dev:	Device to free the descriptors346 */347static inline void msi_free_msi_descs(struct device *dev)348{349	msi_free_msi_descs_range(dev, 0, MSI_MAX_INDEX);350}351 352/*353 * The arch hooks to setup up msi irqs. Default functions are implemented354 * as weak symbols so that they /can/ be overriden by architecture specific355 * code if needed. These hooks can only be enabled by the architecture.356 *357 * If CONFIG_PCI_MSI_ARCH_FALLBACKS is not selected they are replaced by358 * stubs with warnings.359 */360#ifdef CONFIG_PCI_MSI_ARCH_FALLBACKS361int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc);362void arch_teardown_msi_irq(unsigned int irq);363int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);364void arch_teardown_msi_irqs(struct pci_dev *dev);365#endif /* CONFIG_PCI_MSI_ARCH_FALLBACKS */366 367/*368 * Xen uses non-default msi_domain_ops and hence needs a way to populate sysfs369 * entries of MSI IRQs.370 */371#if defined(CONFIG_PCI_XEN) || defined(CONFIG_PCI_MSI_ARCH_FALLBACKS)372#ifdef CONFIG_SYSFS373int msi_device_populate_sysfs(struct device *dev);374void msi_device_destroy_sysfs(struct device *dev);375#else /* CONFIG_SYSFS */376static inline int msi_device_populate_sysfs(struct device *dev) { return 0; }377static inline void msi_device_destroy_sysfs(struct device *dev) { }378#endif /* !CONFIG_SYSFS */379#endif /* CONFIG_PCI_XEN || CONFIG_PCI_MSI_ARCH_FALLBACKS */380 381/*382 * The restore hook is still available even for fully irq domain based383 * setups. Courtesy to XEN/X86.384 */385bool arch_restore_msi_irqs(struct pci_dev *dev);386 387#ifdef CONFIG_GENERIC_MSI_IRQ388 389#include <linux/irqhandler.h>390 391struct irq_domain;392struct irq_domain_ops;393struct irq_chip;394struct irq_fwspec;395struct device_node;396struct fwnode_handle;397struct msi_domain_info;398 399/**400 * struct msi_domain_ops - MSI interrupt domain callbacks401 * @get_hwirq:		Retrieve the resulting hw irq number402 * @msi_init:		Domain specific init function for MSI interrupts403 * @msi_free:		Domain specific function to free a MSI interrupts404 * @msi_prepare:	Prepare the allocation of the interrupts in the domain405 * @prepare_desc:	Optional function to prepare the allocated MSI descriptor406 *			in the domain407 * @set_desc:		Set the msi descriptor for an interrupt408 * @domain_alloc_irqs:	Optional function to override the default allocation409 *			function.410 * @domain_free_irqs:	Optional function to override the default free411 *			function.412 * @msi_post_free:	Optional function which is invoked after freeing413 *			all interrupts.414 * @msi_translate:	Optional translate callback to support the odd wire to415 *			MSI bridges, e.g. MBIGEN416 *417 * @get_hwirq, @msi_init and @msi_free are callbacks used by the underlying418 * irqdomain.419 *420 * @msi_check, @msi_prepare, @prepare_desc and @set_desc are callbacks used by the421 * msi_domain_alloc/free_irqs*() variants.422 *423 * @domain_alloc_irqs, @domain_free_irqs can be used to override the424 * default allocation/free functions (__msi_domain_alloc/free_irqs). This425 * is initially for a wrapper around XENs seperate MSI universe which can't426 * be wrapped into the regular irq domains concepts by mere mortals.  This427 * allows to universally use msi_domain_alloc/free_irqs without having to428 * special case XEN all over the place.429 */430struct msi_domain_ops {431	irq_hw_number_t	(*get_hwirq)(struct msi_domain_info *info,432				     msi_alloc_info_t *arg);433	int		(*msi_init)(struct irq_domain *domain,434				    struct msi_domain_info *info,435				    unsigned int virq, irq_hw_number_t hwirq,436				    msi_alloc_info_t *arg);437	void		(*msi_free)(struct irq_domain *domain,438				    struct msi_domain_info *info,439				    unsigned int virq);440	int		(*msi_prepare)(struct irq_domain *domain,441				       struct device *dev, int nvec,442				       msi_alloc_info_t *arg);443	void		(*prepare_desc)(struct irq_domain *domain, msi_alloc_info_t *arg,444					struct msi_desc *desc);445	void		(*set_desc)(msi_alloc_info_t *arg,446				    struct msi_desc *desc);447	int		(*domain_alloc_irqs)(struct irq_domain *domain,448					     struct device *dev, int nvec);449	void		(*domain_free_irqs)(struct irq_domain *domain,450					    struct device *dev);451	void		(*msi_post_free)(struct irq_domain *domain,452					 struct device *dev);453	int		(*msi_translate)(struct irq_domain *domain, struct irq_fwspec *fwspec,454					 irq_hw_number_t *hwirq, unsigned int *type);455};456 457/**458 * struct msi_domain_info - MSI interrupt domain data459 * @flags:		Flags to decribe features and capabilities460 * @bus_token:		The domain bus token461 * @hwsize:		The hardware table size or the software index limit.462 *			If 0 then the size is considered unlimited and463 *			gets initialized to the maximum software index limit464 *			by the domain creation code.465 * @ops:		The callback data structure466 * @chip:		Optional: associated interrupt chip467 * @chip_data:		Optional: associated interrupt chip data468 * @handler:		Optional: associated interrupt flow handler469 * @handler_data:	Optional: associated interrupt flow handler data470 * @handler_name:	Optional: associated interrupt flow handler name471 * @data:		Optional: domain specific data472 */473struct msi_domain_info {474	u32				flags;475	enum irq_domain_bus_token	bus_token;476	unsigned int			hwsize;477	struct msi_domain_ops		*ops;478	struct irq_chip			*chip;479	void				*chip_data;480	irq_flow_handler_t		handler;481	void				*handler_data;482	const char			*handler_name;483	void				*data;484};485 486/**487 * struct msi_domain_template - Template for MSI device domains488 * @name:	Storage for the resulting name. Filled in by the core.489 * @chip:	Interrupt chip for this domain490 * @ops:	MSI domain ops491 * @info:	MSI domain info data492 */493struct msi_domain_template {494	char			name[48];495	struct irq_chip		chip;496	struct msi_domain_ops	ops;497	struct msi_domain_info	info;498};499 500/*501 * Flags for msi_domain_info502 *503 * Bit 0-15:	Generic MSI functionality which is not subject to restriction504 *		by parent domains505 *506 * Bit 16-31:	Functionality which depends on the underlying parent domain and507 *		can be masked out by msi_parent_ops::init_dev_msi_info() when508 *		a device MSI domain is initialized.509 */510enum {511	/*512	 * Init non implemented ops callbacks with default MSI domain513	 * callbacks.514	 */515	MSI_FLAG_USE_DEF_DOM_OPS	= (1 << 0),516	/*517	 * Init non implemented chip callbacks with default MSI chip518	 * callbacks.519	 */520	MSI_FLAG_USE_DEF_CHIP_OPS	= (1 << 1),521	/* Needs early activate, required for PCI */522	MSI_FLAG_ACTIVATE_EARLY		= (1 << 2),523	/*524	 * Must reactivate when irq is started even when525	 * MSI_FLAG_ACTIVATE_EARLY has been set.526	 */527	MSI_FLAG_MUST_REACTIVATE	= (1 << 3),528	/* Populate sysfs on alloc() and destroy it on free() */529	MSI_FLAG_DEV_SYSFS		= (1 << 4),530	/* Allocate simple MSI descriptors */531	MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS	= (1 << 5),532	/* Free MSI descriptors */533	MSI_FLAG_FREE_MSI_DESCS		= (1 << 6),534	/* Use dev->fwnode for MSI device domain creation */535	MSI_FLAG_USE_DEV_FWNODE		= (1 << 7),536	/* Set parent->dev into domain->pm_dev on device domain creation */537	MSI_FLAG_PARENT_PM_DEV		= (1 << 8),538	/* Support for parent mask/unmask */539	MSI_FLAG_PCI_MSI_MASK_PARENT	= (1 << 9),540 541	/* Mask for the generic functionality */542	MSI_GENERIC_FLAGS_MASK		= GENMASK(15, 0),543 544	/* Mask for the domain specific functionality */545	MSI_DOMAIN_FLAGS_MASK		= GENMASK(31, 16),546 547	/* Support multiple PCI MSI interrupts */548	MSI_FLAG_MULTI_PCI_MSI		= (1 << 16),549	/* Support PCI MSIX interrupts */550	MSI_FLAG_PCI_MSIX		= (1 << 17),551	/* Is level-triggered capable, using two messages */552	MSI_FLAG_LEVEL_CAPABLE		= (1 << 18),553	/* MSI-X entries must be contiguous */554	MSI_FLAG_MSIX_CONTIGUOUS	= (1 << 19),555	/* PCI/MSI-X vectors can be dynamically allocated/freed post MSI-X enable */556	MSI_FLAG_PCI_MSIX_ALLOC_DYN	= (1 << 20),557	/* PCI MSIs cannot be steered separately to CPU cores */558	MSI_FLAG_NO_AFFINITY		= (1 << 21),559};560 561/**562 * struct msi_parent_ops - MSI parent domain callbacks and configuration info563 *564 * @supported_flags:	Required: The supported MSI flags of the parent domain565 * @required_flags:	Optional: The required MSI flags of the parent MSI domain566 * @bus_select_token:	Optional: The bus token of the real parent domain for567 *			irq_domain::select()568 * @bus_select_mask:	Optional: A mask of supported BUS_DOMAINs for569 *			irq_domain::select()570 * @prefix:		Optional: Prefix for the domain and chip name571 * @init_dev_msi_info:	Required: Callback for MSI parent domains to setup parent572 *			domain specific domain flags, domain ops and interrupt chip573 *			callbacks when a per device domain is created.574 */575struct msi_parent_ops {576	u32		supported_flags;577	u32		required_flags;578	u32		bus_select_token;579	u32		bus_select_mask;580	const char	*prefix;581	bool		(*init_dev_msi_info)(struct device *dev, struct irq_domain *domain,582					     struct irq_domain *msi_parent_domain,583					     struct msi_domain_info *msi_child_info);584};585 586bool msi_parent_init_dev_msi_info(struct device *dev, struct irq_domain *domain,587				  struct irq_domain *msi_parent_domain,588				  struct msi_domain_info *msi_child_info);589 590int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,591			    bool force);592 593struct irq_domain *msi_create_irq_domain(struct fwnode_handle *fwnode,594					 struct msi_domain_info *info,595					 struct irq_domain *parent);596 597bool msi_create_device_irq_domain(struct device *dev, unsigned int domid,598				  const struct msi_domain_template *template,599				  unsigned int hwsize, void *domain_data,600				  void *chip_data);601void msi_remove_device_irq_domain(struct device *dev, unsigned int domid);602 603bool msi_match_device_irq_domain(struct device *dev, unsigned int domid,604				 enum irq_domain_bus_token bus_token);605 606int msi_domain_alloc_irqs_range_locked(struct device *dev, unsigned int domid,607				       unsigned int first, unsigned int last);608int msi_domain_alloc_irqs_range(struct device *dev, unsigned int domid,609				unsigned int first, unsigned int last);610int msi_domain_alloc_irqs_all_locked(struct device *dev, unsigned int domid, int nirqs);611 612struct msi_map msi_domain_alloc_irq_at(struct device *dev, unsigned int domid, unsigned int index,613				       const struct irq_affinity_desc *affdesc,614				       union msi_instance_cookie *cookie);615 616void msi_domain_free_irqs_range_locked(struct device *dev, unsigned int domid,617				       unsigned int first, unsigned int last);618void msi_domain_free_irqs_range(struct device *dev, unsigned int domid,619				unsigned int first, unsigned int last);620void msi_domain_free_irqs_all_locked(struct device *dev, unsigned int domid);621void msi_domain_free_irqs_all(struct device *dev, unsigned int domid);622 623struct msi_domain_info *msi_get_domain_info(struct irq_domain *domain);624 625/* Per device platform MSI */626int platform_device_msi_init_and_alloc_irqs(struct device *dev, unsigned int nvec,627					    irq_write_msi_msg_t write_msi_msg);628void platform_device_msi_free_irqs_all(struct device *dev);629 630bool msi_device_has_isolated_msi(struct device *dev);631 632static inline int msi_domain_alloc_irqs(struct device *dev, unsigned int domid, int nirqs)633{634	return msi_domain_alloc_irqs_range(dev, domid, 0, nirqs - 1);635}636 637#else /* CONFIG_GENERIC_MSI_IRQ */638static inline bool msi_device_has_isolated_msi(struct device *dev)639{640	/*641	 * Arguably if the platform does not enable MSI support then it has642	 * "isolated MSI", as an interrupt controller that cannot receive MSIs643	 * is inherently isolated by our definition. The default definition for644	 * arch_is_isolated_msi() is conservative and returns false anyhow.645	 */646	return arch_is_isolated_msi();647}648#endif /* CONFIG_GENERIC_MSI_IRQ */649 650/* PCI specific interfaces */651#ifdef CONFIG_PCI_MSI652struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc);653void pci_write_msi_msg(unsigned int irq, struct msi_msg *msg);654void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);655void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);656void pci_msi_mask_irq(struct irq_data *data);657void pci_msi_unmask_irq(struct irq_data *data);658struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode,659					     struct msi_domain_info *info,660					     struct irq_domain *parent);661u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev);662struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev);663#else /* CONFIG_PCI_MSI */664static inline struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)665{666	return NULL;667}668static inline void pci_write_msi_msg(unsigned int irq, struct msi_msg *msg) { }669#endif /* !CONFIG_PCI_MSI */670 671#endif /* LINUX_MSI_H */672