LCOV - code coverage report
Current view: top level - drivers/pci/msi - msi.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 30 0.0 %
Date: 2023-04-06 08:38:28 Functions: 0 6 0.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0 */
       2             : 
       3             : #include <linux/pci.h>
       4             : #include <linux/msi.h>
       5             : 
       6             : #define msix_table_size(flags)  ((flags & PCI_MSIX_FLAGS_QSIZE) + 1)
       7             : 
       8             : int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
       9             : void pci_msi_teardown_msi_irqs(struct pci_dev *dev);
      10             : 
      11             : /* Mask/unmask helpers */
      12             : void pci_msi_update_mask(struct msi_desc *desc, u32 clear, u32 set);
      13             : 
      14             : static inline void pci_msi_mask(struct msi_desc *desc, u32 mask)
      15             : {
      16           0 :         pci_msi_update_mask(desc, 0, mask);
      17             : }
      18             : 
      19             : static inline void pci_msi_unmask(struct msi_desc *desc, u32 mask)
      20             : {
      21           0 :         pci_msi_update_mask(desc, mask, 0);
      22             : }
      23             : 
      24             : static inline void __iomem *pci_msix_desc_addr(struct msi_desc *desc)
      25             : {
      26           0 :         return desc->pci.mask_base + desc->msi_index * PCI_MSIX_ENTRY_SIZE;
      27             : }
      28             : 
      29             : /*
      30             :  * This internal function does not flush PCI writes to the device.  All
      31             :  * users must ensure that they read from the device before either assuming
      32             :  * that the device state is up to date, or returning out of this file.
      33             :  * It does not affect the msi_desc::msix_ctrl cache either. Use with care!
      34             :  */
      35           0 : static inline void pci_msix_write_vector_ctrl(struct msi_desc *desc, u32 ctrl)
      36             : {
      37           0 :         void __iomem *desc_addr = pci_msix_desc_addr(desc);
      38             : 
      39           0 :         if (desc->pci.msi_attrib.can_mask)
      40           0 :                 writel(ctrl, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL);
      41           0 : }
      42             : 
      43           0 : static inline void pci_msix_mask(struct msi_desc *desc)
      44             : {
      45           0 :         desc->pci.msix_ctrl |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
      46           0 :         pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl);
      47             :         /* Flush write to device */
      48           0 :         readl(desc->pci.mask_base);
      49           0 : }
      50             : 
      51             : static inline void pci_msix_unmask(struct msi_desc *desc)
      52             : {
      53           0 :         desc->pci.msix_ctrl &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
      54           0 :         pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl);
      55             : }
      56             : 
      57           0 : static inline void __pci_msi_mask_desc(struct msi_desc *desc, u32 mask)
      58             : {
      59           0 :         if (desc->pci.msi_attrib.is_msix)
      60           0 :                 pci_msix_mask(desc);
      61             :         else
      62             :                 pci_msi_mask(desc, mask);
      63           0 : }
      64             : 
      65           0 : static inline void __pci_msi_unmask_desc(struct msi_desc *desc, u32 mask)
      66             : {
      67           0 :         if (desc->pci.msi_attrib.is_msix)
      68             :                 pci_msix_unmask(desc);
      69             :         else
      70             :                 pci_msi_unmask(desc, mask);
      71           0 : }
      72             : 
      73             : /*
      74             :  * PCI 2.3 does not specify mask bits for each MSI interrupt.  Attempting to
      75             :  * mask all MSI interrupts by clearing the MSI enable bit does not work
      76             :  * reliably as devices without an INTx disable bit will then generate a
      77             :  * level IRQ which will never be cleared.
      78             :  */
      79             : static inline __attribute_const__ u32 msi_multi_mask(struct msi_desc *desc)
      80             : {
      81             :         /* Don't shift by >= width of type */
      82           0 :         if (desc->pci.msi_attrib.multi_cap >= 5)
      83             :                 return 0xffffffff;
      84           0 :         return (1 << (1 << desc->pci.msi_attrib.multi_cap)) - 1;
      85             : }
      86             : 
      87             : void msix_prepare_msi_desc(struct pci_dev *dev, struct msi_desc *desc);
      88             : 
      89             : /* Subsystem variables */
      90             : extern int pci_msi_enable;
      91             : 
      92             : /* MSI internal functions invoked from the public APIs */
      93             : void pci_msi_shutdown(struct pci_dev *dev);
      94             : void pci_msix_shutdown(struct pci_dev *dev);
      95             : void pci_free_msi_irqs(struct pci_dev *dev);
      96             : int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, struct irq_affinity *affd);
      97             : int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec,
      98             :                             int maxvec,  struct irq_affinity *affd, int flags);
      99             : void __pci_restore_msi_state(struct pci_dev *dev);
     100             : void __pci_restore_msix_state(struct pci_dev *dev);
     101             : 
     102             : /* irq_domain related functionality */
     103             : 
     104             : enum support_mode {
     105             :         ALLOW_LEGACY,
     106             :         DENY_LEGACY,
     107             : };
     108             : 
     109             : bool pci_msi_domain_supports(struct pci_dev *dev, unsigned int feature_mask, enum support_mode mode);
     110             : bool pci_setup_msi_device_domain(struct pci_dev *pdev);
     111             : bool pci_setup_msix_device_domain(struct pci_dev *pdev, unsigned int hwsize);
     112             : 
     113             : /* Legacy (!IRQDOMAIN) fallbacks */
     114             : 
     115             : #ifdef CONFIG_PCI_MSI_ARCH_FALLBACKS
     116             : int pci_msi_legacy_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
     117             : void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev);
     118             : #else
     119           0 : static inline int pci_msi_legacy_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
     120             : {
     121           0 :         WARN_ON_ONCE(1);
     122           0 :         return -ENODEV;
     123             : }
     124             : 
     125           0 : static inline void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev)
     126             : {
     127           0 :         WARN_ON_ONCE(1);
     128           0 : }
     129             : #endif

Generated by: LCOV version 1.14