misc: rockchip: pcie-rkep: Change to use pci_request_irq apis.

Fix error:
[  517.934944] RIP: 0010:pci_free_cap_save_buffers+0x19/0x30
...
[  517.935040]  ? page_fault_oops+0x136/0x2c0
[  517.935048]  ? search_bpf_extables+0x63/0x80
[  517.935055]  ? pci_free_cap_save_buffers+0x19/0x30
[  517.935061]  ? search_exception_tables+0x5f/0x70
[  517.935068]  ? kernelmode_fixup_or_oops+0xa2/0x120
[  517.935074]  ? __bad_area_nosemaphore+0x15d/0x1a0
[  517.935080]  ? __wake_up_common+0x7e/0x140

Change-Id: Ib0d769dc2ee7428fd289cfbda6a31d28ccb970bd
Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
This commit is contained in:
Jon Lin
2023-12-11 15:47:20 +08:00
committed by Tao Huang
parent 47bfce4123
commit a01ba48fea
+41 -102
View File
@@ -40,8 +40,7 @@
static DEFINE_MUTEX(rkep_mutex);
#define BAR_0_SZ SZ_4M
#define RKEP_NUM_MSI_VECTORS 4
#define RKEP_NUM_MSIX_VECTORS 8
#define RKEP_NUM_IRQ_VECTORS 4
#define PCIe_CLIENT_MSI_IRQ_OBJ 0 /* rockchip ep object special irq */
@@ -101,10 +100,9 @@ static DEFINE_MUTEX(rkep_mutex);
#define PCIE_RK3588_RC_DBI_BASE 0xf5000000
#define PCIE_DBI_SIZE 0x400000
struct pcie_rkep_msix_context {
struct pcie_rkep_irq_context {
struct pci_dev *dev;
u16 msg_id;
u8 *name;
};
struct pcie_rkep {
@@ -113,11 +111,8 @@ struct pcie_rkep {
void __iomem *bar2;
void __iomem *bar4;
int cur_mmap_res;
struct msix_entry msix_entries[RKEP_NUM_MSIX_VECTORS];
struct pcie_rkep_msix_context msix_ctx[RKEP_NUM_MSIX_VECTORS];
struct pcie_rkep_msix_context msi_ctx[RKEP_NUM_MSI_VECTORS];
bool msi_enable;
bool msix_enable;
struct pcie_rkep_irq_context irq_ctx[RKEP_NUM_IRQ_VECTORS];
int irq_valid;
struct miscdevice dev;
struct dma_trx_obj *dma_obj;
@@ -972,104 +967,69 @@ static int pcie_rkep_obj_handler(struct pcie_rkep *pcie_rkep, struct pci_dev *pd
static irqreturn_t pcie_rkep_pcie_interrupt(int irq, void *context)
{
struct pcie_rkep_msix_context *ctx = context;
struct pcie_rkep_irq_context *ctx = context;
struct pci_dev *pdev = ctx->dev;
struct pcie_rkep *pcie_rkep = pci_get_drvdata(pdev);
if (!pcie_rkep)
return IRQ_HANDLED;
if (pcie_rkep->msix_enable)
dev_info(&pdev->dev, "MSI-X is triggered for 0x%x\n", ctx->msg_id);
else /* pcie_rkep->msi_enable */ {
/*
* The msi 0 is the dedicated interrupt for obj to issue remote rc device.
*/
if (irq == pci_irq_vector(pcie_rkep->pdev, PCIe_CLIENT_MSI_IRQ_OBJ))
pcie_rkep_obj_handler(pcie_rkep, pdev);
}
/*
* The irq 0 is the dedicated interrupt for obj to issue remote rc device.
*/
if (irq == pci_irq_vector(pcie_rkep->pdev, PCIe_CLIENT_MSI_IRQ_OBJ))
pcie_rkep_obj_handler(pcie_rkep, pdev);
return IRQ_HANDLED;
}
static int __maybe_unused pcie_rkep_request_msi_irq(struct pcie_rkep *pcie_rkep)
static void pcie_rkep_release_irq(struct pcie_rkep *pcie_rkep)
{
int nvec, ret = -EINVAL, i, j;
int i;
if (pcie_rkep->irq_valid) {
for (i = 0; i < pcie_rkep->irq_valid; i++)
pci_free_irq(pcie_rkep->pdev, i, &pcie_rkep->irq_ctx[i]);
pci_free_irq_vectors(pcie_rkep->pdev);
}
pcie_rkep->irq_valid = 0;
}
static int pcie_rkep_request_irq(struct pcie_rkep *pcie_rkep, u32 irq_type)
{
int nvec, ret = -EINVAL, i;
/* Using msi as default */
nvec = pci_alloc_irq_vectors(pcie_rkep->pdev, 1, RKEP_NUM_MSI_VECTORS, PCI_IRQ_MSI);
nvec = pci_alloc_irq_vectors(pcie_rkep->pdev, 1, RKEP_NUM_IRQ_VECTORS, irq_type);
if (nvec < 0)
return nvec;
if (nvec != RKEP_NUM_MSI_VECTORS)
dev_err(&pcie_rkep->pdev->dev, "only allocate %d msi interrupt\n", nvec);
if (nvec != RKEP_NUM_IRQ_VECTORS)
dev_err(&pcie_rkep->pdev->dev, "only allocate %d irq interrupt, irq_type=%d\n", nvec, irq_type);
pcie_rkep->irq_valid = 0;
for (i = 0; i < nvec; i++) {
pcie_rkep->msi_ctx[i].dev = pcie_rkep->pdev;
pcie_rkep->msi_ctx[i].msg_id = i;
pcie_rkep->msi_ctx[i].name =
devm_kzalloc(&pcie_rkep->pdev->dev, RKEP_NUM_MSIX_VECTORS, GFP_KERNEL);
sprintf(pcie_rkep->msi_ctx[i].name, "%s-%d\n", pcie_rkep->dev.name, i);
ret = request_irq(pci_irq_vector(pcie_rkep->pdev, i),
pcie_rkep_pcie_interrupt, IRQF_SHARED,
pcie_rkep->msi_ctx[i].name, &pcie_rkep->msi_ctx[i]);
pcie_rkep->irq_ctx[i].dev = pcie_rkep->pdev;
pcie_rkep->irq_ctx[i].msg_id = i;
ret = pci_request_irq(pcie_rkep->pdev, i,
pcie_rkep_pcie_interrupt, NULL,
&pcie_rkep->irq_ctx[i], "%s-%d", pcie_rkep->dev.name, i);
if (ret)
break;
pcie_rkep->irq_valid++;
}
if (ret) {
for (j = 0; j < i; j++)
free_irq(pci_irq_vector(pcie_rkep->pdev, j), &pcie_rkep->msi_ctx[j]);
pci_disable_msi(pcie_rkep->pdev);
pcie_rkep_release_irq(pcie_rkep);
dev_err(&pcie_rkep->pdev->dev, "fail to allocate msi interrupt\n");
} else {
pcie_rkep->msi_enable = true;
dev_err(&pcie_rkep->pdev->dev, "success to request msi irq\n");
}
return ret;
}
static int __maybe_unused pcie_rkep_request_msix_irq(struct pcie_rkep *pcie_rkep)
{
int ret, i, j;
for (i = 0; i < RKEP_NUM_MSIX_VECTORS; i++)
pcie_rkep->msix_entries[i].entry = i;
ret = pci_enable_msix_exact(pcie_rkep->pdev, pcie_rkep->msix_entries,
RKEP_NUM_MSIX_VECTORS);
if (ret)
return ret;
for (i = 0; i < RKEP_NUM_MSIX_VECTORS; i++) {
pcie_rkep->msix_ctx[i].dev = pcie_rkep->pdev;
pcie_rkep->msix_ctx[i].msg_id = i;
pcie_rkep->msix_ctx[i].name =
devm_kzalloc(&pcie_rkep->pdev->dev, RKEP_NUM_MSIX_VECTORS, GFP_KERNEL);
sprintf(pcie_rkep->msix_ctx[i].name, "%s-%d\n", pcie_rkep->dev.name, i);
ret = request_irq(pcie_rkep->msix_entries[i].vector,
pcie_rkep_pcie_interrupt, 0, pcie_rkep->msix_ctx[i].name,
&pcie_rkep->msix_ctx[i]);
if (ret)
break;
}
if (ret) {
for (j = 0; j < i; j++)
free_irq(pcie_rkep->msix_entries[j].vector, &pcie_rkep->msix_ctx[j]);
pci_disable_msix(pcie_rkep->pdev);
dev_err(&pcie_rkep->pdev->dev, "fail to allocate msi-x interrupt\n");
} else {
pcie_rkep->msix_enable = true;
dev_err(&pcie_rkep->pdev->dev, "success to request msi-x irq\n");
}
return ret;
}
static int rkep_loadfile(struct device *dev, char *path, void __iomem *bar, int pos)
{
struct file *p_file = NULL;
@@ -1120,7 +1080,7 @@ static DEVICE_ATTR_WO(rkep);
static int pcie_rkep_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
int ret, i;
int ret;
struct pcie_rkep *pcie_rkep;
u8 *name;
u16 val;
@@ -1192,7 +1152,7 @@ static int pcie_rkep_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_drvdata(pdev, pcie_rkep);
ret = pcie_rkep_request_msi_irq(pcie_rkep);
ret = pcie_rkep_request_irq(pcie_rkep, PCI_IRQ_MSI);
if (ret)
goto err_register_irq;
@@ -1244,18 +1204,7 @@ static int pcie_rkep_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
err_register_obj:
if (pcie_rkep->msix_enable) {
for (i = 0; i < RKEP_NUM_MSIX_VECTORS; i++)
free_irq(pcie_rkep->msix_entries[i].vector, &pcie_rkep->msix_ctx[i]);
pci_disable_msix(pdev);
} else if (pcie_rkep->msi_enable) {
for (i = 0; i < RKEP_NUM_MSI_VECTORS; i++) {
if (pcie_rkep->msi_ctx[i].dev)
free_irq(pci_irq_vector(pdev, i), &pcie_rkep->msi_ctx[i]);
}
pci_disable_msi(pcie_rkep->pdev);
}
pcie_rkep_release_irq(pcie_rkep);
err_register_irq:
misc_deregister(&pcie_rkep->dev);
err_pci_iomap:
@@ -1276,7 +1225,6 @@ err_pci_enable_dev:
static void pcie_rkep_remove(struct pci_dev *pdev)
{
struct pcie_rkep *pcie_rkep = pci_get_drvdata(pdev);
int i;
if (pcie_rkep->dma_obj)
pcie_dw_dmatest_unregister(pcie_rkep->dma_obj);
@@ -1285,6 +1233,8 @@ static void pcie_rkep_remove(struct pci_dev *pdev)
#if IS_ENABLED(CONFIG_PCIE_FUNC_RKEP_USERPAGES)
free_contig_range(page_to_pfn(pcie_rkep->user_pages), RKEP_USER_MEM_SIZE >> PAGE_SHIFT);
#endif
pcie_rkep_release_irq(pcie_rkep);
if (pcie_rkep->bar0)
pci_iounmap(pdev, pcie_rkep->bar0);
if (pcie_rkep->bar2)
@@ -1294,17 +1244,6 @@ static void pcie_rkep_remove(struct pci_dev *pdev)
pci_release_regions(pdev);
pci_disable_device(pdev);
misc_deregister(&pcie_rkep->dev);
if (pcie_rkep->msix_enable) {
for (i = 0; i < RKEP_NUM_MSIX_VECTORS; i++)
free_irq(pcie_rkep->msix_entries[i].vector, &pcie_rkep->msix_ctx[i]);
pci_disable_msix(pdev);
} else if (pcie_rkep->msi_enable) {
for (i = 0; i < RKEP_NUM_MSI_VECTORS; i++)
if (pcie_rkep->msi_ctx[i].dev)
free_irq(pci_irq_vector(pdev, i), &pcie_rkep->msi_ctx[i]);
pci_disable_msi(pcie_rkep->pdev);
}
}
static const struct pci_device_id pcie_rkep_pcidev_id[] = {