]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
crypto: ccp - rename ccp driver initialize files as sp device
authorBrijesh Singh <brijesh.singh@amd.com>
Thu, 6 Jul 2017 14:59:16 +0000 (09:59 -0500)
committerHerbert Xu <herbert@gondor.apana.org.au>
Tue, 18 Jul 2017 10:15:54 +0000 (18:15 +0800)
CCP device initializes is now integerated into higher level SP device,
to avoid the confusion lets rename the ccp driver initialization files
(ccp-platform.c->sp-platform.c, ccp-pci.c->sp-pci.c). The patch does not
make any functional changes other than renaming file and structures

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>
drivers/crypto/ccp/Makefile
drivers/crypto/ccp/ccp-dev.h
drivers/crypto/ccp/ccp-pci.c [deleted file]
drivers/crypto/ccp/ccp-platform.c [deleted file]
drivers/crypto/ccp/sp-dev.c
drivers/crypto/ccp/sp-pci.c [new file with mode: 0644]
drivers/crypto/ccp/sp-platform.c [new file with mode: 0644]

index d2f1b5264362addd0e9bef93bfba67aebc640991..5f2adc5facfe8488d67d289de41c162a610b8208 100644 (file)
@@ -1,12 +1,12 @@
 obj-$(CONFIG_CRYPTO_DEV_CCP_DD) += ccp.o
-ccp-objs  := sp-dev.o ccp-platform.o
+ccp-objs  := sp-dev.o sp-platform.o
 ccp-$(CONFIG_CRYPTO_DEV_SP_CCP) += ccp-dev.o \
            ccp-ops.o \
            ccp-dev-v3.o \
            ccp-dev-v5.o \
            ccp-dmaengine.o \
            ccp-debugfs.o
-ccp-$(CONFIG_PCI) += ccp-pci.o
+ccp-$(CONFIG_PCI) += sp-pci.o
 
 obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o
 ccp-crypto-objs := ccp-crypto-main.o \
index 193f30973694451e2546dc74edfbf6739656885f..b959e2402aa2cc9c6da28b2106c51551f4803cf6 100644 (file)
@@ -626,12 +626,6 @@ struct ccp5_desc {
        struct dword7 dw7;
 };
 
-int ccp_pci_init(void);
-void ccp_pci_exit(void);
-
-int ccp_platform_init(void);
-void ccp_platform_exit(void);
-
 void ccp_add_device(struct ccp_device *ccp);
 void ccp_del_device(struct ccp_device *ccp);
 
diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/ccp-pci.c
deleted file mode 100644 (file)
index b29a093..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * AMD Cryptographic Coprocessor (CCP) driver
- *
- * Copyright (C) 2013,2016 Advanced Micro Devices, Inc.
- *
- * Author: Tom Lendacky <thomas.lendacky@amd.com>
- * Author: Gary R Hook <gary.hook@amd.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/dma-mapping.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/ccp.h>
-
-#include "ccp-dev.h"
-
-#define MSIX_VECTORS                   2
-
-struct ccp_pci {
-       int msix_count;
-       struct msix_entry msix_entry[MSIX_VECTORS];
-};
-
-static int ccp_get_msix_irqs(struct sp_device *sp)
-{
-       struct ccp_pci *ccp_pci = sp->dev_specific;
-       struct device *dev = sp->dev;
-       struct pci_dev *pdev = to_pci_dev(dev);
-       int v, ret;
-
-       for (v = 0; v < ARRAY_SIZE(ccp_pci->msix_entry); v++)
-               ccp_pci->msix_entry[v].entry = v;
-
-       ret = pci_enable_msix_range(pdev, ccp_pci->msix_entry, 1, v);
-       if (ret < 0)
-               return ret;
-
-       ccp_pci->msix_count = ret;
-       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;
-}
-
-static int ccp_get_msi_irq(struct sp_device *sp)
-{
-       struct device *dev = sp->dev;
-       struct pci_dev *pdev = to_pci_dev(dev);
-       int ret;
-
-       ret = pci_enable_msi(pdev);
-       if (ret)
-               return ret;
-
-       sp->ccp_irq = pdev->irq;
-       sp->psp_irq = pdev->irq;
-
-       return 0;
-}
-
-static int ccp_get_irqs(struct sp_device *sp)
-{
-       struct device *dev = sp->dev;
-       int ret;
-
-       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(sp);
-       if (!ret)
-               return 0;
-
-       /* Couldn't get MSI interrupt */
-       dev_notice(dev, "could not enable MSI (%d)\n", ret);
-
-       return ret;
-}
-
-static void ccp_free_irqs(struct sp_device *sp)
-{
-       struct ccp_pci *ccp_pci = sp->dev_specific;
-       struct device *dev = sp->dev;
-       struct pci_dev *pdev = to_pci_dev(dev);
-
-       if (ccp_pci->msix_count)
-               pci_disable_msix(pdev);
-       else if (sp->psp_irq)
-               pci_disable_msi(pdev);
-
-       sp->ccp_irq = 0;
-       sp->psp_irq = 0;
-}
-
-static int ccp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-       struct sp_device *sp;
-       struct ccp_pci *ccp_pci;
-       struct device *dev = &pdev->dev;
-       void __iomem * const *iomap_table;
-       int bar_mask;
-       int ret;
-
-       ret = -ENOMEM;
-       sp = sp_alloc_struct(dev);
-       if (!sp)
-               goto e_err;
-
-       ccp_pci = devm_kzalloc(dev, sizeof(*ccp_pci), GFP_KERNEL);
-       if (!ccp_pci)
-               goto e_err;
-
-       sp->dev_specific = ccp_pci;
-       sp->dev_vdata = (struct sp_dev_vdata *)id->driver_data;
-       if (!sp->dev_vdata) {
-               ret = -ENODEV;
-               dev_err(dev, "missing driver data\n");
-               goto e_err;
-       }
-
-       ret = pcim_enable_device(pdev);
-       if (ret) {
-               dev_err(dev, "pcim_enable_device failed (%d)\n", ret);
-               goto e_err;
-       }
-
-       bar_mask = pci_select_bars(pdev, IORESOURCE_MEM);
-       ret = pcim_iomap_regions(pdev, bar_mask, "ccp");
-       if (ret) {
-               dev_err(dev, "pcim_iomap_regions failed (%d)\n", ret);
-               goto e_err;
-       }
-
-       iomap_table = pcim_iomap_table(pdev);
-       if (!iomap_table) {
-               dev_err(dev, "pcim_iomap_table failed\n");
-               ret = -ENOMEM;
-               goto e_err;
-       }
-
-       sp->io_map = iomap_table[sp->dev_vdata->bar];
-       if (!sp->io_map) {
-               dev_err(dev, "ioremap failed\n");
-               ret = -ENOMEM;
-               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));
-       if (ret) {
-               ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
-               if (ret) {
-                       dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n",
-                               ret);
-                       goto e_err;
-               }
-       }
-
-       dev_set_drvdata(dev, sp);
-
-       ret = sp_init(sp);
-       if (ret)
-               goto e_err;
-
-       dev_notice(dev, "enabled\n");
-
-       return 0;
-
-e_err:
-       dev_notice(dev, "initialization failed\n");
-       return ret;
-}
-
-static void ccp_pci_remove(struct pci_dev *pdev)
-{
-       struct device *dev = &pdev->dev;
-       struct sp_device *sp = dev_get_drvdata(dev);
-
-       if (!sp)
-               return;
-
-       sp_destroy(sp);
-
-       ccp_free_irqs(sp);
-
-       dev_notice(dev, "disabled\n");
-}
-
-#ifdef CONFIG_PM
-static int ccp_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct device *dev = &pdev->dev;
-       struct sp_device *sp = dev_get_drvdata(dev);
-
-       return sp_suspend(sp, state);
-}
-
-static int ccp_pci_resume(struct pci_dev *pdev)
-{
-       struct device *dev = &pdev->dev;
-       struct sp_device *sp = dev_get_drvdata(dev);
-
-       return sp_resume(sp);
-}
-#endif
-
-static const struct sp_dev_vdata dev_vdata[] = {
-       {
-               .bar = 2,
-#ifdef CONFIG_CRYPTO_DEV_SP_CCP
-               .ccp_vdata = &ccpv3,
-#endif
-       },
-       {
-               .bar = 2,
-#ifdef CONFIG_CRYPTO_DEV_SP_CCP
-               .ccp_vdata = &ccpv5a,
-#endif
-       },
-       {
-               .bar = 2,
-#ifdef CONFIG_CRYPTO_DEV_SP_CCP
-               .ccp_vdata = &ccpv5b,
-#endif
-       },
-};
-static const struct pci_device_id ccp_pci_table[] = {
-       { PCI_VDEVICE(AMD, 0x1537), (kernel_ulong_t)&dev_vdata[0] },
-       { PCI_VDEVICE(AMD, 0x1456), (kernel_ulong_t)&dev_vdata[1] },
-       { PCI_VDEVICE(AMD, 0x1468), (kernel_ulong_t)&dev_vdata[2] },
-       /* Last entry must be zero */
-       { 0, }
-};
-MODULE_DEVICE_TABLE(pci, ccp_pci_table);
-
-static struct pci_driver ccp_pci_driver = {
-       .name = "ccp",
-       .id_table = ccp_pci_table,
-       .probe = ccp_pci_probe,
-       .remove = ccp_pci_remove,
-#ifdef CONFIG_PM
-       .suspend = ccp_pci_suspend,
-       .resume = ccp_pci_resume,
-#endif
-};
-
-int ccp_pci_init(void)
-{
-       return pci_register_driver(&ccp_pci_driver);
-}
-
-void ccp_pci_exit(void)
-{
-       pci_unregister_driver(&ccp_pci_driver);
-}
diff --git a/drivers/crypto/ccp/ccp-platform.c b/drivers/crypto/ccp/ccp-platform.c
deleted file mode 100644 (file)
index 04a1cc4..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * AMD Cryptographic Coprocessor (CCP) driver
- *
- * Copyright (C) 2014,2016 Advanced Micro Devices, Inc.
- *
- * Author: Tom Lendacky <thomas.lendacky@amd.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/ioport.h>
-#include <linux/dma-mapping.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/ccp.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/acpi.h>
-
-#include "ccp-dev.h"
-
-struct ccp_platform {
-       int coherent;
-       unsigned int irq_count;
-};
-
-static const struct acpi_device_id ccp_acpi_match[];
-static const struct of_device_id ccp_of_match[];
-
-static struct sp_dev_vdata *ccp_get_of_version(struct platform_device *pdev)
-{
-#ifdef CONFIG_OF
-       const struct of_device_id *match;
-
-       match = of_match_node(ccp_of_match, pdev->dev.of_node);
-       if (match && match->data)
-               return (struct sp_dev_vdata *)match->data;
-#endif
-       return NULL;
-}
-
-static struct sp_dev_vdata *ccp_get_acpi_version(struct platform_device *pdev)
-{
-#ifdef CONFIG_ACPI
-       const struct acpi_device_id *match;
-
-       match = acpi_match_device(ccp_acpi_match, &pdev->dev);
-       if (match && match->driver_data)
-               return (struct sp_dev_vdata *)match->driver_data;
-#endif
-       return NULL;
-}
-
-static int ccp_get_irqs(struct sp_device *sp)
-{
-       struct ccp_platform *ccp_platform = sp->dev_specific;
-       struct device *dev = sp->dev;
-       struct platform_device *pdev = to_platform_device(dev);
-       unsigned int i, count;
-       int ret;
-
-       for (i = 0, count = 0; i < pdev->num_resources; i++) {
-               struct resource *res = &pdev->resource[i];
-
-               if (resource_type(res) == IORESOURCE_IRQ)
-                       count++;
-       }
-
-       ccp_platform->irq_count = count;
-
-       ret = platform_get_irq(pdev, 0);
-       if (ret < 0) {
-               dev_notice(dev, "unable to get IRQ (%d)\n", ret);
-               return ret;
-       }
-
-       sp->psp_irq = ret;
-       if (count == 1) {
-               sp->ccp_irq = ret;
-       } else {
-               ret = platform_get_irq(pdev, 1);
-               if (ret < 0) {
-                       dev_notice(dev, "unable to get IRQ (%d)\n", ret);
-                       return ret;
-               }
-
-               sp->ccp_irq = ret;
-       }
-
-       return 0;
-}
-
-static int ccp_platform_probe(struct platform_device *pdev)
-{
-       struct sp_device *sp;
-       struct ccp_platform *ccp_platform;
-       struct device *dev = &pdev->dev;
-       enum dev_dma_attr attr;
-       struct resource *ior;
-       int ret;
-
-       ret = -ENOMEM;
-       sp = sp_alloc_struct(dev);
-       if (!sp)
-               goto e_err;
-
-       ccp_platform = devm_kzalloc(dev, sizeof(*ccp_platform), GFP_KERNEL);
-       if (!ccp_platform)
-               goto e_err;
-
-       sp->dev_specific = ccp_platform;
-       sp->dev_vdata = pdev->dev.of_node ? ccp_get_of_version(pdev)
-                                        : ccp_get_acpi_version(pdev);
-       if (!sp->dev_vdata) {
-               ret = -ENODEV;
-               dev_err(dev, "missing driver data\n");
-               goto e_err;
-       }
-
-       ior = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       sp->io_map = devm_ioremap_resource(dev, ior);
-       if (IS_ERR(sp->io_map)) {
-               ret = PTR_ERR(sp->io_map);
-               goto e_err;
-       }
-
-       attr = device_get_dma_attr(dev);
-       if (attr == DEV_DMA_NOT_SUPPORTED) {
-               dev_err(dev, "DMA is not supported");
-               goto e_err;
-       }
-
-       ccp_platform->coherent = (attr == DEV_DMA_COHERENT);
-       if (ccp_platform->coherent)
-               sp->axcache = CACHE_WB_NO_ALLOC;
-       else
-               sp->axcache = CACHE_NONE;
-
-       ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
-       if (ret) {
-               dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret);
-               goto e_err;
-       }
-
-       ret = ccp_get_irqs(sp);
-       if (ret)
-               goto e_err;
-
-       dev_set_drvdata(dev, sp);
-
-       ret = sp_init(sp);
-       if (ret)
-               goto e_err;
-
-       dev_notice(dev, "enabled\n");
-
-       return 0;
-
-e_err:
-       dev_notice(dev, "initialization failed\n");
-       return ret;
-}
-
-static int ccp_platform_remove(struct platform_device *pdev)
-{
-       struct device *dev = &pdev->dev;
-       struct sp_device *sp = dev_get_drvdata(dev);
-
-       sp_destroy(sp);
-
-       dev_notice(dev, "disabled\n");
-
-       return 0;
-}
-
-#ifdef CONFIG_PM
-static int ccp_platform_suspend(struct platform_device *pdev,
-                               pm_message_t state)
-{
-       struct device *dev = &pdev->dev;
-       struct sp_device *sp = dev_get_drvdata(dev);
-
-       return sp_suspend(sp, state);
-}
-
-static int ccp_platform_resume(struct platform_device *pdev)
-{
-       struct device *dev = &pdev->dev;
-       struct sp_device *sp = dev_get_drvdata(dev);
-
-       return sp_resume(sp);
-}
-#endif
-
-static const struct sp_dev_vdata dev_vdata[] = {
-       {
-               .bar = 0,
-#ifdef CONFIG_CRYPTO_DEV_SP_CCP
-               .ccp_vdata = &ccpv3_platform,
-#endif
-       },
-};
-
-#ifdef CONFIG_ACPI
-static const struct acpi_device_id ccp_acpi_match[] = {
-       { "AMDI0C00", (kernel_ulong_t)&dev_vdata[0] },
-       { },
-};
-MODULE_DEVICE_TABLE(acpi, ccp_acpi_match);
-#endif
-
-#ifdef CONFIG_OF
-static const struct of_device_id ccp_of_match[] = {
-       { .compatible = "amd,ccp-seattle-v1a",
-         .data = (const void *)&dev_vdata[0] },
-       { },
-};
-MODULE_DEVICE_TABLE(of, ccp_of_match);
-#endif
-
-static struct platform_driver ccp_platform_driver = {
-       .driver = {
-               .name = "ccp",
-#ifdef CONFIG_ACPI
-               .acpi_match_table = ccp_acpi_match,
-#endif
-#ifdef CONFIG_OF
-               .of_match_table = ccp_of_match,
-#endif
-       },
-       .probe = ccp_platform_probe,
-       .remove = ccp_platform_remove,
-#ifdef CONFIG_PM
-       .suspend = ccp_platform_suspend,
-       .resume = ccp_platform_resume,
-#endif
-};
-
-int ccp_platform_init(void)
-{
-       return platform_driver_register(&ccp_platform_driver);
-}
-
-void ccp_platform_exit(void)
-{
-       platform_driver_unregister(&ccp_platform_driver);
-}
index 7e30773443e93c54b01ce9235c09ab423470b61c..1e5ffad4437bdf34317dbe40a7d164e7e765f8d6 100644 (file)
@@ -242,13 +242,13 @@ static int __init sp_mod_init(void)
 #ifdef CONFIG_X86
        int ret;
 
