aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/ccree
diff options
context:
space:
mode:
authorGilad Ben-Yossef <gilad@benyossef.com>2019-02-07 08:36:11 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2019-02-08 02:28:02 -0500
commit1358c13a48c43f5e4de0c1835291837a27b9720c (patch)
treee5ec75ed516856e6e08a1cbe1dc5f6415c20a810 /drivers/crypto/ccree
parent356690d029e10f1aadebc49819d3908d5f6389fb (diff)
crypto: ccree - fix resume race condition on init
We were enabling autosuspend, which is using data set by the hash module, prior to the hash module being inited, casuing a crash on resume as part of the startup sequence if the race was lost. This was never a real problem because the PM infra was using low res timers so we were always winning the race, until commit 8234f6734c5d ("PM-runtime: Switch autosuspend over to using hrtimers") changed that :-) Fix this by seperating the PM setup and enablement and doing the latter only at the end of the init sequence. Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com> Cc: Vincent Guittot <vincent.guittot@linaro.org> Cc: stable@kernel.org # v4.20 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/ccree')
-rw-r--r--drivers/crypto/ccree/cc_driver.c7
-rw-r--r--drivers/crypto/ccree/cc_pm.c13
-rw-r--r--drivers/crypto/ccree/cc_pm.h3
3 files changed, 13 insertions, 10 deletions
diff --git a/drivers/crypto/ccree/cc_driver.c b/drivers/crypto/ccree/cc_driver.c
index 8ada308d72ee..b0125ad65825 100644
--- a/drivers/crypto/ccree/cc_driver.c
+++ b/drivers/crypto/ccree/cc_driver.c
@@ -380,7 +380,7 @@ static int init_cc_resources(struct platform_device *plat_dev)
380 rc = cc_ivgen_init(new_drvdata); 380 rc = cc_ivgen_init(new_drvdata);
381 if (rc) { 381 if (rc) {
382 dev_err(dev, "cc_ivgen_init failed\n"); 382 dev_err(dev, "cc_ivgen_init failed\n");
383 goto post_power_mgr_err; 383 goto post_buf_mgr_err;
384 } 384 }
385 385
386 /* Allocate crypto algs */ 386 /* Allocate crypto algs */
@@ -403,6 +403,9 @@ static int init_cc_resources(struct platform_device *plat_dev)
403 goto post_hash_err; 403 goto post_hash_err;
404 } 404 }
405 405
406 /* All set, we can allow autosuspend */
407 cc_pm_go(new_drvdata);
408
406 /* If we got here and FIPS mode is enabled 409 /* If we got here and FIPS mode is enabled
407 * it means all FIPS test passed, so let TEE 410 * it means all FIPS test passed, so let TEE
408 * know we're good. 411 * know we're good.
@@ -417,8 +420,6 @@ post_cipher_err:
417 cc_cipher_free(new_drvdata); 420 cc_cipher_free(new_drvdata);
418post_ivgen_err: 421post_ivgen_err:
419 cc_ivgen_fini(new_drvdata); 422 cc_ivgen_fini(new_drvdata);
420post_power_mgr_err:
421 cc_pm_fini(new_drvdata);
422post_buf_mgr_err: 423post_buf_mgr_err:
423 cc_buffer_mgr_fini(new_drvdata); 424 cc_buffer_mgr_fini(new_drvdata);
424post_req_mgr_err: 425post_req_mgr_err:
diff --git a/drivers/crypto/ccree/cc_pm.c b/drivers/crypto/ccree/cc_pm.c
index d990f472e89f..6ff7e75ad90e 100644
--- a/drivers/crypto/ccree/cc_pm.c
+++ b/drivers/crypto/ccree/cc_pm.c
@@ -100,20 +100,19 @@ int cc_pm_put_suspend(struct device *dev)
100 100
101int cc_pm_init(struct cc_drvdata *drvdata) 101int cc_pm_init(struct cc_drvdata *drvdata)
102{ 102{
103 int rc = 0;
104 struct device *dev = drvdata_to_dev(drvdata); 103 struct device *dev = drvdata_to_dev(drvdata);
105 104
106 /* must be before the enabling to avoid resdundent suspending */ 105 /* must be before the enabling to avoid resdundent suspending */
107 pm_runtime_set_autosuspend_delay(dev, CC_SUSPEND_TIMEOUT); 106 pm_runtime_set_autosuspend_delay(dev, CC_SUSPEND_TIMEOUT);
108 pm_runtime_use_autosuspend(dev); 107 pm_runtime_use_autosuspend(dev);
109 /* activate the PM module */ 108 /* activate the PM module */
110 rc = pm_runtime_set_active(dev); 109 return pm_runtime_set_active(dev);
111 if (rc) 110}
112 return rc;
113 /* enable the PM module*/
114 pm_runtime_enable(dev);
115 111
116 return rc; 112/* enable the PM module*/
113void cc_pm_go(struct cc_drvdata *drvdata)
114{
115 pm_runtime_enable(drvdata_to_dev(drvdata));
117} 116}
118 117
119void cc_pm_fini(struct cc_drvdata *drvdata) 118void cc_pm_fini(struct cc_drvdata *drvdata)
diff --git a/drivers/crypto/ccree/cc_pm.h b/drivers/crypto/ccree/cc_pm.h
index 020a5403c58b..f62624357020 100644
--- a/drivers/crypto/ccree/cc_pm.h
+++ b/drivers/crypto/ccree/cc_pm.h
@@ -16,6 +16,7 @@
16extern const struct dev_pm_ops ccree_pm; 16extern const struct dev_pm_ops ccree_pm;
17 17
18int cc_pm_init(struct cc_drvdata *drvdata); 18int cc_pm_init(struct cc_drvdata *drvdata);
19void cc_pm_go(struct cc_drvdata *drvdata);
19void cc_pm_fini(struct cc_drvdata *drvdata); 20void cc_pm_fini(struct cc_drvdata *drvdata);
20int cc_pm_suspend(struct device *dev); 21int cc_pm_suspend(struct device *dev);
21int cc_pm_resume(struct device *dev); 22int cc_pm_resume(struct device *dev);
@@ -29,6 +30,8 @@ static inline int cc_pm_init(struct cc_drvdata *drvdata)
29 return 0; 30 return 0;
30} 31}
31 32
33static void cc_pm_go(struct cc_drvdata *drvdata) {}
34
32static inline void cc_pm_fini(struct cc_drvdata *drvdata) {} 35static inline void cc_pm_fini(struct cc_drvdata *drvdata) {}
33 36
34static inline int cc_pm_suspend(struct device *dev) 37static inline int cc_pm_suspend(struct device *dev)