aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Lendacky <thomas.lendacky@amd.com>2015-02-03 14:07:29 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2015-02-27 04:48:49 -0500
commit6c5063434098b956252d8bb45d7546ff717717e6 (patch)
tree67a88ce65e0701cb2364293825684e232b918db9
parentbe03a3a0961eba0bc695fa91ac87efe5f4b8f40c (diff)
crypto: ccp - Add ACPI support
Add support for ACPI to the CCP platform driver. Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/Kconfig2
-rw-r--r--drivers/crypto/ccp/ccp-platform.c96
2 files changed, 93 insertions, 5 deletions
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index b840b79655bc..7e94413da6e3 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -391,7 +391,7 @@ config CRYPTO_DEV_ATMEL_SHA
391 391
392config CRYPTO_DEV_CCP 392config CRYPTO_DEV_CCP
393 bool "Support for AMD Cryptographic Coprocessor" 393 bool "Support for AMD Cryptographic Coprocessor"
394 depends on ((X86 && PCI) || ARM64) && HAS_IOMEM 394 depends on ((X86 && PCI) || (ARM64 && (OF_ADDRESS || ACPI))) && HAS_IOMEM
395 default n 395 default n
396 help 396 help
397 The AMD Cryptographic Coprocessor provides hardware support 397 The AMD Cryptographic Coprocessor provides hardware support
diff --git a/drivers/crypto/ccp/ccp-platform.c b/drivers/crypto/ccp/ccp-platform.c
index 20661f099198..b1c20b2b5647 100644
--- a/drivers/crypto/ccp/ccp-platform.c
+++ b/drivers/crypto/ccp/ccp-platform.c
@@ -23,9 +23,16 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/ccp.h> 24#include <linux/ccp.h>
25#include <linux/of.h> 25#include <linux/of.h>
26#include <linux/of_address.h>
27#include <linux/acpi.h>
26 28
27#include "ccp-dev.h" 29#include "ccp-dev.h"
28 30
31struct ccp_platform {
32 int use_acpi;
33 int coherent;
34};
35
29static int ccp_get_irq(struct ccp_device *ccp) 36static int ccp_get_irq(struct ccp_device *ccp)
30{ 37{
31 struct device *dev = ccp->dev; 38 struct device *dev = ccp->dev;
@@ -83,10 +90,64 @@ static struct resource *ccp_find_mmio_area(struct ccp_device *ccp)
83 return NULL; 90 return NULL;
84} 91}
85 92
93#ifdef CONFIG_ACPI
94static int ccp_acpi_support(struct ccp_device *ccp)
95{
96 struct ccp_platform *ccp_platform = ccp->dev_specific;
97 struct acpi_device *adev = ACPI_COMPANION(ccp->dev);
98 acpi_handle handle;
99 acpi_status status;
100 unsigned long long data;
101 int cca;
102
103 /* Retrieve the device cache coherency value */
104 handle = adev->handle;
105 do {
106 status = acpi_evaluate_integer(handle, "_CCA", NULL, &data);
107 if (!ACPI_FAILURE(status)) {
108 cca = data;
109 break;
110 }
111 } while (!ACPI_FAILURE(status));
112
113 if (ACPI_FAILURE(status)) {
114 dev_err(ccp->dev, "error obtaining acpi coherency value\n");
115 return -EINVAL;
116 }
117
118 ccp_platform->coherent = !!cca;
119
120 return 0;
121}
122#else /* CONFIG_ACPI */
123static int ccp_acpi_support(struct ccp_device *ccp)
124{
125 return -EINVAL;
126}
127#endif
128
129#ifdef CONFIG_OF
130static int ccp_of_support(struct ccp_device *ccp)
131{
132 struct ccp_platform *ccp_platform = ccp->dev_specific;
133
134 ccp_platform->coherent = of_dma_is_coherent(ccp->dev->of_node);
135
136 return 0;
137}
138#else
139static int ccp_of_support(struct ccp_device *ccp)
140{
141 return -EINVAL;
142}
143#endif
144
86static int ccp_platform_probe(struct platform_device *pdev) 145static int ccp_platform_probe(struct platform_device *pdev)
87{ 146{
88 struct ccp_device *ccp; 147 struct ccp_device *ccp;
148 struct ccp_platform *ccp_platform;
89 struct device *dev = &pdev->dev; 149 struct device *dev = &pdev->dev;
150 struct acpi_device *adev = ACPI_COMPANION(dev);
90 struct resource *ior; 151 struct resource *ior;
91 int ret; 152 int ret;
92 153
@@ -95,10 +156,16 @@ static int ccp_platform_probe(struct platform_device *pdev)
95 if (!ccp) 156 if (!ccp)
96 goto e_err; 157 goto e_err;
97 158
98 ccp->dev_specific = NULL; 159 ccp_platform = devm_kzalloc(dev, sizeof(*ccp_platform), GFP_KERNEL);
160 if (!ccp_platform)
161 goto e_err;
162
163 ccp->dev_specific = ccp_platform;
99 ccp->get_irq = ccp_get_irqs; 164 ccp->get_irq = ccp_get_irqs;
100 ccp->free_irq = ccp_free_irqs; 165 ccp->free_irq = ccp_free_irqs;
101 166
167 ccp_platform->use_acpi = (!adev || acpi_disabled) ? 0 : 1;
168
102 ior = ccp_find_mmio_area(ccp); 169 ior = ccp_find_mmio_area(ccp);
103 ccp->io_map = devm_ioremap_resource(dev, ior); 170 ccp->io_map = devm_ioremap_resource(dev, ior);
104 if (IS_ERR(ccp->io_map)) { 171 if (IS_ERR(ccp->io_map)) {
@@ -115,7 +182,14 @@ static int ccp_platform_probe(struct platform_device *pdev)
115 goto e_err; 182 goto e_err;
116 } 183 }
117 184
118 if (of_property_read_bool(dev->of_node, "dma-coherent")) 185 if (ccp_platform->use_acpi)
186 ret = ccp_acpi_support(ccp);
187 else
188 ret = ccp_of_support(ccp);
189 if (ret)
190 goto e_err;
191
192 if (ccp_platform->coherent)
119 ccp->axcache = CACHE_WB_NO_ALLOC; 193 ccp->axcache = CACHE_WB_NO_ALLOC;
120 else 194 else
121 ccp->axcache = CACHE_NONE; 195 ccp->axcache = CACHE_NONE;
@@ -197,15 +271,29 @@ static int ccp_platform_resume(struct platform_device *pdev)
197} 271}
198#endif 272#endif
199 273
200static const struct of_device_id ccp_platform_ids[] = { 274#ifdef CONFIG_ACPI
275static const struct acpi_device_id ccp_acpi_match[] = {
276 { "AMDI0C00", 0 },
277 { },
278};
279#endif
280
281#ifdef CONFIG_OF
282static const struct of_device_id ccp_of_match[] = {
201 { .compatible = "amd,ccp-seattle-v1a" }, 283 { .compatible = "amd,ccp-seattle-v1a" },
202 { }, 284 { },
203}; 285};
286#endif
204 287
205static struct platform_driver ccp_platform_driver = { 288static struct platform_driver ccp_platform_driver = {
206 .driver = { 289 .driver = {
207 .name = "AMD Cryptographic Coprocessor", 290 .name = "AMD Cryptographic Coprocessor",
208 .of_match_table = ccp_platform_ids, 291#ifdef CONFIG_ACPI
292 .acpi_match_table = ccp_acpi_match,
293#endif
294#ifdef CONFIG_OF
295 .of_match_table = ccp_of_match,
296#endif
209 }, 297 },
210 .probe = ccp_platform_probe, 298 .probe = ccp_platform_probe,
211 .remove = ccp_platform_remove, 299 .remove = ccp_platform_remove,