-       ret = ccp_pci_init();
+       ret = sp_pci_init();
        if (ret)
                return ret;
 
        /* Don't leave the driver loaded if init failed */
        if (ccp_present() != 0) {
-               ccp_pci_exit();
+               sp_pci_exit();
                return -ENODEV;
        }
 
@@ -258,13 +258,13 @@ static int __init sp_mod_init(void)
 #ifdef CONFIG_ARM64
        int ret;
 
-       ret = ccp_platform_init();
+       ret = sp_platform_init();
        if (ret)
                return ret;
 
        /* Don't leave the driver loaded if init failed */
        if (ccp_present() != 0) {
-               ccp_platform_exit();
+               sp_platform_exit();
                return -ENODEV;
        }
 
@@ -277,11 +277,11 @@ static int __init sp_mod_init(void)
 static void __exit sp_mod_exit(void)
 {
 #ifdef CONFIG_X86
-       ccp_pci_exit();
+       sp_pci_exit();
 #endif
 
 #ifdef CONFIG_ARM64
-       ccp_platform_exit();
+       sp_platform_exit();
 #endif
 }
 
diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c
new file mode 100644 (file)
index 0000000..9859aa6
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * AMD Secure Processor device driver
+ *
+ * Copyright (C) 2013,2016 Advanced Micro Devices, Inc.
+ *
+ * Author: Tom Lendacky <thomas.lendacky@amd.com>
+ * Author: Gary R Hook <gary.hook@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/ccp.h>
+
+#include "ccp-dev.h"
+
+#define MSIX_VECTORS                   2
+
+struct sp_pci {
+       int msix_count;
+       struct msix_entry msix_entry[MSIX_VECTORS];
+};
+
+static int sp_get_msix_irqs(struct sp_device *sp)
+{
+       struct sp_pci *sp_pci = sp->dev_specific;
+       struct device *dev = sp->dev;
+       struct pci_dev *pdev = to_pci_dev(dev);
+       int v, ret;
+
+       for (v = 0; v < ARRAY_SIZE(sp_pci->msix_entry); v++)
+               sp_pci->msix_entry[v].entry = v;
+
+       ret = pci_enable_msix_range(pdev, sp_pci->msix_entry, 1, v);
+       if (ret < 0)
+               return ret;
+
+       sp_pci->msix_count = ret;
+       sp->use_tasklet = true;
+
+       sp->psp_irq = sp_pci->msix_entry[0].vector;
+       sp->ccp_irq = (sp_pci->msix_count > 1) ? sp_pci->msix_entry[1].vector
+                                              : sp_pci->msix_entry[0].vector;
+       return 0;
+}
+
+static int sp_get_msi_irq(struct sp_device *sp)
+{
+       struct device *dev = sp->dev;
+       struct pci_dev *pdev = to_pci_dev(dev);
+       int ret;
+
+       ret = pci_enable_msi(pdev);
+       if (ret)
+               return ret;
+
+       sp->ccp_irq = pdev->irq;
+       sp->psp_irq = pdev->irq;
+
+       return 0;
+}
+
+static int sp_get_irqs(struct sp_device *sp)
+{
+       struct device *dev = sp->dev;
+       int ret;
+
+       ret = sp_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 = sp_get_msi_irq(sp);
+       if (!ret)
+               return 0;
+
+       /* Couldn't get MSI interrupt */
+       dev_notice(dev, "could not enable MSI (%d)\n", ret);
+
+       return ret;
+}
+
+static void sp_free_irqs(struct sp_device *sp)
+{
+       struct sp_pci *sp_pci = sp->dev_specific;
+       struct device *dev = sp->dev;
+       struct pci_dev *pdev = to_pci_dev(dev);
+
+       if (sp_pci->msix_count)
+               pci_disable_msix(pdev);
+       else if (sp->psp_irq)
+               pci_disable_msi(pdev);
+
+       sp->ccp_irq = 0;
+       sp->psp_irq = 0;
+}
+
+static int sp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+       struct sp_device *sp;
+       struct sp_pci *sp_pci;
+       struct device *dev = &pdev->dev;
+       void __iomem * const *iomap_table;
+       int bar_mask;
+       int ret;
+
+       ret = -ENOMEM;
+       sp = sp_alloc_struct(dev);
+       if (!sp)
+               goto e_err;
+
+       sp_pci = devm_kzalloc(dev, sizeof(*sp_pci), GFP_KERNEL);
+       if (!sp_pci)
+               goto e_err;
+
+       sp->dev_specific = sp_pci;
+       sp->dev_vdata = (struct sp_dev_vdata *)id->driver_data;
+       if (!sp->dev_vdata) {
+               ret = -ENODEV;
+               dev_err(dev, "missing driver data\n");
+               goto e_err;
+       }
+
+       ret = pcim_enable_device(pdev);
+       if (ret) {
+               dev_err(dev, "pcim_enable_device failed (%d)\n", ret);
+               goto e_err;
+       }
+
+       bar_mask = pci_select_bars(pdev, IORESOURCE_MEM);
+       ret = pcim_iomap_regions(pdev, bar_mask, "ccp");
+       if (ret) {
+               dev_err(dev, "pcim_iomap_regions failed (%d)\n", ret);
+               goto e_err;
+       }
+
+       iomap_table = pcim_iomap_table(pdev);
+       if (!iomap_table) {
+               dev_err(dev, "pcim_iomap_table failed\n");
+               ret = -ENOMEM;
+               goto e_err;
+       }
+
+       sp->io_map = iomap_table[sp->dev_vdata->bar];
+       if (!sp->io_map) {
+               dev_err(dev, "ioremap failed\n");
+               ret = -ENOMEM;
+               goto e_err;
+       }
+
+       ret = sp_get_irqs(sp);
+       if (ret)
+               goto e_err;
+
+       pci_set_master(pdev);
+
+       ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
+       if (ret) {
+               ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+               if (ret) {
+                       dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n",
+                               ret);
+                       goto e_err;
+               }
+       }
+
+       dev_set_drvdata(dev, sp);
+
+       ret = sp_init(sp);
+       if (ret)
+               goto e_err;
+
+       dev_notice(dev, "enabled\n");
+
+       return 0;
+
+e_err:
+       dev_notice(dev, "initialization failed\n");
+       return ret;
+}
+
+static void sp_pci_remove(struct pci_dev *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct sp_device *sp = dev_get_drvdata(dev);
+
+       if (!sp)
+               return;
+
+       sp_destroy(sp);
+
+       sp_free_irqs(sp);
+
+       dev_notice(dev, "disabled\n");
+}
+
+#ifdef CONFIG_PM
+static int sp_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct device *dev = &pdev->dev;
+       struct sp_device *sp = dev_get_drvdata(dev);
+
+       return sp_suspend(sp, state);
+}
+
+static int sp_pci_resume(struct pci_dev *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct sp_device *sp = dev_get_drvdata(dev);
+
+       return sp_resume(sp);
+}
+#endif
+
+static const struct sp_dev_vdata dev_vdata[] = {
+       {
+               .bar = 2,
+#ifdef CONFIG_CRYPTO_DEV_SP_CCP
+               .ccp_vdata = &ccpv3,
+#endif
+       },
+       {
+               .bar = 2,
+#ifdef CONFIG_CRYPTO_DEV_SP_CCP
+               .ccp_vdata = &ccpv5a,
+#endif
+       },
+       {
+               .bar = 2,
+#ifdef CONFIG_CRYPTO_DEV_SP_CCP
+               .ccp_vdata = &ccpv5b,
+#endif
+       },
+};
+static const struct pci_device_id sp_pci_table[] = {
+       { PCI_VDEVICE(AMD, 0x1537), (kernel_ulong_t)&dev_vdata[0] },
+       { PCI_VDEVICE(AMD, 0x1456), (kernel_ulong_t)&dev_vdata[1] },
+       { PCI_VDEVICE(AMD, 0x1468), (kernel_ulong_t)&dev_vdata[2] },
+       /* Last entry must be zero */
+       { 0, }
+};
+MODULE_DEVICE_TABLE(pci, sp_pci_table);
+
+static struct pci_driver sp_pci_driver = {
+       .name = "ccp",
+       .id_table = sp_pci_table,
+       .probe = sp_pci_probe,
+       .remove = sp_pci_remove,
+#ifdef CONFIG_PM
+       .suspend = sp_pci_suspend,
+       .resume = sp_pci_resume,
+#endif
+};
+
+int sp_pci_init(void)
+{
+       return pci_register_driver(&sp_pci_driver);
+}
+
+void sp_pci_exit(void)
+{
+       pci_unregister_driver(&sp_pci_driver);
+}
diff --git a/drivers/crypto/ccp/sp-platform.c b/drivers/crypto/ccp/sp-platform.c
new file mode 100644 (file)
index 0000000..71734f2
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * AMD Secure Processor device driver
+ *
+ * Copyright (C) 2014,2016 Advanced Micro Devices, Inc.
+ *
+ * Author: Tom Lendacky <thomas.lendacky@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/ccp.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/acpi.h>
+
+#include "ccp-dev.h"
+
+struct sp_platform {
+       int coherent;
+       unsigned int irq_count;
+};
+
+static const struct acpi_device_id sp_acpi_match[];
+static const struct of_device_id sp_of_match[];
+
+static struct sp_dev_vdata *sp_get_of_version(struct platform_device *pdev)
+{
+#ifdef CONFIG_OF
+       const struct of_device_id *match;
+
+       match = of_match_node(sp_of_match, pdev->dev.of_node);
+       if (match && match->data)
+               return (struct sp_dev_vdata *)match->data;
+#endif
+       return NULL;
+}
+
+static struct sp_dev_vdata *sp_get_acpi_version(struct platform_device *pdev)
+{
+#ifdef CONFIG_ACPI
+       const struct acpi_device_id *match;
+
+       match = acpi_match_device(sp_acpi_match, &pdev->dev);
+       if (match && match->driver_data)
+               return (struct sp_dev_vdata *)match->driver_data;
+#endif
+       return NULL;
+}
+
+static int sp_get_irqs(struct sp_device *sp)
+{
+       struct sp_platform *sp_platform = sp->dev_specific;
+       struct device *dev = sp->dev;
+       struct platform_device *pdev = to_platform_device(dev);
+       unsigned int i, count;
+       int ret;
+
+       for (i = 0, count = 0; i < pdev->num_resources; i++) {
+               struct resource *res = &pdev->resource[i];
+
+               if (resource_type(res) == IORESOURCE_IRQ)
+                       count++;
+       }
+
+       sp_platform->irq_count = count;
+
+       ret = platform_get_irq(pdev, 0);
+       if (ret < 0) {
+               dev_notice(dev, "unable to get IRQ (%d)\n", ret);
+               return ret;
+       }
+
+       sp->psp_irq = ret;
+       if (count == 1) {
+               sp->ccp_irq = ret;
+       } else {
+               ret = platform_get_irq(pdev, 1);
+               if (ret < 0) {
+                       dev_notice(dev, "unable to get IRQ (%d)\n", ret);
+                       return ret;
+               }
+
+               sp->ccp_irq = ret;
+       }
+
+       return 0;
+}
+
+static int sp_platform_probe(struct platform_device *pdev)
+{
+       struct sp_device *sp;
+       struct sp_platform *sp_platform;
+       struct device *dev = &pdev->dev;
+       enum dev_dma_attr attr;
+       struct resource *ior;
+       int ret;
+
+       ret = -ENOMEM;
+       sp = sp_alloc_struct(dev);
+       if (!sp)
+               goto e_err;
+
+       sp_platform = devm_kzalloc(dev, sizeof(*sp_platform), GFP_KERNEL);
+       if (!sp_platform)
+               goto e_err;
+
+       sp->dev_specific = sp_platform;
+       sp->dev_vdata = pdev->dev.of_node ? sp_get_of_version(pdev)
+                                        : sp_get_acpi_version(pdev);
+       if (!sp->dev_vdata) {
+               ret = -ENODEV;
+               dev_err(dev, "missing driver data\n");
+               goto e_err;
+       }
+
+       ior = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       sp->io_map = devm_ioremap_resource(dev, ior);
+       if (IS_ERR(sp->io_map)) {
+               ret = PTR_ERR(sp->io_map);
+               goto e_err;
+       }
+
+       attr = device_get_dma_attr(dev);
+       if (attr == DEV_DMA_NOT_SUPPORTED) {
+               dev_err(dev, "DMA is not supported");
+               goto e_err;
+       }
+
+       sp_platform->coherent = (attr == DEV_DMA_COHERENT);
+       if (sp_platform->coherent)
+               sp->axcache = CACHE_WB_NO_ALLOC;
+       else
+               sp->axcache = CACHE_NONE;
+
+       ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
+       if (ret) {
+               dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret);
+               goto e_err;
+       }
+
+       ret = sp_get_irqs(sp);
+       if (ret)
+               goto e_err;
+
+       dev_set_drvdata(dev, sp);
+
+       ret = sp_init(sp);
+       if (ret)
+               goto e_err;
+
+       dev_notice(dev, "enabled\n");
+
+       return 0;
+
+e_err:
+       dev_notice(dev, "initialization failed\n");
+       return ret;
+}
+
+static int sp_platform_remove(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct sp_device *sp = dev_get_drvdata(dev);
+
+       sp_destroy(sp);
+
+       dev_notice(dev, "disabled\n");
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int sp_platform_suspend(struct platform_device *pdev,
+                               pm_message_t state)
+{
+       struct device *dev = &pdev->dev;
+       struct sp_device *sp = dev_get_drvdata(dev);
+
+       return sp_suspend(sp, state);
+}
+
+static int sp_platform_resume(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct sp_device *sp = dev_get_drvdata(dev);
+
+       return sp_resume(sp);
+}
+#endif
+
+static const struct sp_dev_vdata dev_vdata[] = {
+       {
+               .bar = 0,
+#ifdef CONFIG_CRYPTO_DEV_SP_CCP
+               .ccp_vdata = &ccpv3_platform,
+#endif
+       },
+};
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id sp_acpi_match[] = {
+       { "AMDI0C00", (kernel_ulong_t)&dev_vdata[0] },
+       { },
+};
+MODULE_DEVICE_TABLE(acpi, sp_acpi_match);
+#endif
+
+#ifdef CONFIG_OF
+static const struct of_device_id sp_of_match[] = {
+       { .compatible = "amd,ccp-seattle-v1a",
+         .data = (const void *)&dev_vdata[0] },
+       { },
+};
+MODULE_DEVICE_TABLE(of, sp_of_match);
+#endif
+
+static struct platform_driver sp_platform_driver = {
+       .driver = {
+               .name = "ccp",
+#ifdef CONFIG_ACPI
+               .acpi_match_table = sp_acpi_match,
+#endif
+#ifdef CONFIG_OF
+               .of_match_table = sp_of_match,
+#endif
+       },
+       .probe = sp_platform_probe,
+       .remove = sp_platform_remove,
+#ifdef CONFIG_PM
+       .suspend = sp_platform_suspend,
+       .resume = sp_platform_resume,
+#endif
+};
+
+int sp_platform_init(void)
+{
+       return platform_driver_register(&sp_platform_driver);
+}
+
+void sp_platform_exit(void)
+{
+       platform_driver_unregister(&sp_platform_driver);
+}