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

Commit d7042bda authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "scsi: ufs-qcom: add freeze-restore callback"

parents 593b4d23 25674241
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -2882,6 +2882,9 @@ static const struct dev_pm_ops ufs_qcom_pm_ops = {
	.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
	.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
	.runtime_resume  = ufshcd_pltfrm_runtime_resume,
	.runtime_resume  = ufshcd_pltfrm_runtime_resume,
	.runtime_idle    = ufshcd_pltfrm_runtime_idle,
	.runtime_idle    = ufshcd_pltfrm_runtime_idle,
	.freeze		= ufshcd_pltfrm_freeze,
	.restore	= ufshcd_pltfrm_restore,
	.thaw		= ufshcd_pltfrm_thaw,
};
};


static struct platform_driver ufs_qcom_pltform = {
static struct platform_driver ufs_qcom_pltform = {
+39 −0
Original line number Original line Diff line number Diff line
@@ -370,6 +370,45 @@ static void ufshcd_parse_dev_ref_clk_freq(struct ufs_hba *hba)
}
}


#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
/**
 * ufshcd_pltfrm_restore - restore power management function
 * @dev: pointer to device handle
 *
 * Returns 0 if successful
 * Returns non-zero otherwise
 */
int ufshcd_pltfrm_restore(struct device *dev)
{
	return ufshcd_system_restore(dev_get_drvdata(dev));
}
EXPORT_SYMBOL(ufshcd_pltfrm_restore);

/**
 * ufshcd_pltfrm_freeze - freeze power management function
 * @dev: pointer to device handle
 *
 * Returns 0 if successful
 * Returns non-zero otherwise
 */
int ufshcd_pltfrm_freeze(struct device *dev)
{
	return ufshcd_system_freeze(dev_get_drvdata(dev));
}
EXPORT_SYMBOL(ufshcd_pltfrm_freeze);

/**
 * ufshcd_pltfrm_thaw - freeze power management function
 * @dev: pointer to device handle
 *
 * Returns 0 if successful
 * Returns non-zero otherwise
 */
int ufshcd_pltfrm_thaw(struct device *dev)
{
	return ufshcd_system_thaw(dev_get_drvdata(dev));
}
EXPORT_SYMBOL(ufshcd_pltfrm_thaw);

/**
/**
 * ufshcd_pltfrm_suspend - suspend power management function
 * ufshcd_pltfrm_suspend - suspend power management function
 * @dev: pointer to device handle
 * @dev: pointer to device handle
+4 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -27,6 +27,9 @@ int ufshcd_pltfrm_resume(struct device *dev);
int ufshcd_pltfrm_runtime_suspend(struct device *dev);
int ufshcd_pltfrm_runtime_suspend(struct device *dev);
int ufshcd_pltfrm_runtime_resume(struct device *dev);
int ufshcd_pltfrm_runtime_resume(struct device *dev);
int ufshcd_pltfrm_runtime_idle(struct device *dev);
int ufshcd_pltfrm_runtime_idle(struct device *dev);
int ufshcd_pltfrm_freeze(struct device *dev);
int ufshcd_pltfrm_restore(struct device *dev);
int ufshcd_pltfrm_thaw(struct device *dev);


#else /* !CONFIG_PM */
#else /* !CONFIG_PM */


