2020-10-30 01:55:55

by Bhaumik Bhatt

[permalink] [raw]
Subject: [PATCH v2 00/12] Bug fixes and improvements for MHI power operations

v2:
-Addressed patches based on review comments and made improvements
-Added bus: mhi: core: Check for IRQ availability during registration
-Dropped bus: mhi: core: Use the IRQF_ONESHOT flag for the BHI interrupt line
-Split bus: mhi: core: Move to an error state on any firmware load failure
-Modified the following patches:
-bus: mhi: core: Disable IRQs when powering down
-bus: mhi: core: Improve shutdown handling after link down detection
-bus: mhi: core: Mark device inactive soon after host issues a shutdown
-bus: mhi: core: Move to SYS_ERROR regardless of RDDM capability
-Addressed the above as follow-up patches with improvements:
-bus: mhi: core: Prevent sending multiple RDDM entry callbacks
-bus: mhi: core: Separate system error and power down handling
-bus: mhi: core: Remove MHI event ring IRQ handlers when powering down

Bug fixes and improvements for MHI powerup and shutdown handling.
Firmware load function names are updated to accurately reflect their purpose.
Closed certain design gaps where the host (MHI bus) would allow clients to
operate after a power down or error detection.
Move to an error state sooner based on different scenarios.

These patches were tested on arm64 and X86_64 architectures.

Bhaumik Bhatt (12):
bus: mhi: core: Use appropriate names for firmware load functions
bus: mhi: core: Move to using high priority workqueue
bus: mhi: core: Skip device wake in error or shutdown states
bus: mhi: core: Move to SYS_ERROR regardless of RDDM capability
bus: mhi: core: Prevent sending multiple RDDM entry callbacks
bus: mhi: core: Move to an error state on any firmware load failure
bus: mhi: core: Use appropriate label in firmware load handler API
bus: mhi: core: Move to an error state on mission mode failure
bus: mhi: core: Check for IRQ availability during registration
bus: mhi: core: Separate system error and power down handling
bus: mhi: core: Mark and maintain device states early on after power
down
bus: mhi: core: Remove MHI event ring IRQ handlers when powering down

drivers/bus/mhi/core/boot.c | 60 ++++++-----
drivers/bus/mhi/core/init.c | 10 +-
drivers/bus/mhi/core/main.c | 16 +--
drivers/bus/mhi/core/pm.c | 236 ++++++++++++++++++++++++++++++++------------
include/linux/mhi.h | 2 +
5 files changed, 225 insertions(+), 99 deletions(-)

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


2020-10-30 01:55:56

by Bhaumik Bhatt

[permalink] [raw]
Subject: [PATCH v2 01/12] bus: mhi: core: Use appropriate names for firmware load functions

mhi_fw_load_sbl() function is currently used to transfer SBL or EDL
images over BHI (Boot Host Interface). Same goes with mhi_fw_load_amss()
which uses BHIe. However, the contents of these functions do not
indicate support for a specific set of images. Since these can be used
for any image download over BHI or BHIe, rename them based on the
protocol used.

Signed-off-by: Bhaumik Bhatt <[email protected]>
---
drivers/bus/mhi/core/boot.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/bus/mhi/core/boot.c b/drivers/bus/mhi/core/boot.c
index 24422f5..7d6b3a7 100644
--- a/drivers/bus/mhi/core/boot.c
+++ b/drivers/bus/mhi/core/boot.c
@@ -171,7 +171,7 @@ int mhi_download_rddm_img(struct mhi_controller *mhi_cntrl, bool in_panic)
}
EXPORT_SYMBOL_GPL(mhi_download_rddm_img);

