Skip to content

Commit 7f41ce0

Browse files
mchetankumardavem330
authored andcommitted
net: iosm: irq handling
1) Request interrupt vector, frees allocated resource. 2) Registers IRQ handler. Signed-off-by: M Chetan Kumar <m.chetan.kumar@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 7e98d78 commit 7f41ce0

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

drivers/net/wwan/iosm/iosm_ipc_irq.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Copyright (C) 2020-21 Intel Corporation.
4+
*/
5+
6+
#include "iosm_ipc_pcie.h"
7+
#include "iosm_ipc_protocol.h"
8+
9+
static void ipc_write_dbell_reg(struct iosm_pcie *ipc_pcie, int irq_n, u32 data)
10+
{
11+
void __iomem *write_reg;
12+
13+
/* Select the first doorbell register, which is only currently needed
14+
* by CP.
15+
*/
16+
write_reg = (void __iomem *)((u8 __iomem *)ipc_pcie->ipc_regs +
17+
ipc_pcie->doorbell_write +
18+
(irq_n * ipc_pcie->doorbell_reg_offset));
19+
20+
/* Fire the doorbell irq by writing data on the doorbell write pointer
21+
* register.
22+
*/
23+
iowrite32(data, write_reg);
24+
}
25+
26+
void ipc_doorbell_fire(struct iosm_pcie *ipc_pcie, int irq_n, u32 data)
27+
{
28+
ipc_write_dbell_reg(ipc_pcie, irq_n, data);
29+
}
30+
31+
/* Threaded Interrupt handler for MSI interrupts */
32+
static irqreturn_t ipc_msi_interrupt(int irq, void *dev_id)
33+
{
34+
struct iosm_pcie *ipc_pcie = dev_id;
35+
int instance = irq - ipc_pcie->pci->irq;
36+
37+
/* Shift the MSI irq actions to the IPC tasklet. IRQ_NONE means the
38+
* irq was not from the IPC device or could not be served.
39+
*/
40+
if (instance >= ipc_pcie->nvec)
41+
return IRQ_NONE;
42+
43+
if (!test_bit(0, &ipc_pcie->suspend))
44+
ipc_imem_irq_process(ipc_pcie->imem, instance);
45+
46+
return IRQ_HANDLED;
47+
}
48+
49+
void ipc_release_irq(struct iosm_pcie *ipc_pcie)
50+
{
51+
struct pci_dev *pdev = ipc_pcie->pci;
52+
53+
if (pdev->msi_enabled) {
54+
while (--ipc_pcie->nvec >= 0)
55+
free_irq(pdev->irq + ipc_pcie->nvec, ipc_pcie);
56+
}
57+
pci_free_irq_vectors(pdev);
58+
}
59+
60+
int ipc_acquire_irq(struct iosm_pcie *ipc_pcie)
61+
{
62+
struct pci_dev *pdev = ipc_pcie->pci;
63+
int i, rc = -EINVAL;
64+
65+
ipc_pcie->nvec = pci_alloc_irq_vectors(pdev, IPC_MSI_VECTORS,
66+
IPC_MSI_VECTORS, PCI_IRQ_MSI);
67+
68+
if (ipc_pcie->nvec < 0) {
69+
rc = ipc_pcie->nvec;
70+
goto error;
71+
}
72+
73+
if (!pdev->msi_enabled)
74+
goto error;
75+
76+
for (i = 0; i < ipc_pcie->nvec; ++i) {
77+
rc = request_threaded_irq(pdev->irq + i, NULL,
78+
ipc_msi_interrupt, IRQF_ONESHOT,
79+
KBUILD_MODNAME, ipc_pcie);
80+
if (rc) {
81+
dev_err(ipc_pcie->dev, "unable to grab IRQ, rc=%d", rc);
82+
ipc_pcie->nvec = i;
83+
ipc_release_irq(ipc_pcie);
84+
goto error;
85+
}
86+
}
87+
88+
error:
89+
return rc;
90+
}

drivers/net/wwan/iosm/iosm_ipc_irq.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only
2+
*
3+
* Copyright (C) 2020-21 Intel Corporation.
4+
*/
5+
6+
#ifndef IOSM_IPC_IRQ_H
7+
#define IOSM_IPC_IRQ_H
8+
9+
struct iosm_pcie;
10+
11+
/**
12+
* ipc_doorbell_fire - fire doorbell to CP
13+
* @ipc_pcie: Pointer to iosm_pcie
14+
* @irq_n: Doorbell type
15+
* @data: ipc state
16+
*/
17+
void ipc_doorbell_fire(struct iosm_pcie *ipc_pcie, int irq_n, u32 data);
18+
19+
/**
20+
* ipc_release_irq - Release the IRQ handler.
21+
* @ipc_pcie: Pointer to iosm_pcie struct
22+
*/
23+
void ipc_release_irq(struct iosm_pcie *ipc_pcie);
24+
25+
/**
26+
* ipc_acquire_irq - acquire IRQ & register IRQ handler.
27+
* @ipc_pcie: Pointer to iosm_pcie struct
28+
*
29+
* Return: 0 on success and failure value on error
30+
*/
31+
int ipc_acquire_irq(struct iosm_pcie *ipc_pcie);
32+
33+
#endif

0 commit comments

Comments
 (0)