18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * AMD Secure Processor device driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2013,2019 Advanced Micro Devices, Inc. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Author: Tom Lendacky <thomas.lendacky@amd.com> 88c2ecf20Sopenharmony_ci * Author: Gary R Hook <gary.hook@amd.com> 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/module.h> 128c2ecf20Sopenharmony_ci#include <linux/kernel.h> 138c2ecf20Sopenharmony_ci#include <linux/device.h> 148c2ecf20Sopenharmony_ci#include <linux/pci.h> 158c2ecf20Sopenharmony_ci#include <linux/pci_ids.h> 168c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 178c2ecf20Sopenharmony_ci#include <linux/kthread.h> 188c2ecf20Sopenharmony_ci#include <linux/sched.h> 198c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 208c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 218c2ecf20Sopenharmony_ci#include <linux/delay.h> 228c2ecf20Sopenharmony_ci#include <linux/ccp.h> 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#include "ccp-dev.h" 258c2ecf20Sopenharmony_ci#include "psp-dev.h" 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define MSIX_VECTORS 2 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistruct sp_pci { 308c2ecf20Sopenharmony_ci int msix_count; 318c2ecf20Sopenharmony_ci struct msix_entry msix_entry[MSIX_VECTORS]; 328c2ecf20Sopenharmony_ci}; 338c2ecf20Sopenharmony_cistatic struct sp_device *sp_dev_master; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic int sp_get_msix_irqs(struct sp_device *sp) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci struct sp_pci *sp_pci = sp->dev_specific; 388c2ecf20Sopenharmony_ci struct device *dev = sp->dev; 398c2ecf20Sopenharmony_ci struct pci_dev *pdev = to_pci_dev(dev); 408c2ecf20Sopenharmony_ci int v, ret; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci for (v = 0; v < ARRAY_SIZE(sp_pci->msix_entry); v++) 438c2ecf20Sopenharmony_ci sp_pci->msix_entry[v].entry = v; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci ret = pci_enable_msix_range(pdev, sp_pci->msix_entry, 1, v); 468c2ecf20Sopenharmony_ci if (ret < 0) 478c2ecf20Sopenharmony_ci return ret; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci sp_pci->msix_count = ret; 508c2ecf20Sopenharmony_ci sp->use_tasklet = true; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci sp->psp_irq = sp_pci->msix_entry[0].vector; 538c2ecf20Sopenharmony_ci sp->ccp_irq = (sp_pci->msix_count > 1) ? sp_pci->msix_entry[1].vector 548c2ecf20Sopenharmony_ci : sp_pci->msix_entry[0].vector; 558c2ecf20Sopenharmony_ci return 0; 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cistatic int sp_get_msi_irq(struct sp_device *sp) 598c2ecf20Sopenharmony_ci{ 608c2ecf20Sopenharmony_ci struct device *dev = sp->dev; 618c2ecf20Sopenharmony_ci struct pci_dev *pdev = to_pci_dev(dev); 628c2ecf20Sopenharmony_ci int ret; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci ret = pci_enable_msi(pdev); 658c2ecf20Sopenharmony_ci if (ret) 668c2ecf20Sopenharmony_ci return ret; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci sp->ccp_irq = pdev->irq; 698c2ecf20Sopenharmony_ci sp->psp_irq = pdev->irq; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci return 0; 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistatic int sp_get_irqs(struct sp_device *sp) 758c2ecf20Sopenharmony_ci{ 768c2ecf20Sopenharmony_ci struct device *dev = sp->dev; 778c2ecf20Sopenharmony_ci int ret; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci ret = sp_get_msix_irqs(sp); 808c2ecf20Sopenharmony_ci if (!ret) 818c2ecf20Sopenharmony_ci return 0; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci /* Couldn't get MSI-X vectors, try MSI */ 848c2ecf20Sopenharmony_ci dev_notice(dev, "could not enable MSI-X (%d), trying MSI\n", ret); 858c2ecf20Sopenharmony_ci ret = sp_get_msi_irq(sp); 868c2ecf20Sopenharmony_ci if (!ret) 878c2ecf20Sopenharmony_ci return 0; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci /* Couldn't get MSI interrupt */ 908c2ecf20Sopenharmony_ci dev_notice(dev, "could not enable MSI (%d)\n", ret); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci return ret; 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cistatic void sp_free_irqs(struct sp_device *sp) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci struct sp_pci *sp_pci = sp->dev_specific; 988c2ecf20Sopenharmony_ci struct device *dev = sp->dev; 998c2ecf20Sopenharmony_ci struct pci_dev *pdev = to_pci_dev(dev); 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci if (sp_pci->msix_count) 1028c2ecf20Sopenharmony_ci pci_disable_msix(pdev); 1038c2ecf20Sopenharmony_ci else if (sp->psp_irq) 1048c2ecf20Sopenharmony_ci pci_disable_msi(pdev); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci sp->ccp_irq = 0; 1078c2ecf20Sopenharmony_ci sp->psp_irq = 0; 1088c2ecf20Sopenharmony_ci} 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistatic bool sp_pci_is_master(struct sp_device *sp) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci struct device *dev_cur, *dev_new; 1138c2ecf20Sopenharmony_ci struct pci_dev *pdev_cur, *pdev_new; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci dev_new = sp->dev; 1168c2ecf20Sopenharmony_ci dev_cur = sp_dev_master->dev; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci pdev_new = to_pci_dev(dev_new); 1198c2ecf20Sopenharmony_ci pdev_cur = to_pci_dev(dev_cur); 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci if (pdev_new->bus->number < pdev_cur->bus->number) 1228c2ecf20Sopenharmony_ci return true; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci if (PCI_SLOT(pdev_new->devfn) < PCI_SLOT(pdev_cur->devfn)) 1258c2ecf20Sopenharmony_ci return true; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci if (PCI_FUNC(pdev_new->devfn) < PCI_FUNC(pdev_cur->devfn)) 1288c2ecf20Sopenharmony_ci return true; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci return false; 1318c2ecf20Sopenharmony_ci} 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_cistatic void psp_set_master(struct sp_device *sp) 1348c2ecf20Sopenharmony_ci{ 1358c2ecf20Sopenharmony_ci if (!sp_dev_master) { 1368c2ecf20Sopenharmony_ci sp_dev_master = sp; 1378c2ecf20Sopenharmony_ci return; 1388c2ecf20Sopenharmony_ci } 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci if (sp_pci_is_master(sp)) 1418c2ecf20Sopenharmony_ci sp_dev_master = sp; 1428c2ecf20Sopenharmony_ci} 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_cistatic struct sp_device *psp_get_master(void) 1458c2ecf20Sopenharmony_ci{ 1468c2ecf20Sopenharmony_ci return sp_dev_master; 1478c2ecf20Sopenharmony_ci} 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_cistatic void psp_clear_master(struct sp_device *sp) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci if (sp == sp_dev_master) { 1528c2ecf20Sopenharmony_ci sp_dev_master = NULL; 1538c2ecf20Sopenharmony_ci dev_dbg(sp->dev, "Cleared sp_dev_master\n"); 1548c2ecf20Sopenharmony_ci } 1558c2ecf20Sopenharmony_ci} 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_cistatic int sp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1588c2ecf20Sopenharmony_ci{ 1598c2ecf20Sopenharmony_ci struct sp_device *sp; 1608c2ecf20Sopenharmony_ci struct sp_pci *sp_pci; 1618c2ecf20Sopenharmony_ci struct device *dev = &pdev->dev; 1628c2ecf20Sopenharmony_ci void __iomem * const *iomap_table; 1638c2ecf20Sopenharmony_ci int bar_mask; 1648c2ecf20Sopenharmony_ci int ret; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci ret = -ENOMEM; 1678c2ecf20Sopenharmony_ci sp = sp_alloc_struct(dev); 1688c2ecf20Sopenharmony_ci if (!sp) 1698c2ecf20Sopenharmony_ci goto e_err; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci sp_pci = devm_kzalloc(dev, sizeof(*sp_pci), GFP_KERNEL); 1728c2ecf20Sopenharmony_ci if (!sp_pci) 1738c2ecf20Sopenharmony_ci goto e_err; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci sp->dev_specific = sp_pci; 1768c2ecf20Sopenharmony_ci sp->dev_vdata = (struct sp_dev_vdata *)id->driver_data; 1778c2ecf20Sopenharmony_ci if (!sp->dev_vdata) { 1788c2ecf20Sopenharmony_ci ret = -ENODEV; 1798c2ecf20Sopenharmony_ci dev_err(dev, "missing driver data\n"); 1808c2ecf20Sopenharmony_ci goto e_err; 1818c2ecf20Sopenharmony_ci } 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci ret = pcim_enable_device(pdev); 1848c2ecf20Sopenharmony_ci if (ret) { 1858c2ecf20Sopenharmony_ci dev_err(dev, "pcim_enable_device failed (%d)\n", ret); 1868c2ecf20Sopenharmony_ci goto e_err; 1878c2ecf20Sopenharmony_ci } 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci bar_mask = pci_select_bars(pdev, IORESOURCE_MEM); 1908c2ecf20Sopenharmony_ci ret = pcim_iomap_regions(pdev, bar_mask, "ccp"); 1918c2ecf20Sopenharmony_ci if (ret) { 1928c2ecf20Sopenharmony_ci dev_err(dev, "pcim_iomap_regions failed (%d)\n", ret); 1938c2ecf20Sopenharmony_ci goto e_err; 1948c2ecf20Sopenharmony_ci } 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci iomap_table = pcim_iomap_table(pdev); 1978c2ecf20Sopenharmony_ci if (!iomap_table) { 1988c2ecf20Sopenharmony_ci dev_err(dev, "pcim_iomap_table failed\n"); 1998c2ecf20Sopenharmony_ci ret = -ENOMEM; 2008c2ecf20Sopenharmony_ci goto e_err; 2018c2ecf20Sopenharmony_ci } 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci sp->io_map = iomap_table[sp->dev_vdata->bar]; 2048c2ecf20Sopenharmony_ci if (!sp->io_map) { 2058c2ecf20Sopenharmony_ci dev_err(dev, "ioremap failed\n"); 2068c2ecf20Sopenharmony_ci ret = -ENOMEM; 2078c2ecf20Sopenharmony_ci goto e_err; 2088c2ecf20Sopenharmony_ci } 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci ret = sp_get_irqs(sp); 2118c2ecf20Sopenharmony_ci if (ret) 2128c2ecf20Sopenharmony_ci goto e_err; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci pci_set_master(pdev); 2158c2ecf20Sopenharmony_ci sp->set_psp_master_device = psp_set_master; 2168c2ecf20Sopenharmony_ci sp->get_psp_master_device = psp_get_master; 2178c2ecf20Sopenharmony_ci sp->clear_psp_master_device = psp_clear_master; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); 2208c2ecf20Sopenharmony_ci if (ret) { 2218c2ecf20Sopenharmony_ci ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 2228c2ecf20Sopenharmony_ci if (ret) { 2238c2ecf20Sopenharmony_ci dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", 2248c2ecf20Sopenharmony_ci ret); 2258c2ecf20Sopenharmony_ci goto free_irqs; 2268c2ecf20Sopenharmony_ci } 2278c2ecf20Sopenharmony_ci } 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci dev_set_drvdata(dev, sp); 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci ret = sp_init(sp); 2328c2ecf20Sopenharmony_ci if (ret) 2338c2ecf20Sopenharmony_ci goto free_irqs; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci return 0; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_cifree_irqs: 2388c2ecf20Sopenharmony_ci sp_free_irqs(sp); 2398c2ecf20Sopenharmony_cie_err: 2408c2ecf20Sopenharmony_ci dev_notice(dev, "initialization failed\n"); 2418c2ecf20Sopenharmony_ci return ret; 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_cistatic void sp_pci_shutdown(struct pci_dev *pdev) 2458c2ecf20Sopenharmony_ci{ 2468c2ecf20Sopenharmony_ci struct device *dev = &pdev->dev; 2478c2ecf20Sopenharmony_ci struct sp_device *sp = dev_get_drvdata(dev); 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci if (!sp) 2508c2ecf20Sopenharmony_ci return; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci sp_destroy(sp); 2538c2ecf20Sopenharmony_ci} 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_cistatic void sp_pci_remove(struct pci_dev *pdev) 2568c2ecf20Sopenharmony_ci{ 2578c2ecf20Sopenharmony_ci struct device *dev = &pdev->dev; 2588c2ecf20Sopenharmony_ci struct sp_device *sp = dev_get_drvdata(dev); 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci if (!sp) 2618c2ecf20Sopenharmony_ci return; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci sp_destroy(sp); 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci sp_free_irqs(sp); 2668c2ecf20Sopenharmony_ci} 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_cistatic int __maybe_unused sp_pci_suspend(struct device *dev) 2698c2ecf20Sopenharmony_ci{ 2708c2ecf20Sopenharmony_ci struct sp_device *sp = dev_get_drvdata(dev); 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci return sp_suspend(sp); 2738c2ecf20Sopenharmony_ci} 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_cistatic int __maybe_unused sp_pci_resume(struct device *dev) 2768c2ecf20Sopenharmony_ci{ 2778c2ecf20Sopenharmony_ci struct sp_device *sp = dev_get_drvdata(dev); 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci return sp_resume(sp); 2808c2ecf20Sopenharmony_ci} 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci#ifdef CONFIG_CRYPTO_DEV_SP_PSP 2838c2ecf20Sopenharmony_cistatic const struct sev_vdata sevv1 = { 2848c2ecf20Sopenharmony_ci .cmdresp_reg = 0x10580, 2858c2ecf20Sopenharmony_ci .cmdbuff_addr_lo_reg = 0x105e0, 2868c2ecf20Sopenharmony_ci .cmdbuff_addr_hi_reg = 0x105e4, 2878c2ecf20Sopenharmony_ci}; 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_cistatic const struct sev_vdata sevv2 = { 2908c2ecf20Sopenharmony_ci .cmdresp_reg = 0x10980, 2918c2ecf20Sopenharmony_ci .cmdbuff_addr_lo_reg = 0x109e0, 2928c2ecf20Sopenharmony_ci .cmdbuff_addr_hi_reg = 0x109e4, 2938c2ecf20Sopenharmony_ci}; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_cistatic const struct tee_vdata teev1 = { 2968c2ecf20Sopenharmony_ci .cmdresp_reg = 0x10544, 2978c2ecf20Sopenharmony_ci .cmdbuff_addr_lo_reg = 0x10548, 2988c2ecf20Sopenharmony_ci .cmdbuff_addr_hi_reg = 0x1054c, 2998c2ecf20Sopenharmony_ci .ring_wptr_reg = 0x10550, 3008c2ecf20Sopenharmony_ci .ring_rptr_reg = 0x10554, 3018c2ecf20Sopenharmony_ci}; 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_cistatic const struct psp_vdata pspv1 = { 3048c2ecf20Sopenharmony_ci .sev = &sevv1, 3058c2ecf20Sopenharmony_ci .feature_reg = 0x105fc, 3068c2ecf20Sopenharmony_ci .inten_reg = 0x10610, 3078c2ecf20Sopenharmony_ci .intsts_reg = 0x10614, 3088c2ecf20Sopenharmony_ci}; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_cistatic const struct psp_vdata pspv2 = { 3118c2ecf20Sopenharmony_ci .sev = &sevv2, 3128c2ecf20Sopenharmony_ci .feature_reg = 0x109fc, 3138c2ecf20Sopenharmony_ci .inten_reg = 0x10690, 3148c2ecf20Sopenharmony_ci .intsts_reg = 0x10694, 3158c2ecf20Sopenharmony_ci}; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic const struct psp_vdata pspv3 = { 3188c2ecf20Sopenharmony_ci .tee = &teev1, 3198c2ecf20Sopenharmony_ci .feature_reg = 0x109fc, 3208c2ecf20Sopenharmony_ci .inten_reg = 0x10690, 3218c2ecf20Sopenharmony_ci .intsts_reg = 0x10694, 3228c2ecf20Sopenharmony_ci}; 3238c2ecf20Sopenharmony_ci#endif 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_cistatic const struct sp_dev_vdata dev_vdata[] = { 3268c2ecf20Sopenharmony_ci { /* 0 */ 3278c2ecf20Sopenharmony_ci .bar = 2, 3288c2ecf20Sopenharmony_ci#ifdef CONFIG_CRYPTO_DEV_SP_CCP 3298c2ecf20Sopenharmony_ci .ccp_vdata = &ccpv3, 3308c2ecf20Sopenharmony_ci#endif 3318c2ecf20Sopenharmony_ci }, 3328c2ecf20Sopenharmony_ci { /* 1 */ 3338c2ecf20Sopenharmony_ci .bar = 2, 3348c2ecf20Sopenharmony_ci#ifdef CONFIG_CRYPTO_DEV_SP_CCP 3358c2ecf20Sopenharmony_ci .ccp_vdata = &ccpv5a, 3368c2ecf20Sopenharmony_ci#endif 3378c2ecf20Sopenharmony_ci#ifdef CONFIG_CRYPTO_DEV_SP_PSP 3388c2ecf20Sopenharmony_ci .psp_vdata = &pspv1, 3398c2ecf20Sopenharmony_ci#endif 3408c2ecf20Sopenharmony_ci }, 3418c2ecf20Sopenharmony_ci { /* 2 */ 3428c2ecf20Sopenharmony_ci .bar = 2, 3438c2ecf20Sopenharmony_ci#ifdef CONFIG_CRYPTO_DEV_SP_CCP 3448c2ecf20Sopenharmony_ci .ccp_vdata = &ccpv5b, 3458c2ecf20Sopenharmony_ci#endif 3468c2ecf20Sopenharmony_ci }, 3478c2ecf20Sopenharmony_ci { /* 3 */ 3488c2ecf20Sopenharmony_ci .bar = 2, 3498c2ecf20Sopenharmony_ci#ifdef CONFIG_CRYPTO_DEV_SP_CCP 3508c2ecf20Sopenharmony_ci .ccp_vdata = &ccpv5a, 3518c2ecf20Sopenharmony_ci#endif 3528c2ecf20Sopenharmony_ci#ifdef CONFIG_CRYPTO_DEV_SP_PSP 3538c2ecf20Sopenharmony_ci .psp_vdata = &pspv2, 3548c2ecf20Sopenharmony_ci#endif 3558c2ecf20Sopenharmony_ci }, 3568c2ecf20Sopenharmony_ci { /* 4 */ 3578c2ecf20Sopenharmony_ci .bar = 2, 3588c2ecf20Sopenharmony_ci#ifdef CONFIG_CRYPTO_DEV_SP_CCP 3598c2ecf20Sopenharmony_ci .ccp_vdata = &ccpv5a, 3608c2ecf20Sopenharmony_ci#endif 3618c2ecf20Sopenharmony_ci#ifdef CONFIG_CRYPTO_DEV_SP_PSP 3628c2ecf20Sopenharmony_ci .psp_vdata = &pspv3, 3638c2ecf20Sopenharmony_ci#endif 3648c2ecf20Sopenharmony_ci }, 3658c2ecf20Sopenharmony_ci}; 3668c2ecf20Sopenharmony_cistatic const struct pci_device_id sp_pci_table[] = { 3678c2ecf20Sopenharmony_ci { PCI_VDEVICE(AMD, 0x1537), (kernel_ulong_t)&dev_vdata[0] }, 3688c2ecf20Sopenharmony_ci { PCI_VDEVICE(AMD, 0x1456), (kernel_ulong_t)&dev_vdata[1] }, 3698c2ecf20Sopenharmony_ci { PCI_VDEVICE(AMD, 0x1468), (kernel_ulong_t)&dev_vdata[2] }, 3708c2ecf20Sopenharmony_ci { PCI_VDEVICE(AMD, 0x1486), (kernel_ulong_t)&dev_vdata[3] }, 3718c2ecf20Sopenharmony_ci { PCI_VDEVICE(AMD, 0x15DF), (kernel_ulong_t)&dev_vdata[4] }, 3728c2ecf20Sopenharmony_ci /* Last entry must be zero */ 3738c2ecf20Sopenharmony_ci { 0, } 3748c2ecf20Sopenharmony_ci}; 3758c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(pci, sp_pci_table); 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(sp_pci_pm_ops, sp_pci_suspend, sp_pci_resume); 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_cistatic struct pci_driver sp_pci_driver = { 3808c2ecf20Sopenharmony_ci .name = "ccp", 3818c2ecf20Sopenharmony_ci .id_table = sp_pci_table, 3828c2ecf20Sopenharmony_ci .probe = sp_pci_probe, 3838c2ecf20Sopenharmony_ci .remove = sp_pci_remove, 3848c2ecf20Sopenharmony_ci .shutdown = sp_pci_shutdown, 3858c2ecf20Sopenharmony_ci .driver.pm = &sp_pci_pm_ops, 3868c2ecf20Sopenharmony_ci}; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ciint sp_pci_init(void) 3898c2ecf20Sopenharmony_ci{ 3908c2ecf20Sopenharmony_ci return pci_register_driver(&sp_pci_driver); 3918c2ecf20Sopenharmony_ci} 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_civoid sp_pci_exit(void) 3948c2ecf20Sopenharmony_ci{ 3958c2ecf20Sopenharmony_ci pci_unregister_driver(&sp_pci_driver); 3968c2ecf20Sopenharmony_ci} 397