-static int mhi_fw_load_amss(struct mhi_controller *mhi_cntrl,
+static int mhi_fw_load_bhie(struct mhi_controller *mhi_cntrl,
const struct mhi_buf *mhi_buf)
{
void __iomem *base = mhi_cntrl->bhie;
@@ -187,7 +187,7 @@ static int mhi_fw_load_amss(struct mhi_controller *mhi_cntrl,
}

sequence_id = MHI_RANDOM_U32_NONZERO(BHIE_TXVECSTATUS_SEQNUM_BMSK);
- dev_dbg(dev, "Starting AMSS download via BHIe. Sequence ID:%u\n",
+ dev_dbg(dev, "Starting image download via BHIe. Sequence ID: %u\n",
sequence_id);
mhi_write_reg(mhi_cntrl, base, BHIE_TXVECADDR_HIGH_OFFS,
upper_32_bits(mhi_buf->dma_addr));
@@ -218,7 +218,7 @@ static int mhi_fw_load_amss(struct mhi_controller *mhi_cntrl,
return (!ret) ? -ETIMEDOUT : 0;
}

-static int mhi_fw_load_sbl(struct mhi_controller *mhi_cntrl,
+static int mhi_fw_load_bhi(struct mhi_controller *mhi_cntrl,
dma_addr_t dma_addr,
size_t size)
{
@@ -245,7 +245,7 @@ static int mhi_fw_load_sbl(struct mhi_controller *mhi_cntrl,
}

session_id = MHI_RANDOM_U32_NONZERO(BHI_TXDB_SEQNUM_BMSK);
- dev_dbg(dev, "Starting SBL download via BHI. Session ID:%u\n",
+ dev_dbg(dev, "Starting image download via BHI. Session ID: %u\n",
session_id);
mhi_write_reg(mhi_cntrl, base, BHI_STATUS, 0);
mhi_write_reg(mhi_cntrl, base, BHI_IMGADDR_HIGH,
@@ -446,9 +446,9 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
return;
}

- /* Download SBL image */
+ /* Download image using BHI */
memcpy(buf, firmware->data, size);
- ret = mhi_fw_load_sbl(mhi_cntrl, dma_addr, size);
+ ret = mhi_fw_load_bhi(mhi_cntrl, dma_addr, size);
mhi_free_coherent(mhi_cntrl, size, buf, dma_addr);

if (!mhi_cntrl->fbc_download || ret || mhi_cntrl->ee == MHI_EE_EDL)
@@ -456,7 +456,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)

/* Error or in EDL mode, we're done */
if (ret) {
- dev_err(dev, "MHI did not load SBL, ret:%d\n", ret);
+ dev_err(dev, "MHI did not load image over BHI, ret: %d\n", ret);
return;
}

@@ -506,11 +506,12 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)

/* Start full firmware image download */
image_info = mhi_cntrl->fbc_image;
- ret = mhi_fw_load_amss(mhi_cntrl,
+ ret = mhi_fw_load_bhie(mhi_cntrl,
/* Vector table is the last entry */
&image_info->mhi_buf[image_info->entries - 1]);
if (ret)
- dev_err(dev, "MHI did not load AMSS, ret:%d\n", ret);
+ dev_err(dev, "MHI did not load image over BHIe, ret: %d\n",
+ ret);

release_firmware(firmware);

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

2020-10-30 01:57:33

by Bhaumik Bhatt

[permalink] [raw]
Subject: [PATCH v2 04/12] bus: mhi: core: Move to SYS_ERROR regardless of RDDM capability

In some cases, the entry of device to RDDM execution environment
can occur after a significant amount of time has elapsed and a
SYS_ERROR state change event has already arrived. This can result
in scenarios where MHI controller and client drivers are unaware
of the error state of the device. Remove the check for rddm_image
when processing the SYS_ERROR state change as it is present in
mhi_pm_sys_err_handler() already and prevent further activity
until the expected RDDM execution environment change occurs or
the controller driver decides further action.

Signed-off-by: Bhaumik Bhatt <[email protected]>
---
drivers/bus/mhi/core/main.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c
index 2cff5dd..1f32d67 100644
--- a/drivers/bus/mhi/core/main.c
+++ b/drivers/bus/mhi/core/main.c
@@ -733,19 +733,15 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl,
break;
case MHI_STATE_SYS_ERR:
{
- enum mhi_pm_state new_state;
-
- /* skip SYS_ERROR handling if RDDM supported */
- if (mhi_cntrl->ee == MHI_EE_RDDM ||
- mhi_cntrl->rddm_image)
- break;
+ enum mhi_pm_state state = MHI_PM_STATE_MAX;

dev_dbg(dev, "System error detected\n");
write_lock_irq(&mhi_cntrl->pm_lock);
- new_state = mhi_tryset_pm_state(mhi_cntrl,
+ if (mhi_cntrl->ee != MHI_EE_RDDM)
+ state = mhi_tryset_pm_state(mhi_cntrl,
MHI_PM_SYS_ERR_DETECT);
write_unlock_irq(&mhi_cntrl->pm_lock);
- if (new_state == MHI_PM_SYS_ERR_DETECT)
+ if (state == MHI_PM_SYS_ERR_DETECT)
mhi_pm_sys_err_handler(mhi_cntrl);
break;
}
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project