crypto: ice: Make ICE init & reset API synchronous

ICE init & reset can be synchronous now because ICE does not need
to go to secure side for any ICE configuration. This would simplify
interface and make call more efficient.

Change-Id: I7aa4e2d3ba3383d25758b21b8ae261a0220f35f9
Signed-off-by: Dinesh K Garg <dineshg@codeaurora.org>
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
Signed-off-by: Gilad Broner <gbroner@codeaurora.org>
This commit is contained in:
Dinesh K Garg 2015-10-26 11:40:37 -07:00 committed by AnilKumar Chimata
parent 7fe56710a1
commit a646e145b2
6 changed files with 46 additions and 189 deletions

View File

@ -88,7 +88,6 @@ struct ice_device {
bool is_ice_enabled;
bool is_ice_disable_fuse_blown;
bool is_clear_irq_pending;
ice_success_cb success_cb;
ice_error_cb error_cb;
void *host_controller_data; /* UFS/EMMC/other? */
spinlock_t lock;
@ -987,25 +986,26 @@ out:
return ret;
}
static void qcom_ice_finish_init(void *data, async_cookie_t cookie)
static int qcom_ice_finish_init(struct ice_device *ice_dev)
{
struct ice_device *ice_dev = data;
unsigned reg;
int err = 0;
if (!ice_dev) {
pr_err("%s: Null data received\n", __func__);
return;
err = -ENODEV;
goto out;
}
if (ice_dev->is_ice_clk_available) {
if (qcom_ice_init_clocks(ice_dev)) {
ice_dev->error_cb(ice_dev->host_controller_data,
ICE_ERROR_IMPROPER_INITIALIZATION);
return;
err = -ICE_ERROR_IMPROPER_INITIALIZATION;
goto out;
}
if (qcom_ice_bus_register(ice_dev)) {
err = -ICE_ERROR_IMPROPER_INITIALIZATION;
goto out;
}
if (qcom_ice_bus_register(ice_dev))
ice_dev->error_cb(ice_dev->host_controller_data,
ICE_ERROR_IMPROPER_INITIALIZATION);
}
/*
@ -1015,15 +1015,13 @@ static void qcom_ice_finish_init(void *data, async_cookie_t cookie)
* configurations of host & ice. It is prudent to restore the config
*/
if (qcom_ice_update_sec_cfg(ice_dev)) {
ice_dev->error_cb(ice_dev->host_controller_data,
ICE_ERROR_ICE_TZ_INIT_FAILED);
return;
err = -ICE_ERROR_ICE_TZ_INIT_FAILED;
goto out;
}
if (qcom_ice_verify_ice(ice_dev)) {
ice_dev->error_cb(ice_dev->host_controller_data,
ICE_ERROR_UNEXPECTED_ICE_DEVICE);
return;
err = -ICE_ERROR_UNEXPECTED_ICE_DEVICE;
goto out;
}
/* if ICE_DISABLE_FUSE is blown, return immediately */
@ -1034,16 +1032,14 @@ static void qcom_ice_finish_init(void *data, async_cookie_t cookie)
ice_dev->is_ice_disable_fuse_blown = true;
pr_err("%s: Error: ICE_ERROR_HW_DISABLE_FUSE_BLOWN\n",
__func__);
ice_dev->error_cb(ice_dev->host_controller_data,
ICE_ERROR_HW_DISABLE_FUSE_BLOWN);
return;
err = -ICE_ERROR_HW_DISABLE_FUSE_BLOWN;
goto out;
}
if (!qcom_ice_secure_ice_init(ice_dev)) {
pr_err("%s: Error: ICE_ERROR_ICE_TZ_INIT_FAILED\n", __func__);
ice_dev->error_cb(ice_dev->host_controller_data,
ICE_ERROR_ICE_TZ_INIT_FAILED);
return;
err = -ICE_ERROR_ICE_TZ_INIT_FAILED;
goto out;
}
qcom_ice_low_power_mode_enable(ice_dev);
@ -1054,14 +1050,12 @@ static void qcom_ice_finish_init(void *data, async_cookie_t cookie)
ice_dev->is_ice_enabled = true;
qcom_ice_enable_intr(ice_dev);
ice_dev->success_cb(ice_dev->host_controller_data,
ICE_INIT_COMPLETION);
return;
out:
return err;
}
static int qcom_ice_init(struct platform_device *pdev,
void *host_controller_data,
ice_success_cb success_cb,
ice_error_cb error_cb)
{
/*
@ -1079,29 +1073,20 @@ static int qcom_ice_init(struct platform_device *pdev,
return -EINVAL;
}
ice_dev->success_cb = success_cb;
ice_dev->error_cb = error_cb;
ice_dev->host_controller_data = host_controller_data;
/*
* As ICE init may take time, create an async task to complete rest
* of init
*/
async_schedule(qcom_ice_finish_init, ice_dev);
return 0;
return qcom_ice_finish_init(ice_dev);
}
EXPORT_SYMBOL(qcom_ice_init);
static void qcom_ice_finish_power_collapse(void *data, async_cookie_t cookie)
static int qcom_ice_finish_power_collapse(struct ice_device *ice_dev)
{
struct ice_device *ice_dev = data;
int err = 0;
if (ice_dev->is_ice_disable_fuse_blown) {
ice_dev->error_cb(ice_dev->host_controller_data,
ICE_ERROR_HW_DISABLE_FUSE_BLOWN);
return;
err = -ICE_ERROR_HW_DISABLE_FUSE_BLOWN;
goto out;
}
if (ice_dev->is_ice_enabled) {
@ -1121,9 +1106,10 @@ static void qcom_ice_finish_power_collapse(void *data, async_cookie_t cookie)
* When ICE resets, it wipes all of keys from LUTs
* ICE driver should call TZ to restore keys
*/
if (qcom_ice_restore_config())
ice_dev->error_cb(ice_dev->host_controller_data,
ICE_ERROR_ICE_KEY_RESTORE_FAILED);
if (qcom_ice_restore_config()) {
err = -ICE_ERROR_ICE_KEY_RESTORE_FAILED;
goto out;
}
}
/*
* INTR Status are not retained. So there is no need to
@ -1133,14 +1119,11 @@ static void qcom_ice_finish_power_collapse(void *data, async_cookie_t cookie)
}
ice_dev->ice_reset_complete_time = ktime_get();
if (ice_dev->success_cb && ice_dev->host_controller_data)
ice_dev->success_cb(ice_dev->host_controller_data,
ICE_RESUME_COMPLETION);
return;
out:
return err;
}
static int qcom_ice_resume(struct platform_device *pdev)
static int qcom_ice_resume(struct platform_device *pdev)
{
/*
* ICE is power collapsed when storage controller is power collapsed
@ -1168,10 +1151,6 @@ static int qcom_ice_resume(struct platform_device *pdev)
qcom_ice_enable(ice_dev);
}
if (ice_dev->success_cb && ice_dev->host_controller_data)
ice_dev->success_cb(ice_dev->host_controller_data,
ICE_RESUME_COMPLETION);
return 0;
}
EXPORT_SYMBOL(qcom_ice_resume);
@ -1388,8 +1367,7 @@ static int qcom_ice_reset(struct platform_device *pdev)
ice_dev->ice_reset_start_time = ktime_get();
async_schedule(qcom_ice_finish_power_collapse, ice_dev);
return 0;
return qcom_ice_finish_power_collapse(ice_dev);
}
EXPORT_SYMBOL(qcom_ice_reset);

View File

@ -13,19 +13,6 @@
#include "sdhci-msm-ice.h"
static void sdhci_msm_ice_success_cb(void *host_ctrl,
enum ice_event_completion evt)
{
struct sdhci_msm_host *msm_host = (struct sdhci_msm_host *)host_ctrl;
if ((msm_host->ice.state == SDHCI_MSM_ICE_STATE_DISABLED &&
evt == ICE_INIT_COMPLETION) || (msm_host->ice.state ==
SDHCI_MSM_ICE_STATE_SUSPENDED && evt == ICE_RESUME_COMPLETION))
msm_host->ice.state = SDHCI_MSM_ICE_STATE_ACTIVE;
complete(&msm_host->ice.async_done);
}
static void sdhci_msm_ice_error_cb(void *host_ctrl, enum ice_error_code evt)
{
struct sdhci_msm_host *msm_host = (struct sdhci_msm_host *)host_ctrl;
@ -35,8 +22,6 @@ static void sdhci_msm_ice_error_cb(void *host_ctrl, enum ice_error_code evt)
if (msm_host->ice.state == SDHCI_MSM_ICE_STATE_ACTIVE)
msm_host->ice.state = SDHCI_MSM_ICE_STATE_DISABLED;
complete(&msm_host->ice.async_done);
}
static struct platform_device *sdhci_msm_ice_get_pdevice(struct device *dev)
@ -117,34 +102,21 @@ int sdhci_msm_ice_init(struct sdhci_host *host)
struct sdhci_msm_host *msm_host = pltfm_host->priv;
int err = 0;
init_completion(&msm_host->ice.async_done);
if (msm_host->ice.vops->config) {
err = msm_host->ice.vops->init(msm_host->ice.pdev,
msm_host,
sdhci_msm_ice_success_cb,
sdhci_msm_ice_error_cb);
if (err) {
pr_err("%s: ice init err %d\n",
mmc_hostname(host->mmc), err);
return err;
sdhci_msm_ice_print_regs(host);
goto out;
}
msm_host->ice.state = SDHCI_MSM_ICE_STATE_ACTIVE;
}
if (!wait_for_completion_timeout(&msm_host->ice.async_done,
msecs_to_jiffies(SDHCI_MSM_ICE_COMPLETION_TIMEOUT_MS))) {
pr_err("%s: ice init timedout after %d ms\n",
mmc_hostname(host->mmc),
SDHCI_MSM_ICE_COMPLETION_TIMEOUT_MS);
sdhci_msm_ice_print_regs(host);
return -ETIMEDOUT;
}
if (msm_host->ice.state != SDHCI_MSM_ICE_STATE_ACTIVE) {
pr_err("%s: ice is in invalid state %d\n",
mmc_hostname(host->mmc), msm_host->ice.state);
return -EINVAL;
}
return 0;
out:
return err;
}
void sdhci_msm_ice_cfg_reset(struct sdhci_host *host, u32 slot)
@ -244,26 +216,16 @@ int sdhci_msm_ice_reset(struct sdhci_host *host)
return -EINVAL;
}
init_completion(&msm_host->ice.async_done);
if (msm_host->ice.vops->reset) {
err = msm_host->ice.vops->reset(msm_host->ice.pdev);
if (err) {
pr_err("%s: ice reset failed %d\n",
mmc_hostname(host->mmc), err);
sdhci_msm_ice_print_regs(host);
return err;
}
}
if (!wait_for_completion_timeout(&msm_host->ice.async_done,
msecs_to_jiffies(SDHCI_MSM_ICE_COMPLETION_TIMEOUT_MS))) {
pr_err("%s: ice reset timedout after %d ms\n",
mmc_hostname(host->mmc),
SDHCI_MSM_ICE_COMPLETION_TIMEOUT_MS);
sdhci_msm_ice_print_regs(host);
return -ETIMEDOUT;
}
if (msm_host->ice.state != SDHCI_MSM_ICE_STATE_ACTIVE) {
pr_err("%s: ice is in invalid state after reset %d\n",
mmc_hostname(host->mmc), msm_host->ice.state);
@ -285,8 +247,6 @@ int sdhci_msm_ice_resume(struct sdhci_host *host)
return -EINVAL;
}
init_completion(&msm_host->ice.async_done);
if (msm_host->ice.vops->resume) {
err = msm_host->ice.vops->resume(msm_host->ice.pdev);
if (err) {
@ -296,20 +256,7 @@ int sdhci_msm_ice_resume(struct sdhci_host *host)
}
}
if (!wait_for_completion_timeout(&msm_host->ice.async_done,
msecs_to_jiffies(SDHCI_MSM_ICE_COMPLETION_TIMEOUT_MS))) {
pr_err("%s: ice resume timedout after %d ms\n",
mmc_hostname(host->mmc),
SDHCI_MSM_ICE_COMPLETION_TIMEOUT_MS);
sdhci_msm_ice_print_regs(host);
return -ETIMEDOUT;
}
if (msm_host->ice.state != SDHCI_MSM_ICE_STATE_ACTIVE) {
pr_err("%s: ice is in invalid state after resume %d\n",
mmc_hostname(host->mmc), msm_host->ice.state);
return -EINVAL;
}
msm_host->ice.state = SDHCI_MSM_ICE_STATE_ACTIVE;
return 0;
}

View File

@ -17,7 +17,6 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/async.h>
#include <linux/blkdev.h>
#include <crypto/ice.h>

View File

@ -128,7 +128,6 @@ struct sdhci_msm_bus_vote {
struct sdhci_msm_ice_data {
struct qcom_ice_variant_ops *vops;
struct completion async_done;
struct platform_device *pdev;
int state;
};

View File

@ -13,7 +13,6 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/async.h>
#include <linux/blkdev.h>
#include <linux/scsi/ufs/ufshcd.h>
#include <crypto/ice.h>
@ -53,26 +52,10 @@ void ufs_qcom_ice_print_regs(struct ufs_qcom_host *qcom_host)
pr_err("REG_UFS_QCOM_ICE_CTRL_INFO_2_%d = 0x%08X\n", i,
ufshcd_readl(qcom_host->hba,
(REG_UFS_QCOM_ICE_CTRL_INFO_2_n + 8 * i)));
}
}
static void ufs_qcom_ice_success_cb(void *host_ctrl,
enum ice_event_completion evt)
{
struct ufs_qcom_host *qcom_host = (struct ufs_qcom_host *)host_ctrl;
if (qcom_host->ice.state == UFS_QCOM_ICE_STATE_DISABLED &&
evt == ICE_INIT_COMPLETION)
qcom_host->ice.state = UFS_QCOM_ICE_STATE_ACTIVE;
else if (qcom_host->ice.state == UFS_QCOM_ICE_STATE_SUSPENDED &&
evt == ICE_RESUME_COMPLETION)
qcom_host->ice.state = UFS_QCOM_ICE_STATE_ACTIVE;
complete(&qcom_host->ice.async_done);
}
static void ufs_qcom_ice_error_cb(void *host_ctrl, enum ice_error_code evt)
{
struct ufs_qcom_host *qcom_host = (struct ufs_qcom_host *)host_ctrl;
@ -82,8 +65,6 @@ static void ufs_qcom_ice_error_cb(void *host_ctrl, enum ice_error_code evt)
if (qcom_host->ice.state == UFS_QCOM_ICE_STATE_ACTIVE)
qcom_host->ice.state = UFS_QCOM_ICE_STATE_DISABLED;
complete(&qcom_host->ice.async_done);
}
static struct platform_device *ufs_qcom_ice_get_pdevice(struct device *ufs_dev)
@ -195,33 +176,17 @@ out:
int ufs_qcom_ice_init(struct ufs_qcom_host *qcom_host)
{
struct device *ufs_dev = qcom_host->hba->dev;
int err = -EINVAL;
int err;
init_completion(&qcom_host->ice.async_done);
err = qcom_host->ice.vops->init(qcom_host->ice.pdev,
qcom_host,
ufs_qcom_ice_success_cb,
ufs_qcom_ice_error_cb);
if (err) {
dev_err(ufs_dev, "%s: ice init failed. err = %d\n",
__func__, err);
goto out;
}
if (!wait_for_completion_timeout(&qcom_host->ice.async_done,
msecs_to_jiffies(UFS_QCOM_ICE_COMPLETION_TIMEOUT_MS))) {
dev_err(qcom_host->hba->dev,
"%s: error. got timeout after %d ms\n",
__func__, UFS_QCOM_ICE_COMPLETION_TIMEOUT_MS);
err = -ETIMEDOUT;
goto out;
}
if (qcom_host->ice.state != UFS_QCOM_ICE_STATE_ACTIVE) {
dev_err(qcom_host->hba->dev,
"%s: error. ice.state (%d) is not in active state\n",
__func__, qcom_host->ice.state);
err = -EINVAL;
} else {
qcom_host->ice.state = UFS_QCOM_ICE_STATE_ACTIVE;
}
qcom_host->dbg_print_en |= UFS_QCOM_ICE_DEFAULT_DBG_PRINT_EN;
@ -379,8 +344,6 @@ int ufs_qcom_ice_reset(struct ufs_qcom_host *qcom_host)
if (qcom_host->ice.state != UFS_QCOM_ICE_STATE_ACTIVE)
goto out;
init_completion(&qcom_host->ice.async_done);
if (qcom_host->ice.vops->reset) {
err = qcom_host->ice.vops->reset(qcom_host->ice.pdev);
if (err) {
@ -390,14 +353,6 @@ int ufs_qcom_ice_reset(struct ufs_qcom_host *qcom_host)
}
}
if (!wait_for_completion_timeout(&qcom_host->ice.async_done,
msecs_to_jiffies(UFS_QCOM_ICE_COMPLETION_TIMEOUT_MS))) {
dev_err(dev,
"%s: error. got timeout after %d ms\n",
__func__, UFS_QCOM_ICE_COMPLETION_TIMEOUT_MS);
err = -ETIMEDOUT;
}
if (qcom_host->ice.state != UFS_QCOM_ICE_STATE_ACTIVE) {
dev_err(qcom_host->hba->dev,
"%s: error. ice.state (%d) is not in active state\n",
@ -439,28 +394,15 @@ int ufs_qcom_ice_resume(struct ufs_qcom_host *qcom_host)
return -EINVAL;
}
init_completion(&qcom_host->ice.async_done);
if (qcom_host->ice.vops->resume) {
err = qcom_host->ice.vops->resume(qcom_host->ice.pdev);
if (err) {
dev_err(dev, "%s: ice_vops->resume failed. err %d\n",
__func__, err);
return -EINVAL;
return err;
}
}
if (!wait_for_completion_timeout(&qcom_host->ice.async_done,
msecs_to_jiffies(UFS_QCOM_ICE_COMPLETION_TIMEOUT_MS))) {
dev_err(dev,
"%s: error. got timeout after %d ms\n",
__func__, UFS_QCOM_ICE_COMPLETION_TIMEOUT_MS);
err = -ETIMEDOUT;
goto out;
}
if (qcom_host->ice.state != UFS_QCOM_ICE_STATE_ACTIVE)
err = -EINVAL;
qcom_host->ice.state = UFS_QCOM_ICE_STATE_ACTIVE;
out:
return err;
}

View File

@ -49,12 +49,6 @@ struct ice_data_setting {
bool encr_bypass;
};
enum ice_event_completion {
ICE_INIT_COMPLETION,
ICE_RESUME_COMPLETION,
ICE_RESET_COMPLETION,
};
enum ice_error_code {
ICE_ERROR_UNEXPECTED_ICE_DEVICE,
ICE_ERROR_PARTITIAL_KEY_LOAD,
@ -81,7 +75,6 @@ enum ice_error_code {
ICE_ERROR_STREAM2_NOT_EXPECTED_NEW_TRNS
};
typedef void (*ice_success_cb)(void *, enum ice_event_completion);
typedef void (*ice_error_cb)(void *, enum ice_error_code);
struct qcom_ice_variant_ops *qcom_ice_get_variant_ops(struct device_node *node);
@ -98,8 +91,7 @@ static inline int qcom_ice_setup_ice_hw(const char *storage_type, int enable)
struct qcom_ice_variant_ops {
const char *name;
int (*init)(struct platform_device *, void *,
ice_success_cb, ice_error_cb);
int (*init)(struct platform_device *, void *, ice_error_cb);
int (*reset)(struct platform_device *);
int (*resume)(struct platform_device *);
int (*suspend)(struct platform_device *);