[MIAMI] spi: spi-msm-geni: system suspend support

we are not serving system suspend if spi xfers were in progress, doing
force suspend if spi xfers were completed.

Port of patch spi_geni_fix2.patch provided by qcom in case 06677540

Change-Id: I929031556694abf77e78e573a6f56986dc8667e9
Reviewed-on: https://gerrit.mot.com/2697260
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Bruno Oliveira <brunosoe@motorola.com>
Reviewed-by: Rafael Ortolan <rafones@motorola.com>
Reviewed-by: Jun Weng <wengjun1@motorola.com>
Reviewed-by: Huosheng Liao <liaohs@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
Alison Venancio 2023-08-01 17:32:17 -04:00 • committed by Xiaojun Ji
commit 16c8d2ce9e
3 changed files with 47 additions and 7 deletions

View file

@ -28,3 +28,4 @@ CONFIG_QUP0_SE2_AP=y
CONFIG_CRYPTO_CHACHA20POLY1305=y
CONFIG_CAM_SENSOR_PROBE_RETRY=y
CONFIG_CAMERA_CCI_ADDR_SWITCH=y
CONFIG_IS_XFER_IN_PROGRESS=y

View file

@ -960,3 +960,8 @@ config SPI_DYNAMIC
def_bool ACPI || OF_DYNAMIC || SPI_SLAVE
endif # SPI
config IS_XFER_IN_PROGRESS
bool "Check if xfer is in progress"
help
Force suspend if spi xfers were completed.

View file

@ -164,6 +164,9 @@ struct spi_geni_master {
int num_rx_eot;
int num_xfers;
atomic_t is_irq_enable;
#ifdef CONFIG_IS_XFER_IN_PROGRESS
bool is_xfer_in_progress;
#endif
void *ipc;
bool gsi_mode; /* GSI Mode */
bool shared_ee; /* Dual EE use case */
@ -1006,7 +1009,7 @@ static int spi_geni_prepare_message(struct spi_master *spi,
if (mas->shared_ee) {
if (mas->setup) {
#if 0
#ifdef CONFIG_IS_XFER_IN_PROGRESS
/* Client to respect system suspend */
if (!pm_runtime_enabled(mas->dev)) {
GENI_SE_ERR(mas->ipc, false, NULL,
@ -1021,7 +1024,7 @@ static int spi_geni_prepare_message(struct spi_master *spi,
__func__, ret);
WARN_ON_ONCE(1);
pm_runtime_put_noidle(mas->dev);
#if 0
#ifdef CONFIG_IS_XFER_IN_PROGRESS
/* Set device in suspended since resume failed */
pm_runtime_set_suspended(mas->dev);
#endif
@ -1338,6 +1341,10 @@ static int spi_geni_prepare_transfer_hardware(struct spi_master *spi)
/* Adjust the IB based on the max speed of the slave in kHz.*/
rsc->ib = (max_speed * DEFAULT_BUS_WIDTH) / 1000;
#ifdef CONFIG_IS_XFER_IN_PROGRESS
mas->is_xfer_in_progress = true;
#endif
/*
* Not required for LE as below intializations are specific
* to usecases. For LE, client takes care of get_sync.
@ -1345,11 +1352,12 @@ static int spi_geni_prepare_transfer_hardware(struct spi_master *spi)
if (mas->is_le_vm)
return 0;
#if 0
#ifdef CONFIG_IS_XFER_IN_PROGRESS
/* Client to respect system suspend */
if (!pm_runtime_enabled(mas->dev)) {
GENI_SE_ERR(mas->ipc, false, NULL,
"%s: System suspended\n", __func__);
mas->is_xfer_in_progress = false;
return -EACCES;
}
#endif
@ -1385,9 +1393,10 @@ static int spi_geni_prepare_transfer_hardware(struct spi_master *spi)
__func__, ret);
WARN_ON_ONCE(1);
pm_runtime_put_noidle(mas->dev);
#if 0
#ifdef CONFIG_IS_XFER_IN_PROGRESS
/* Set device in suspended since resume failed */
pm_runtime_set_suspended(mas->dev);
mas->is_xfer_in_progress = false;
#endif
return ret;
}
@ -1397,6 +1406,9 @@ static int spi_geni_prepare_transfer_hardware(struct spi_master *spi)
if (ret) {
GENI_SE_ERR(mas->ipc, true, NULL,
"%s mas_setup failed: %d\n", __func__, ret);
#ifdef CONFIG_IS_XFER_IN_PROGRESS
mas->is_xfer_in_progress = false;
#endif
return ret;
}
}
@ -1418,8 +1430,12 @@ static int spi_geni_unprepare_transfer_hardware(struct spi_master *spi)
struct spi_geni_master *mas = spi_master_get_devdata(spi);
int count = 0;
if (mas->shared_ee || mas->is_le_vm)
if (mas->shared_ee || mas->is_le_vm) {
#ifdef CONFIG_IS_XFER_IN_PROGRESS
mas->is_xfer_in_progress = false;
#endif
return 0;
}
if (mas->gsi_mode) {
struct se_geni_rsc *rsc;
@ -1448,6 +1464,9 @@ static int spi_geni_unprepare_transfer_hardware(struct spi_master *spi)
pm_runtime_mark_last_busy(mas->dev);
pm_runtime_put_autosuspend(mas->dev);
}
#ifdef CONFIG_IS_XFER_IN_PROGRESS
mas->is_xfer_in_progress = false;
#endif
return 0;
}
@ -1674,7 +1693,7 @@ static int spi_geni_transfer_one(struct spi_master *spi,
GENI_SE_DBG(mas->ipc, false, mas->dev,
"current xfer_timeout:%lu ms.\n", xfer_timeout);
#if 0
#ifdef CONFIG_IS_XFER_IN_PROGRESS
/* Double check PM status, client might have not taken wakelock and
* continue to queue more transfers. Post auto-suspend, system suspend
* can keep driver to forced suspend, hence it's client's responsibility
@ -2221,6 +2240,9 @@ static int spi_geni_probe(struct platform_device *pdev)
"M - DRIVER GENI_SPI_%d Ready", spi->bus_num);
place_marker(boot_marker);
dev_info(&pdev->dev, "%s: completed\n", __func__);
#ifdef CONFIG_IS_XFER_IN_PROGRESS
geni_mas->is_xfer_in_progress = false;
#endif
return ret;
spi_geni_probe_unmap:
devm_iounmap(&pdev->dev, geni_mas->base);
@ -2329,11 +2351,23 @@ static int spi_geni_suspend(struct device *dev)
int ret = 0;
struct spi_master *spi = get_spi_master(dev);
struct spi_geni_master *geni_mas = spi_master_get_devdata(spi);
#ifdef CONFIG_IS_XFER_IN_PROGRESS
if (geni_mas->is_xfer_in_progress) {
ret = -EBUSY;
if (!pm_runtime_status_suspended(dev)) {
GENI_SE_ERR(geni_mas->ipc, true, dev,
":%s: runtime PM is active\n", __func__);
return ret;
}
GENI_SE_ERR(geni_mas->ipc, true, dev,
"%s System suspend not allowed while xfer in progress\n",
__func__);
#else
if (!pm_runtime_status_suspended(dev)) {
GENI_SE_ERR(geni_mas->ipc, true, dev,
":%s: runtime PM is active\n", __func__);
ret = -EBUSY;
#endif
return ret;
}