0001
0002
0003
0004
0005
0006 #include "iosm_ipc_pcie.h"
0007 #include "iosm_ipc_protocol.h"
0008
0009 static void ipc_write_dbell_reg(struct iosm_pcie *ipc_pcie, int irq_n, u32 data)
0010 {
0011 void __iomem *write_reg;
0012
0013
0014
0015
0016 write_reg = (void __iomem *)((u8 __iomem *)ipc_pcie->ipc_regs +
0017 ipc_pcie->doorbell_write +
0018 (irq_n * ipc_pcie->doorbell_reg_offset));
0019
0020
0021
0022
0023 iowrite32(data, write_reg);
0024 }
0025
0026 void ipc_doorbell_fire(struct iosm_pcie *ipc_pcie, int irq_n, u32 data)
0027 {
0028 ipc_write_dbell_reg(ipc_pcie, irq_n, data);
0029 }
0030
0031
0032 static irqreturn_t ipc_msi_interrupt(int irq, void *dev_id)
0033 {
0034 struct iosm_pcie *ipc_pcie = dev_id;
0035 int instance = irq - ipc_pcie->pci->irq;
0036
0037
0038
0039
0040 if (instance >= ipc_pcie->nvec)
0041 return IRQ_NONE;
0042
0043 if (!test_bit(0, &ipc_pcie->suspend))
0044 ipc_imem_irq_process(ipc_pcie->imem, instance);
0045
0046 return IRQ_HANDLED;
0047 }
0048
0049 void ipc_release_irq(struct iosm_pcie *ipc_pcie)
0050 {
0051 struct pci_dev *pdev = ipc_pcie->pci;
0052
0053 if (pdev->msi_enabled) {
0054 while (--ipc_pcie->nvec >= 0)
0055 free_irq(pdev->irq + ipc_pcie->nvec, ipc_pcie);
0056 }
0057 pci_free_irq_vectors(pdev);
0058 }
0059
0060 int ipc_acquire_irq(struct iosm_pcie *ipc_pcie)
0061 {
0062 struct pci_dev *pdev = ipc_pcie->pci;
0063 int i, rc = -EINVAL;
0064
0065 ipc_pcie->nvec = pci_alloc_irq_vectors(pdev, IPC_MSI_VECTORS,
0066 IPC_MSI_VECTORS, PCI_IRQ_MSI);
0067
0068 if (ipc_pcie->nvec < 0) {
0069 rc = ipc_pcie->nvec;
0070 goto error;
0071 }
0072
0073 if (!pdev->msi_enabled)
0074 goto error;
0075
0076 for (i = 0; i < ipc_pcie->nvec; ++i) {
0077 rc = request_threaded_irq(pdev->irq + i, NULL,
0078 ipc_msi_interrupt, IRQF_ONESHOT,
0079 KBUILD_MODNAME, ipc_pcie);
0080 if (rc) {
0081 dev_err(ipc_pcie->dev, "unable to grab IRQ, rc=%d", rc);
0082 ipc_pcie->nvec = i;
0083 ipc_release_irq(ipc_pcie);
0084 goto error;
0085 }
0086 }
0087
0088 error:
0089 return rc;
0090 }