Skip to content

Commit d993cae

Browse files
authored
Merge pull request #274 from arakshit011/qce-pm
FROMLIST: crypto: qce - Add runtime PM and interconnect bandwidth sca…
2 parents c60e1a1 + 690704e commit d993cae

1 file changed

Lines changed: 87 additions & 18 deletions

File tree

drivers/crypto/qce/core.c

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include <linux/module.h>
1313
#include <linux/mod_devicetable.h>
1414
#include <linux/platform_device.h>
15+
#include <linux/pm.h>
16+
#include <linux/pm_runtime.h>
17+
#include <linux/pm_clock.h>
1518
#include <linux/types.h>
1619
#include <crypto/internal/hash.h>
1720

@@ -90,13 +93,17 @@ static int qce_handle_queue(struct qce_device *qce,
9093
struct crypto_async_request *async_req, *backlog;
9194
int ret = 0, err;
9295

96+
ret = pm_runtime_resume_and_get(qce->dev);
97+
if (ret < 0)
98+
return ret;
99+
93100
scoped_guard(mutex, &qce->lock) {
94101
if (req)
95102
ret = crypto_enqueue_request(&qce->queue, req);
96103

97104
/* busy, do not dequeue request */
98105
if (qce->req)
99-
return ret;
106+
goto qce_suspend;
100107

101108
backlog = crypto_get_backlog(&qce->queue);
102109
async_req = crypto_dequeue_request(&qce->queue);
@@ -105,7 +112,7 @@ static int qce_handle_queue(struct qce_device *qce,
105112
}
106113

107114
if (!async_req)
108-
return ret;
115+
goto qce_suspend;
109116

110117
if (backlog) {
111118
scoped_guard(mutex, &qce->lock)
@@ -118,6 +125,8 @@ static int qce_handle_queue(struct qce_device *qce,
118125
schedule_work(&qce->done_work);
119126
}
120127

128+
qce_suspend:
129+
pm_runtime_put_autosuspend(qce->dev);
121130
return ret;
122131
}
123132

@@ -216,37 +225,47 @@ static int qce_crypto_probe(struct platform_device *pdev)
216225
if (ret < 0)
217226
return ret;
218227

219-
qce->core = devm_clk_get_optional_enabled(qce->dev, "core");
220-
if (IS_ERR(qce->core))
221-
return PTR_ERR(qce->core);
228+
/* PM clock helpers: register device clocks */
229+
ret = devm_pm_clk_create(dev);
230+
if (ret)
231+
return ret;
222232

223-
qce->iface = devm_clk_get_optional_enabled(qce->dev, "iface");
224-
if (IS_ERR(qce->iface))
225-
return PTR_ERR(qce->iface);
233+
ret = pm_clk_add(dev, "core");
234+
if (ret)
235+
return ret;
226236

227-
qce->bus = devm_clk_get_optional_enabled(qce->dev, "bus");
228-
if (IS_ERR(qce->bus))
229-
return PTR_ERR(qce->bus);
237+
ret = pm_clk_add(dev, "iface");
238+
if (ret)
239+
return ret;
230240

231-
qce->mem_path = devm_of_icc_get(qce->dev, "memory");
241+
ret = pm_clk_add(dev, "bus");
242+
if (ret)
243+
return ret;
244+
245+
qce->mem_path = devm_of_icc_get(dev, "memory");
232246
if (IS_ERR(qce->mem_path))
233247
return PTR_ERR(qce->mem_path);
234248

235-
ret = icc_set_bw(qce->mem_path, QCE_DEFAULT_MEM_BANDWIDTH, QCE_DEFAULT_MEM_BANDWIDTH);
249+
/* Enable runtime PM after clocks and ICC are acquired */
250+
ret = devm_pm_runtime_enable(dev);
236251
if (ret)
237252
return ret;
238253

239-
ret = devm_qce_dma_request(qce);
254+
ret = pm_runtime_resume_and_get(dev);
240255
if (ret)
241256
return ret;
242257

258+
ret = devm_qce_dma_request(qce);
259+
if (ret)
260+
goto err_pm;
261+
243262
ret = qce_check_version(qce);
244263
if (ret)
245-
return ret;
264+
goto err_pm;
246265

247266
ret = devm_mutex_init(qce->dev, &qce->lock);
248267
if (ret)
249-
return ret;
268+
goto err_pm;
250269

251270
INIT_WORK(&qce->done_work, qce_req_done_work);
252271
crypto_init_queue(&qce->queue, QCE_QUEUE_LENGTH);
@@ -256,19 +275,68 @@ static int qce_crypto_probe(struct platform_device *pdev)
256275

257276
ret = devm_qce_register_algs(qce);
258277
if (ret)
259-
return ret;
278+
goto err_pm;
260279

261280
qce->dma_size = resource_size(res);
262281
qce->base_dma = dma_map_resource(dev, res->start, qce->dma_size,
263282
DMA_BIDIRECTIONAL, 0);
264283
qce->base_phys = res->start;
265284
ret = dma_mapping_error(dev, qce->base_dma);
285+
if (ret)
286+
goto err_pm;
287+
288+
ret = devm_add_action_or_reset(qce->dev, qce_crypto_unmap_dma, qce);
289+
if (ret)
290+
goto err_pm;
291+
292+
/* Configure autosuspend after successful init */
293+
pm_runtime_set_autosuspend_delay(dev, 100);
294+
pm_runtime_use_autosuspend(dev);
295+
pm_runtime_mark_last_busy(dev);
296+
pm_runtime_put_autosuspend(dev);
297+
298+
return 0;
299+
300+
err_pm:
301+
pm_runtime_put(dev);
302+
303+
return ret;
304+
}
305+
306+
static int __maybe_unused qce_runtime_suspend(struct device *dev)
307+
{
308+
struct qce_device *qce = dev_get_drvdata(dev);
309+
310+
icc_disable(qce->mem_path);
311+
312+
return 0;
313+
}
314+
315+
static int __maybe_unused qce_runtime_resume(struct device *dev)
316+
{
317+
struct qce_device *qce = dev_get_drvdata(dev);
318+
int ret = 0;
319+
320+
ret = icc_enable(qce->mem_path);
266321
if (ret)
267322
return ret;
268323

269-
return devm_add_action_or_reset(qce->dev, qce_crypto_unmap_dma, qce);
324+
ret = icc_set_bw(qce->mem_path, QCE_DEFAULT_MEM_BANDWIDTH, QCE_DEFAULT_MEM_BANDWIDTH);
325+
if (ret)
326+
goto err_icc;
327+
328+
return 0;
329+
330+
err_icc:
331+
icc_disable(qce->mem_path);
332+
return ret;
270333
}
271334

335+
static const struct dev_pm_ops qce_crypto_pm_ops = {
336+
SET_RUNTIME_PM_OPS(qce_runtime_suspend, qce_runtime_resume, NULL)
337+
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
338+
};
339+
272340
static const struct of_device_id qce_crypto_of_match[] = {
273341
{ .compatible = "qcom,crypto-v5.1", },
274342
{ .compatible = "qcom,crypto-v5.4", },
@@ -282,6 +350,7 @@ static struct platform_driver qce_crypto_driver = {
282350
.driver = {
283351
.name = KBUILD_MODNAME,
284352
.of_match_table = qce_crypto_of_match,
353+
.pm = &qce_crypto_pm_ops,
285354
},
286355
};
287356
module_platform_driver(qce_crypto_driver);

0 commit comments

Comments
 (0)