From c4f4b325e9c885b11901174158d5e1ff4b19a189 Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Thu, 5 Jun 2014 10:17:57 -0500 Subject: crypto: ccp - Add platform device support for arm64 Add support for the CCP on arm64 as a platform device. Signed-off-by: Tom Lendacky Signed-off-by: Herbert Xu --- drivers/crypto/ccp/ccp-dev.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'drivers/crypto/ccp/ccp-dev.c') diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c index 2c7816149b01..fa1ab10f960f 100644 --- a/drivers/crypto/ccp/ccp-dev.c +++ b/drivers/crypto/ccp/ccp-dev.c @@ -20,7 +20,9 @@ #include #include #include +#ifdef CONFIG_X86 #include +#endif #include #include "ccp-dev.h" @@ -360,6 +362,12 @@ int ccp_init(struct ccp_device *ccp) /* Build queue interrupt mask (two interrupts per queue) */ qim |= cmd_q->int_ok | cmd_q->int_err; +#ifdef CONFIG_ARM64 + /* For arm64 set the recommended queue cache settings */ + iowrite32(CACHE_WB_NO_ALLOC, ccp->io_regs + CMD_Q_CACHE_BASE + + (CMD_Q_CACHE_INC * i)); +#endif + dev_dbg(dev, "queue #%u available\n", i); } if (ccp->cmd_q_count == 0) { @@ -558,12 +566,15 @@ bool ccp_queues_suspended(struct ccp_device *ccp) } #endif +#ifdef CONFIG_X86 static const struct x86_cpu_id ccp_support[] = { { X86_VENDOR_AMD, 22, }, }; +#endif static int __init ccp_mod_init(void) { +#ifdef CONFIG_X86 struct cpuinfo_x86 *cpuinfo = &boot_cpu_data; int ret; @@ -589,12 +600,30 @@ static int __init ccp_mod_init(void) break; } +#endif + +#ifdef CONFIG_ARM64 + int ret; + + ret = ccp_platform_init(); + if (ret) + return ret; + + /* Don't leave the driver loaded if init failed */ + if (!ccp_get_device()) { + ccp_platform_exit(); + return -ENODEV; + } + + return 0; +#endif return -ENODEV; } static void __exit ccp_mod_exit(void) { +#ifdef CONFIG_X86 struct cpuinfo_x86 *cpuinfo = &boot_cpu_data; switch (cpuinfo->x86) { @@ -602,6 +631,11 @@ static void __exit ccp_mod_exit(void) ccp_pci_exit(); break; } +#endif + +#ifdef CONFIG_ARM64 + ccp_platform_exit(); +#endif } module_init(ccp_mod_init); -- cgit v1.2.3 From 126ae9adc1ec8d9006542f1a5e474b0183845e21 Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Thu, 10 Jul 2014 10:58:35 -0500 Subject: crypto: ccp - Base AXI DMA cache settings on device tree The default cache operations for ARM64 were changed during 3.15. To use coherent operations a "dma-coherent" device tree property is required. If that property is not present in the device tree node then the non-coherent operations are assigned for the device. Add support to the ccp driver to assign the AXI DMA cache settings based on whether the "dma-coherent" property is present in the device node. If present, use settings that work with the caches. If not present, use settings that do not look at the caches. Signed-off-by: Tom Lendacky Signed-off-by: Herbert Xu --- Documentation/devicetree/bindings/crypto/amd-ccp.txt | 3 +++ drivers/crypto/ccp/Kconfig | 1 + drivers/crypto/ccp/ccp-dev.c | 2 +- drivers/crypto/ccp/ccp-dev.h | 4 ++++ drivers/crypto/ccp/ccp-platform.c | 6 ++++++ 5 files changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers/crypto/ccp/ccp-dev.c') diff --git a/Documentation/devicetree/bindings/crypto/amd-ccp.txt b/Documentation/devicetree/bindings/crypto/amd-ccp.txt index 6e0b11aa8995..8c61183b41e0 100644 --- a/Documentation/devicetree/bindings/crypto/amd-ccp.txt +++ b/Documentation/devicetree/bindings/crypto/amd-ccp.txt @@ -7,6 +7,9 @@ Required properties: that services interrupts for this device - interrupts: Should contain the CCP interrupt +Optional properties: +- dma-coherent: Present if dma operations are coherent + Example: ccp@e0100000 { compatible = "amd,ccp-seattle-v1a"; diff --git a/drivers/crypto/ccp/Kconfig b/drivers/crypto/ccp/Kconfig index 7639ffc36c68..474382d50ec4 100644 --- a/drivers/crypto/ccp/Kconfig +++ b/drivers/crypto/ccp/Kconfig @@ -3,6 +3,7 @@ config CRYPTO_DEV_CCP_DD depends on CRYPTO_DEV_CCP default m select HW_RANDOM + select OF if ARM64 help Provides the interface to use the AMD Cryptographic Coprocessor which can be used to accelerate or offload encryption operations diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c index fa1ab10f960f..a7d110652a74 100644 --- a/drivers/crypto/ccp/ccp-dev.c +++ b/drivers/crypto/ccp/ccp-dev.c @@ -364,7 +364,7 @@ int ccp_init(struct ccp_device *ccp) #ifdef CONFIG_ARM64 /* For arm64 set the recommended queue cache settings */ - iowrite32(CACHE_WB_NO_ALLOC, ccp->io_regs + CMD_Q_CACHE_BASE + + iowrite32(ccp->axcache, ccp->io_regs + CMD_Q_CACHE_BASE + (CMD_Q_CACHE_INC * i)); #endif diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h index 1c5651b09506..62ff35a6b9ec 100644 --- a/drivers/crypto/ccp/ccp-dev.h +++ b/drivers/crypto/ccp/ccp-dev.h @@ -30,6 +30,7 @@ #define TRNG_RETRIES 10 +#define CACHE_NONE 0x00 #define CACHE_WB_NO_ALLOC 0xb7 @@ -255,6 +256,9 @@ struct ccp_device { /* Suspend support */ unsigned int suspending; wait_queue_head_t suspend_queue; + + /* DMA caching attribute support */ + unsigned int axcache; }; diff --git a/drivers/crypto/ccp/ccp-platform.c b/drivers/crypto/ccp/ccp-platform.c index 65e58291c668..b0a2806908f1 100644 --- a/drivers/crypto/ccp/ccp-platform.c +++ b/drivers/crypto/ccp/ccp-platform.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "ccp-dev.h" @@ -112,6 +113,11 @@ static int ccp_platform_probe(struct platform_device *pdev) *(dev->dma_mask) = DMA_BIT_MASK(48); dev->coherent_dma_mask = DMA_BIT_MASK(48); + if (of_property_read_bool(dev->of_node, "dma-coherent")) + ccp->axcache = CACHE_WB_NO_ALLOC; + else + ccp->axcache = CACHE_NONE; + dev_set_drvdata(dev, ccp); ret = ccp_init(ccp); -- cgit v1.2.3 From c9f21cb6388898bfe69886d001316dae7ecc9a4b Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Fri, 5 Sep 2014 10:31:09 -0500 Subject: crypto: ccp - Check for CCP before registering crypto algs If the ccp is built as a built-in module, then ccp-crypto (whether built as a module or a built-in module) will be able to load and it will register its crypto algorithms. If the system does not have a CCP this will result in -ENODEV being returned whenever a command is attempted to be queued by the registered crypto algorithms. Add an API, ccp_present(), that checks for the presence of a CCP on the system. The ccp-crypto module can use this to determine if it should register it's crypto alogorithms. Cc: stable@vger.kernel.org Reported-by: Scot Doyle Signed-off-by: Tom Lendacky Tested-by: Scot Doyle Signed-off-by: Herbert Xu --- drivers/crypto/ccp/ccp-crypto-main.c | 4 ++++ drivers/crypto/ccp/ccp-dev.c | 14 ++++++++++++++ include/linux/ccp.h | 12 ++++++++++++ 3 files changed, 30 insertions(+) (limited to 'drivers/crypto/ccp/ccp-dev.c') diff --git a/drivers/crypto/ccp/ccp-crypto-main.c b/drivers/crypto/ccp/ccp-crypto-main.c index 20dc848481e7..4d4e016d755b 100644 --- a/drivers/crypto/ccp/ccp-crypto-main.c +++ b/drivers/crypto/ccp/ccp-crypto-main.c @@ -367,6 +367,10 @@ static int ccp_crypto_init(void) { int ret; + ret = ccp_present(); + if (ret) + return ret; + spin_lock_init(&req_queue_lock); INIT_LIST_HEAD(&req_queue.cmds); req_queue.backlog = &req_queue.cmds; diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c index a7d110652a74..c6e6171eb6d3 100644 --- a/drivers/crypto/ccp/ccp-dev.c +++ b/drivers/crypto/ccp/ccp-dev.c @@ -54,6 +54,20 @@ static inline void ccp_del_device(struct ccp_device *ccp) ccp_dev = NULL; } +/** + * ccp_present - check if a CCP device is present + * + * Returns zero if a CCP device is present, -ENODEV otherwise. + */ +int ccp_present(void) +{ + if (ccp_get_device()) + return 0; + + return -ENODEV; +} +EXPORT_SYMBOL_GPL(ccp_present); + /** * ccp_enqueue_cmd - queue an operation for processing by the CCP * diff --git a/include/linux/ccp.h b/include/linux/ccp.h index ebcc9d146219..7f437036baa4 100644 --- a/include/linux/ccp.h +++ b/include/linux/ccp.h @@ -26,6 +26,13 @@ struct ccp_cmd; #if defined(CONFIG_CRYPTO_DEV_CCP_DD) || \ defined(CONFIG_CRYPTO_DEV_CCP_DD_MODULE) +/** + * ccp_present - check if a CCP device is present + * + * Returns zero if a CCP device is present, -ENODEV otherwise. + */ +int ccp_present(void); + /** * ccp_enqueue_cmd - queue an operation for processing by the CCP * @@ -53,6 +60,11 @@ int ccp_enqueue_cmd(struct ccp_cmd *cmd); #else /* CONFIG_CRYPTO_DEV_CCP_DD is not enabled */ +static inline int ccp_present(void) +{ + return -ENODEV; +} + static inline int ccp_enqueue_cmd(struct ccp_cmd *cmd) { return -ENODEV; -- cgit v1.2.3