mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2024-11-30 03:24:14 +01:00
116 lines
3.6 KiB
C
116 lines
3.6 KiB
C
/*
|
|
* SPDX-FileCopyrightText: Copyright (c) 2018 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#ifndef _NV_MSI_H_
|
|
#define _NV_MSI_H_
|
|
|
|
#include "nv-linux.h"
|
|
|
|
#if (defined(CONFIG_X86_LOCAL_APIC) || defined(NVCPU_AARCH64) || \
|
|
defined(NVCPU_PPC64LE)) && \
|
|
(defined(CONFIG_PCI_MSI) || defined(CONFIG_PCI_USE_VECTOR))
|
|
#define NV_LINUX_PCIE_MSI_SUPPORTED
|
|
#endif
|
|
|
|
#if !defined(NV_LINUX_PCIE_MSI_SUPPORTED) || !defined(CONFIG_PCI_MSI)
|
|
#define NV_PCI_DISABLE_MSI(pci_dev)
|
|
#else
|
|
#define NV_PCI_DISABLE_MSI(pci_dev) pci_disable_msi(pci_dev)
|
|
#endif
|
|
|
|
irqreturn_t nvidia_isr (int, void *);
|
|
irqreturn_t nvidia_isr_msix (int, void *);
|
|
irqreturn_t nvidia_isr_kthread_bh (int, void *);
|
|
irqreturn_t nvidia_isr_msix_kthread_bh(int, void *);
|
|
|
|
#if defined(NV_LINUX_PCIE_MSI_SUPPORTED)
|
|
void NV_API_CALL nv_init_msi (nv_state_t *);
|
|
void NV_API_CALL nv_init_msix (nv_state_t *);
|
|
NvS32 NV_API_CALL nv_request_msix_irq (nv_linux_state_t *);
|
|
|
|
#define NV_PCI_MSIX_FLAGS 2
|
|
#define NV_PCI_MSIX_FLAGS_QSIZE 0x7FF
|
|
|
|
static inline void nv_free_msix_irq(nv_linux_state_t *nvl)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < nvl->num_intr; i++)
|
|
{
|
|
free_irq(nvl->msix_entries[i].vector, (void *)nvl);
|
|
}
|
|
}
|
|
|
|
static inline int nv_get_max_irq(struct pci_dev *pci_dev)
|
|
{
|
|
int nvec;
|
|
int cap_ptr;
|
|
NvU16 ctrl;
|
|
|
|
cap_ptr = pci_find_capability(pci_dev, PCI_CAP_ID_MSIX);
|
|
/*
|
|
* The 'PCI_MSIX_FLAGS' was added in 2.6.21-rc3 by:
|
|
* 2007-03-05 f5f2b13129a6541debf8851bae843cbbf48298b7
|
|
*/
|
|
#if defined(PCI_MSIX_FLAGS)
|
|
pci_read_config_word(pci_dev, cap_ptr + PCI_MSIX_FLAGS, &ctrl);
|
|
nvec = (ctrl & PCI_MSIX_FLAGS_QSIZE) + 1;
|
|
#else
|
|
pci_read_config_word(pci_dev, cap_ptr + NV_PCI_MSIX_FLAGS, &ctrl);
|
|
nvec = (ctrl & NV_PCI_MSIX_FLAGS_QSIZE) + 1;
|
|
#endif
|
|
|
|
return nvec;
|
|
}
|
|
|
|
static inline int nv_pci_enable_msix(nv_linux_state_t *nvl, int nvec)
|
|
{
|
|
int rc = 0;
|
|
|
|
/*
|
|
* pci_enable_msix_range() replaced pci_enable_msix() in 3.14-rc1:
|
|
* 2014-01-03 302a2523c277bea0bbe8340312b09507905849ed
|
|
*/
|
|
|
|
#if defined(NV_PCI_ENABLE_MSIX_RANGE_PRESENT)
|
|
// We require all the vectors we are requesting so use the same min and max
|
|
rc = pci_enable_msix_range(nvl->pci_dev, nvl->msix_entries, nvec, nvec);
|
|
if (rc < 0)
|
|
{
|
|
return NV_ERR_OPERATING_SYSTEM;
|
|
}
|
|
WARN_ON(nvec != rc);
|
|
#else
|
|
rc = pci_enable_msix(nvl->pci_dev, nvl->msix_entries, nvec);
|
|
if (rc != 0)
|
|
{
|
|
return NV_ERR_OPERATING_SYSTEM;
|
|
}
|
|
#endif
|
|
|
|
nvl->num_intr = nvec;
|
|
return NV_OK;
|
|
}
|
|
#endif
|
|
#endif /* _NV_MSI_H_ */
|