fbdev: Use of_property_read_bool() for boolean properties
[linux-2.6-block.git] / drivers / crypto / aspeed / aspeed-hace.c
CommitLineData
108713a7
NL
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2021 Aspeed Technology Inc.
4 */
5
6#include <linux/clk.h>
7#include <linux/module.h>
8#include <linux/of_address.h>
9#include <linux/of_device.h>
10#include <linux/of_irq.h>
11#include <linux/of.h>
12#include <linux/platform_device.h>
13
14#include "aspeed-hace.h"
15
16#ifdef CONFIG_CRYPTO_DEV_ASPEED_DEBUG
17#define HACE_DBG(d, fmt, ...) \
18 dev_info((d)->dev, "%s() " fmt, __func__, ##__VA_ARGS__)
19#else
20#define HACE_DBG(d, fmt, ...) \
21 dev_dbg((d)->dev, "%s() " fmt, __func__, ##__VA_ARGS__)
22#endif
23
24/* HACE interrupt service routine */
25static irqreturn_t aspeed_hace_irq(int irq, void *dev)
26{
27 struct aspeed_hace_dev *hace_dev = (struct aspeed_hace_dev *)dev;
62f58b16 28 struct aspeed_engine_crypto *crypto_engine = &hace_dev->crypto_engine;
108713a7
NL
29 struct aspeed_engine_hash *hash_engine = &hace_dev->hash_engine;
30 u32 sts;
31
32 sts = ast_hace_read(hace_dev, ASPEED_HACE_STS);
33 ast_hace_write(hace_dev, sts, ASPEED_HACE_STS);
34
35 HACE_DBG(hace_dev, "irq status: 0x%x\n", sts);
36
37 if (sts & HACE_HASH_ISR) {
38 if (hash_engine->flags & CRYPTO_FLAGS_BUSY)
39 tasklet_schedule(&hash_engine->done_task);
40 else
41 dev_warn(hace_dev->dev, "HASH no active requests.\n");
42 }
43
62f58b16
NL
44 if (sts & HACE_CRYPTO_ISR) {
45 if (crypto_engine->flags & CRYPTO_FLAGS_BUSY)
46 tasklet_schedule(&crypto_engine->done_task);
47 else
48 dev_warn(hace_dev->dev, "CRYPTO no active requests.\n");
49 }
50
108713a7
NL
51 return IRQ_HANDLED;
52}
53
62f58b16
NL
54static void aspeed_hace_crypto_done_task(unsigned long data)
55{
56 struct aspeed_hace_dev *hace_dev = (struct aspeed_hace_dev *)data;
57 struct aspeed_engine_crypto *crypto_engine = &hace_dev->crypto_engine;
58
59 crypto_engine->resume(hace_dev);
60}
61
108713a7
NL
62static void aspeed_hace_hash_done_task(unsigned long data)
63{
64 struct aspeed_hace_dev *hace_dev = (struct aspeed_hace_dev *)data;
65 struct aspeed_engine_hash *hash_engine = &hace_dev->hash_engine;
66
67 hash_engine->resume(hace_dev);
68}
69
70static void aspeed_hace_register(struct aspeed_hace_dev *hace_dev)
71{
72#ifdef CONFIG_CRYPTO_DEV_ASPEED_HACE_HASH
73 aspeed_register_hace_hash_algs(hace_dev);
74#endif
62f58b16
NL
75#ifdef CONFIG_CRYPTO_DEV_ASPEED_HACE_CRYPTO
76 aspeed_register_hace_crypto_algs(hace_dev);
77#endif
108713a7
NL
78}
79
80static void aspeed_hace_unregister(struct aspeed_hace_dev *hace_dev)
81{
82#ifdef CONFIG_CRYPTO_DEV_ASPEED_HACE_HASH
83 aspeed_unregister_hace_hash_algs(hace_dev);
84#endif
62f58b16
NL
85#ifdef CONFIG_CRYPTO_DEV_ASPEED_HACE_CRYPTO
86 aspeed_unregister_hace_crypto_algs(hace_dev);
87#endif
108713a7
NL
88}
89
90static const struct of_device_id aspeed_hace_of_matches[] = {
91 { .compatible = "aspeed,ast2500-hace", .data = (void *)5, },
92 { .compatible = "aspeed,ast2600-hace", .data = (void *)6, },
93 {},
94};
95
96static int aspeed_hace_probe(struct platform_device *pdev)
97{
62f58b16 98 struct aspeed_engine_crypto *crypto_engine;
108713a7
NL
99 const struct of_device_id *hace_dev_id;
100 struct aspeed_engine_hash *hash_engine;
101 struct aspeed_hace_dev *hace_dev;
108713a7
NL
102 int rc;
103
104 hace_dev = devm_kzalloc(&pdev->dev, sizeof(struct aspeed_hace_dev),
105 GFP_KERNEL);
106 if (!hace_dev)
107 return -ENOMEM;
108
109 hace_dev_id = of_match_device(aspeed_hace_of_matches, &pdev->dev);
110 if (!hace_dev_id) {
111 dev_err(&pdev->dev, "Failed to match hace dev id\n");
112 return -EINVAL;
113 }
114
115 hace_dev->dev = &pdev->dev;
116 hace_dev->version = (unsigned long)hace_dev_id->data;
117 hash_engine = &hace_dev->hash_engine;
62f58b16 118 crypto_engine = &hace_dev->crypto_engine;
108713a7 119
108713a7
NL
120 platform_set_drvdata(pdev, hace_dev);
121
e9040736 122 hace_dev->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
b411b1a0 123 if (IS_ERR(hace_dev->regs))
dc377e01 124 return PTR_ERR(hace_dev->regs);
108713a7
NL
125
126 /* Get irq number and register it */
127 hace_dev->irq = platform_get_irq(pdev, 0);
70513e1d 128 if (hace_dev->irq < 0)
108713a7 129 return -ENXIO;
108713a7
NL
130
131 rc = devm_request_irq(&pdev->dev, hace_dev->irq, aspeed_hace_irq, 0,
132 dev_name(&pdev->dev), hace_dev);
133 if (rc) {
134 dev_err(&pdev->dev, "Failed to request interrupt\n");
135 return rc;
136 }
137
138 /* Get clk and enable it */
139 hace_dev->clk = devm_clk_get(&pdev->dev, NULL);
140 if (IS_ERR(hace_dev->clk)) {
141 dev_err(&pdev->dev, "Failed to get clk\n");
142 return -ENODEV;
143 }
144
145 rc = clk_prepare_enable(hace_dev->clk);
146 if (rc) {
147 dev_err(&pdev->dev, "Failed to enable clock 0x%x\n", rc);
148 return rc;
149 }
150
151 /* Initialize crypto hardware engine structure for hash */
152 hace_dev->crypt_engine_hash = crypto_engine_alloc_init(hace_dev->dev,
153 true);
154 if (!hace_dev->crypt_engine_hash) {
155 rc = -ENOMEM;
156 goto clk_exit;
157 }
158
159 rc = crypto_engine_start(hace_dev->crypt_engine_hash);
160 if (rc)
161 goto err_engine_hash_start;
162
163 tasklet_init(&hash_engine->done_task, aspeed_hace_hash_done_task,
164 (unsigned long)hace_dev);
165
62f58b16
NL
166 /* Initialize crypto hardware engine structure for crypto */
167 hace_dev->crypt_engine_crypto = crypto_engine_alloc_init(hace_dev->dev,
168 true);
169 if (!hace_dev->crypt_engine_crypto) {
170 rc = -ENOMEM;
171 goto err_engine_hash_start;
172 }
173
174 rc = crypto_engine_start(hace_dev->crypt_engine_crypto);
175 if (rc)
176 goto err_engine_crypto_start;
177
178 tasklet_init(&crypto_engine->done_task, aspeed_hace_crypto_done_task,
179 (unsigned long)hace_dev);
180
108713a7
NL
181 /* Allocate DMA buffer for hash engine input used */
182 hash_engine->ahash_src_addr =
183 dmam_alloc_coherent(&pdev->dev,
184 ASPEED_HASH_SRC_DMA_BUF_LEN,
185 &hash_engine->ahash_src_dma_addr,
186 GFP_KERNEL);
187 if (!hash_engine->ahash_src_addr) {
188 dev_err(&pdev->dev, "Failed to allocate dma buffer\n");
189 rc = -ENOMEM;
62f58b16
NL
190 goto err_engine_crypto_start;
191 }
192
193 /* Allocate DMA buffer for crypto engine context used */
194 crypto_engine->cipher_ctx =
195 dmam_alloc_coherent(&pdev->dev,
196 PAGE_SIZE,
197 &crypto_engine->cipher_ctx_dma,
198 GFP_KERNEL);
199 if (!crypto_engine->cipher_ctx) {
200 dev_err(&pdev->dev, "Failed to allocate cipher ctx dma\n");
201 rc = -ENOMEM;
202 goto err_engine_crypto_start;
203 }
204
205 /* Allocate DMA buffer for crypto engine input used */
206 crypto_engine->cipher_addr =
207 dmam_alloc_coherent(&pdev->dev,
208 ASPEED_CRYPTO_SRC_DMA_BUF_LEN,
209 &crypto_engine->cipher_dma_addr,
210 GFP_KERNEL);
211 if (!crypto_engine->cipher_addr) {
212 dev_err(&pdev->dev, "Failed to allocate cipher addr dma\n");
213 rc = -ENOMEM;
214 goto err_engine_crypto_start;
215 }
216
217 /* Allocate DMA buffer for crypto engine output used */
218 if (hace_dev->version == AST2600_VERSION) {
219 crypto_engine->dst_sg_addr =
220 dmam_alloc_coherent(&pdev->dev,
221 ASPEED_CRYPTO_DST_DMA_BUF_LEN,
222 &crypto_engine->dst_sg_dma_addr,
223 GFP_KERNEL);
224 if (!crypto_engine->dst_sg_addr) {
225 dev_err(&pdev->dev, "Failed to allocate dst_sg dma\n");
226 rc = -ENOMEM;
227 goto err_engine_crypto_start;
228 }
108713a7
NL
229 }
230
231 aspeed_hace_register(hace_dev);
232
233 dev_info(&pdev->dev, "Aspeed Crypto Accelerator successfully registered\n");
234
235 return 0;
236
62f58b16
NL
237err_engine_crypto_start:
238 crypto_engine_exit(hace_dev->crypt_engine_crypto);
108713a7
NL
239err_engine_hash_start:
240 crypto_engine_exit(hace_dev->crypt_engine_hash);
241clk_exit:
242 clk_disable_unprepare(hace_dev->clk);
243
244 return rc;
245}
246
247static int aspeed_hace_remove(struct platform_device *pdev)
248{
249 struct aspeed_hace_dev *hace_dev = platform_get_drvdata(pdev);
62f58b16 250 struct aspeed_engine_crypto *crypto_engine = &hace_dev->crypto_engine;
108713a7
NL
251 struct aspeed_engine_hash *hash_engine = &hace_dev->hash_engine;
252
253 aspeed_hace_unregister(hace_dev);
254
255 crypto_engine_exit(hace_dev->crypt_engine_hash);
62f58b16 256 crypto_engine_exit(hace_dev->crypt_engine_crypto);
108713a7
NL
257
258 tasklet_kill(&hash_engine->done_task);
62f58b16 259 tasklet_kill(&crypto_engine->done_task);
108713a7
NL
260
261 clk_disable_unprepare(hace_dev->clk);
262
263 return 0;
264}
265
266MODULE_DEVICE_TABLE(of, aspeed_hace_of_matches);
267
268static struct platform_driver aspeed_hace_driver = {
269 .probe = aspeed_hace_probe,
270 .remove = aspeed_hace_remove,
271 .driver = {
272 .name = KBUILD_MODNAME,
273 .of_match_table = aspeed_hace_of_matches,
274 },
275};
276
277module_platform_driver(aspeed_hace_driver);
278
279MODULE_AUTHOR("Neal Liu <neal_liu@aspeedtech.com>");
280MODULE_DESCRIPTION("Aspeed HACE driver Crypto Accelerator");
281MODULE_LICENSE("GPL");