Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4571f9a authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "crypto: ice: Make ICE init & reset API synchronous"

parents 1b4975d2 4b6110e6
Loading
Loading
Loading
Loading
+33 −55
Original line number Diff line number Diff line
@@ -91,7 +91,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;
@@ -1028,25 +1027,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);
	}

	/*
@@ -1056,15 +1056,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
@@ -1081,18 +1079,16 @@ 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;
	}

	/* TZ side of ICE driver would handle secure init of ICE HW from v2 */
	if (ICE_REV(ice_dev->ice_hw_version, MAJOR) == 1 &&
		!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);
@@ -1103,14 +1099,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)
{
	/*
@@ -1128,29 +1122,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) {
@@ -1170,9 +1155,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
@@ -1182,11 +1168,8 @@ 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)
@@ -1217,10 +1200,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);
@@ -1445,8 +1424,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);

+7 −60
Original line number Diff line number Diff line
@@ -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;
		}
	}

	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;
			goto out;
		}

	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;
		msm_host->ice.state = SDHCI_MSM_ICE_STATE_ACTIVE;
	}
	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;
}

+0 −1
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@

#include <linux/io.h>
#include <linux/of.h>
#include <linux/async.h>
#include <linux/blkdev.h>
#include <crypto/ice.h>

+0 −1
Original line number Diff line number Diff line
@@ -166,7 +166,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;
};
+5 −63
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@

#include <linux/io.h>
#include <linux/of.h>
#include <linux/async.h>
#include <linux/blkdev.h>
#include <crypto/ice.h>

@@ -53,24 +52,8 @@ 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)
@@ -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;
@@ -390,8 +355,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) {
@@ -401,14 +364,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",
@@ -450,28 +405,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;
}
Loading