diff options
author | Brijesh Singh <brijesh.singh@amd.com> | 2017-07-06 17:59:15 +0300 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2017-07-18 12:57:14 +0300 |
commit | f4d18d656f882a7ca558313d5f1b18b1fd01f759 (patch) | |
tree | 505605640669c9a727ce65e8553661538f6b5661 /drivers/crypto/ccp/ccp-pci.c | |
parent | 720419f01832f7e697cb80480b97b2a1e96045cd (diff) | |
download | linux-f4d18d656f882a7ca558313d5f1b18b1fd01f759.tar.xz |
crypto: ccp - Abstract interrupt registeration
The CCP and PSP devices part of AMD Secure Procesor may share the same
interrupt. Hence we expand the SP device to register a common interrupt
handler and provide functions to CCP and PSP devices to register their
interrupt callback which will be invoked upon interrupt.
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Acked-by: Gary R Hook <gary.hook@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/ccp/ccp-pci.c')
-rw-r--r-- | drivers/crypto/ccp/ccp-pci.c | 103 |
1 files changed, 31 insertions, 72 deletions
diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/ccp-pci.c index ab2df96c4b9d..b29a093fd127 100644 --- a/drivers/crypto/ccp/ccp-pci.c +++ b/drivers/crypto/ccp/ccp-pci.c @@ -28,67 +28,37 @@ #define MSIX_VECTORS 2 -struct ccp_msix { - u32 vector; - char name[16]; -}; - struct ccp_pci { int msix_count; - struct ccp_msix msix[MSIX_VECTORS]; + struct msix_entry msix_entry[MSIX_VECTORS]; }; -static int ccp_get_msix_irqs(struct ccp_device *ccp) +static int ccp_get_msix_irqs(struct sp_device *sp) { - struct sp_device *sp = ccp->sp; struct ccp_pci *ccp_pci = sp->dev_specific; - struct device *dev = ccp->dev; + struct device *dev = sp->dev; struct pci_dev *pdev = to_pci_dev(dev); - struct msix_entry msix_entry[MSIX_VECTORS]; - unsigned int name_len = sizeof(ccp_pci->msix[0].name) - 1; int v, ret; - for (v = 0; v < ARRAY_SIZE(msix_entry); v++) - msix_entry[v].entry = v; + for (v = 0; v < ARRAY_SIZE(ccp_pci->msix_entry); v++) + ccp_pci->msix_entry[v].entry = v; - ret = pci_enable_msix_range(pdev, msix_entry, 1, v); + ret = pci_enable_msix_range(pdev, ccp_pci->msix_entry, 1, v); if (ret < 0) return ret; ccp_pci->msix_count = ret; - for (v = 0; v < ccp_pci->msix_count; v++) { - /* Set the interrupt names and request the irqs */ - snprintf(ccp_pci->msix[v].name, name_len, "%s-%u", - sp->name, v); - ccp_pci->msix[v].vector = msix_entry[v].vector; - ret = request_irq(ccp_pci->msix[v].vector, - ccp->vdata->perform->irqhandler, - 0, ccp_pci->msix[v].name, ccp); - if (ret) { - dev_notice(dev, "unable to allocate MSI-X IRQ (%d)\n", - ret); - goto e_irq; - } - } - ccp->use_tasklet = true; + sp->use_tasklet = true; + sp->psp_irq = ccp_pci->msix_entry[0].vector; + sp->ccp_irq = (ccp_pci->msix_count > 1) ? ccp_pci->msix_entry[1].vector + : ccp_pci->msix_entry[0].vector; return 0; - -e_irq: - while (v--) - free_irq(ccp_pci->msix[v].vector, dev); - - pci_disable_msix(pdev); - - ccp_pci->msix_count = 0; - - return ret; } -static int ccp_get_msi_irq(struct ccp_device *ccp) +static int ccp_get_msi_irq(struct sp_device *sp) { - struct sp_device *sp = ccp->sp; - struct device *dev = ccp->dev; + struct device *dev = sp->dev; struct pci_dev *pdev = to_pci_dev(dev); int ret; @@ -96,35 +66,24 @@ static int ccp_get_msi_irq(struct ccp_device *ccp) if (ret) return ret; - ccp->irq = pdev->irq; - ret = request_irq(ccp->irq, ccp->vdata->perform->irqhandler, 0, - sp->name, ccp); - if (ret) { - dev_notice(dev, "unable to allocate MSI IRQ (%d)\n", ret); - goto e_msi; - } - ccp->use_tasklet = true; + sp->ccp_irq = pdev->irq; + sp->psp_irq = pdev->irq; return 0; - -e_msi: - pci_disable_msi(pdev); - - return ret; } -static int ccp_get_irqs(struct ccp_device *ccp) +static int ccp_get_irqs(struct sp_device *sp) { - struct device *dev = ccp->dev; + struct device *dev = sp->dev; int ret; - ret = ccp_get_msix_irqs(ccp); + ret = ccp_get_msix_irqs(sp); if (!ret) return 0; /* Couldn't get MSI-X vectors, try MSI */ dev_notice(dev, "could not enable MSI-X (%d), trying MSI\n", ret); - ret = ccp_get_msi_irq(ccp); + ret = ccp_get_msi_irq(sp); if (!ret) return 0; @@ -134,23 +93,19 @@ static int ccp_get_irqs(struct ccp_device *ccp) return ret; } -static void ccp_free_irqs(struct ccp_device *ccp) +static void ccp_free_irqs(struct sp_device *sp) { - struct sp_device *sp = ccp->sp; struct ccp_pci *ccp_pci = sp->dev_specific; - struct device *dev = ccp->dev; + struct device *dev = sp->dev; struct pci_dev *pdev = to_pci_dev(dev); - if (ccp_pci->msix_count) { - while (ccp_pci->msix_count--) - free_irq(ccp_pci->msix[ccp_pci->msix_count].vector, - ccp); + if (ccp_pci->msix_count) pci_disable_msix(pdev); - } else if (ccp->irq) { - free_irq(ccp->irq, ccp); + else if (sp->psp_irq) pci_disable_msi(pdev); - } - ccp->irq = 0; + + sp->ccp_irq = 0; + sp->psp_irq = 0; } static int ccp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) @@ -178,8 +133,6 @@ static int ccp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev_err(dev, "missing driver data\n"); goto e_err; } - sp->get_irq = ccp_get_irqs; - sp->free_irq = ccp_free_irqs; ret = pcim_enable_device(pdev); if (ret) { @@ -208,6 +161,10 @@ static int ccp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto e_err; } + ret = ccp_get_irqs(sp); + if (ret) + goto e_err; + pci_set_master(pdev); ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); @@ -245,6 +202,8 @@ static void ccp_pci_remove(struct pci_dev *pdev) sp_destroy(sp); + ccp_free_irqs(sp); + dev_notice(dev, "disabled\n"); } |