+41 −3
Original line number Original line Diff line number Diff line
@@ -3817,8 +3817,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
	if (err) {
	if (err) {
		if (err != -EAGAIN)
		if (err != -EAGAIN)
			dev_err(hba->dev,
			dev_err(hba->dev,
				"%s: failed to compose upiu %d\n",
				"%s: failed to compose upiu %d cmd:0x%08x lun:%d\n",
				__func__, err);
				__func__, err, cmd, lrbp->lun);


		lrbp->cmd = NULL;
		lrbp->cmd = NULL;
		clear_bit_unlock(tag, &hba->lrb_in_use);
		clear_bit_unlock(tag, &hba->lrb_in_use);
@@ -10254,7 +10254,19 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
	ret = ufshcd_vreg_set_hpm(hba);
	ret = ufshcd_vreg_set_hpm(hba);
	if (ret)
	if (ret)
		goto disable_irq_and_vops_clks;
		goto disable_irq_and_vops_clks;

	if (hba->restore) {
		/* Configure UTRL and UTMRL base address registers */
		ufshcd_writel(hba, lower_32_bits(hba->utrdl_dma_addr),
			      REG_UTP_TRANSFER_REQ_LIST_BASE_L);
		ufshcd_writel(hba, upper_32_bits(hba->utrdl_dma_addr),
			      REG_UTP_TRANSFER_REQ_LIST_BASE_H);
		ufshcd_writel(hba, lower_32_bits(hba->utmrdl_dma_addr),
			      REG_UTP_TASK_REQ_LIST_BASE_L);
		ufshcd_writel(hba, upper_32_bits(hba->utmrdl_dma_addr),
			      REG_UTP_TASK_REQ_LIST_BASE_H);
		/* Commit the registers */
		mb();
	}
	/*
	/*
	 * Call vendor specific resume callback. As these callbacks may access
	 * Call vendor specific resume callback. As these callbacks may access
	 * vendor specific host controller register space call them when the
	 * vendor specific host controller register space call them when the
@@ -10269,6 +10281,10 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
	     (ufshcd_is_card_online(hba) && !hba->sdev_ufs_device)))
	     (ufshcd_is_card_online(hba) && !hba->sdev_ufs_device)))
		goto skip_dev_ops;
		goto skip_dev_ops;


	/* Resuming from hibernate, assume that link was OFF */
	if (hba->restore)
		ufshcd_set_link_off(hba);

	if (ufshcd_is_link_hibern8(hba)) {
	if (ufshcd_is_link_hibern8(hba)) {
		ret = ufshcd_uic_hibern8_exit(hba);
		ret = ufshcd_uic_hibern8_exit(hba);
		if (!ret) {
		if (!ret) {
@@ -10340,6 +10356,9 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
out:
out:
	hba->pm_op_in_progress = 0;
	hba->pm_op_in_progress = 0;


	if (hba->restore)
		hba->restore = false;

	if (ret)
	if (ret)
		ufshcd_update_error_stats(hba, UFS_ERR_RESUME);
		ufshcd_update_error_stats(hba, UFS_ERR_RESUME);


@@ -10502,6 +10521,25 @@ int ufshcd_runtime_idle(struct ufs_hba *hba)
}
}
EXPORT_SYMBOL(ufshcd_runtime_idle);
EXPORT_SYMBOL(ufshcd_runtime_idle);


int ufshcd_system_freeze(struct ufs_hba *hba)
{
	return ufshcd_system_suspend(hba);
}
EXPORT_SYMBOL(ufshcd_system_freeze);

int ufshcd_system_restore(struct ufs_hba *hba)
{
	hba->restore = true;
	return ufshcd_system_resume(hba);
}
EXPORT_SYMBOL(ufshcd_system_restore);

int ufshcd_system_thaw(struct ufs_hba *hba)
{
	return ufshcd_system_resume(hba);
}
EXPORT_SYMBOL(ufshcd_system_thaw);

static inline ssize_t ufshcd_pm_lvl_store(struct device *dev,
static inline ssize_t ufshcd_pm_lvl_store(struct device *dev,
					   struct device_attribute *attr,
					   struct device_attribute *attr,
					   const char *buf, size_t count,
					   const char *buf, size_t count,
+8 −1
Original line number Original line Diff line number Diff line
@@ -3,7 +3,7 @@
 *
 *
 * This code is based on drivers/scsi/ufs/ufshcd.h
 * This code is based on drivers/scsi/ufs/ufshcd.h
 * Copyright (C) 2011-2013 Samsung India Software Operations
 * Copyright (C) 2011-2013 Samsung India Software Operations
 * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
 *
 *
 * Authors:
 * Authors:
 *	Santosh Yaraganavi <santosh.sy@samsung.com>
 *	Santosh Yaraganavi <santosh.sy@samsung.com>
@@ -112,11 +112,13 @@ enum ufs_pm_op {
	UFS_RUNTIME_PM,
	UFS_RUNTIME_PM,
	UFS_SYSTEM_PM,
	UFS_SYSTEM_PM,
	UFS_SHUTDOWN_PM,
	UFS_SHUTDOWN_PM,
	UFS_SYSTEM_RESTORE,
};
};


#define ufshcd_is_runtime_pm(op) ((op) == UFS_RUNTIME_PM)
#define ufshcd_is_runtime_pm(op) ((op) == UFS_RUNTIME_PM)
#define ufshcd_is_system_pm(op) ((op) == UFS_SYSTEM_PM)
#define ufshcd_is_system_pm(op) ((op) == UFS_SYSTEM_PM)
#define ufshcd_is_shutdown_pm(op) ((op) == UFS_SHUTDOWN_PM)
#define ufshcd_is_shutdown_pm(op) ((op) == UFS_SHUTDOWN_PM)
#define ufshcd_is_restore(op) ((op) == UFS_SYSTEM_RESTORE)


/* Host <-> Device UniPro Link state */
/* Host <-> Device UniPro Link state */
enum uic_link_state {
enum uic_link_state {
@@ -1042,6 +1044,8 @@ struct ufs_hba {


	bool reinit_g4_rate_A;
	bool reinit_g4_rate_A;
	bool force_g4;
	bool force_g4;
	/* distinguish between resume and restore */
	bool restore;
};
};


static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba)
static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba)
@@ -1171,6 +1175,9 @@ static inline bool ufshcd_keep_autobkops_enabled_except_suspend(
	return hba->caps & UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND;
	return hba->caps & UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND;
}
}


extern int ufshcd_system_thaw(struct ufs_hba *hba);
extern int ufshcd_system_restore(struct ufs_hba *hba);
extern int ufshcd_system_freeze(struct ufs_hba *hba);
extern int ufshcd_runtime_suspend(struct ufs_hba *hba);
extern int ufshcd_runtime_suspend(struct ufs_hba *hba);
extern int ufshcd_runtime_resume(struct ufs_hba *hba);
extern int ufshcd_runtime_resume(struct ufs_hba *hba);
extern int ufshcd_runtime_idle(struct ufs_hba *hba);
extern int ufshcd_runtime_idle(struct ufs_hba *hba);