Stop publishing a driver-wide singleton. Mark the instance ready with scm->available, look it up from the platform driver for module-parameter stores, and use platform_get_drvdata() on shutdown.
Signed-off-by: Albert Esteve aesteve@redhat.com --- drivers/firmware/qcom/qcom_scm.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 73e9752e3cca..68cd8dc622c6 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -63,6 +63,9 @@ struct qcom_scm {
struct qcom_tzmem_pool *mempool; unsigned int wq_cnt; + + /* Published with smp_store_release() once the SCM API is usable. */ + int available; };
struct qcom_scm_current_perm_info { @@ -174,8 +177,6 @@ static const char * const download_mode_name[] = { [QCOM_DLOAD_BOTHDUMP] = "full,mini", };
-static struct qcom_scm *__scm; - static int qcom_scm_clk_enable(struct qcom_scm *scm) { int ret; @@ -1962,7 +1963,7 @@ EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh_available); * This is only supposed to be called once by the TZMem module. It takes the * SCM struct device as argument and uses it to pass the call as at the time * the SHM Bridge is enabled, the SCM is not yet fully set up and doesn't - * accept global user calls. Don't try to use the __scm pointer here. + * accept global user calls. */ int qcom_scm_shm_bridge_enable(struct device *scm_dev) { @@ -2657,7 +2658,7 @@ static void qcom_scm_qtee_init(struct qcom_scm *scm) bool qcom_scm_is_available(struct qcom_scm *scm) { /* Paired with smp_store_release() in qcom_scm_probe */ - return scm && scm == smp_load_acquire(&__scm); + return scm && smp_load_acquire(&scm->available); } EXPORT_SYMBOL_GPL(qcom_scm_is_available);
@@ -2817,7 +2818,7 @@ static int set_download_mode(const char *val, const struct kernel_param *kp)
download_mode = ret; /* Pairs with smp_store_release() in qcom_scm_probe(). */ - scm = smp_load_acquire(&__scm); + scm = qcom_scm_get(); if (scm) qcom_scm_set_download_mode(scm, download_mode);
@@ -2858,7 +2859,7 @@ static int set_minidump_dest(const char *val, const struct kernel_param *kp) minidump_dest = minidump_dest_map[i].val;
/* Pairs with smp_store_release() in qcom_scm_probe(). */ - scm = smp_load_acquire(&__scm); + scm = qcom_scm_get(); if (scm && scm->minidump_sram && (download_mode & QCOM_DLOAD_MINIDUMP)) writel_relaxed(minidump_dest, scm->minidump_sram);
@@ -2983,7 +2984,7 @@ static int qcom_scm_probe(struct platform_device *pdev) * be called after the TrustZone memory pool is initialized and the * waitqueue interrupt requested. */ - smp_store_release(&__scm, scm); + smp_store_release(&scm->available, 1);
__get_convention(scm->dev);
@@ -3033,8 +3034,10 @@ static int qcom_scm_probe(struct platform_device *pdev)
static void qcom_scm_shutdown(struct platform_device *pdev) { + struct qcom_scm *scm = platform_get_drvdata(pdev); + /* Clean shutdown, disable download mode to allow normal restart */ - qcom_scm_set_download_mode(__scm, QCOM_DLOAD_NODUMP); + qcom_scm_set_download_mode(scm, QCOM_DLOAD_NODUMP); qcom_pas_ops_unregister(); }