diff options
author | Tom Lendacky <thomas.lendacky@amd.com> | 2015-02-03 14:07:29 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2015-02-27 04:48:49 -0500 |
commit | 6c5063434098b956252d8bb45d7546ff717717e6 (patch) | |
tree | 67a88ce65e0701cb2364293825684e232b918db9 | |
parent | be03a3a0961eba0bc695fa91ac87efe5f4b8f40c (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/Kconfig | 2 | ||||
-rw-r--r-- | drivers/crypto/ccp/ccp-platform.c | 96 |
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 | ||
392 | config CRYPTO_DEV_CCP | 392 | config 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 | ||
31 | struct ccp_platform { | ||
32 | int use_acpi; | ||
33 | int coherent; | ||
34 | }; | ||
35 | |||
29 | static int ccp_get_irq(struct ccp_device *ccp) | 36 | static 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 | ||
94 | static 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 */ | ||
123 | static int ccp_acpi_support(struct ccp_device *ccp) | ||
124 | { | ||
125 | return -EINVAL; | ||
126 | } | ||
127 | #endif | ||
128 | |||
129 | #ifdef CONFIG_OF | ||
130 | static 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 | ||
139 | static int ccp_of_support(struct ccp_device *ccp) | ||
140 | { | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | #endif | ||
144 | |||
86 | static int ccp_platform_probe(struct platform_device *pdev) | 145 | static 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 | ||
200 | static const struct of_device_id ccp_platform_ids[] = { | 274 | #ifdef CONFIG_ACPI |
275 | static const struct acpi_device_id ccp_acpi_match[] = { | ||
276 | { "AMDI0C00", 0 }, | ||
277 | { }, | ||
278 | }; | ||
279 | #endif | ||
280 | |||
281 | #ifdef CONFIG_OF | ||
282 | static 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 | ||
205 | static struct platform_driver ccp_platform_driver = { | 288 | static 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, |