From 04d4e7ae5cd3cf956adbbb33d893e207d716c0fb Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Tue, 16 Jun 2020 15:01:41 -0700 Subject: [PATCH 01/34] bus: mhi: host: Add support for processing of sleepable events Processing of some events requires the use of a sleeping function. In order to handle those events, work is queued using high priority workqueue. Sleepable events also require use of a dedicated event ring. Replaced 'TO_MHI_STATE_STR' with 'mhi_state_str' to aid in compilation. Change-Id: I3c42bc5b33b179de79911f8ec21b9a351116a112 Signed-off-by: Hemant Kumar Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/init.c | 10 +++++--- drivers/bus/mhi/host/internal.h | 3 +++ drivers/bus/mhi/host/main.c | 45 +++++++++++++++++++++++++++++++++ drivers/bus/mhi/host/pm.c | 15 +++++++++-- include/linux/mhi.h | 2 ++ 5 files changed, 69 insertions(+), 6 deletions(-) diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index cc31ed191943..cb57f23f7875 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -946,11 +946,13 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl, mhi_event->mhi_cntrl = mhi_cntrl; spin_lock_init(&mhi_event->lock); - if (mhi_event->data_type == MHI_ER_CTRL) - tasklet_init(&mhi_event->task, mhi_ctrl_ev_task, - (ulong)mhi_event); + + if (mhi_event->priority == MHI_ER_PRIORITY_HI_SLEEP) + INIT_WORK(&mhi_event->work, mhi_process_ev_work); else - tasklet_init(&mhi_event->task, mhi_ev_task, + tasklet_init(&mhi_event->task, + (mhi_event->data_type == MHI_ER_CTRL) ? + mhi_ctrl_ev_task : mhi_ev_task, (ulong)mhi_event); } diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index 78c33c00393c..b88330658270 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -201,6 +201,7 @@ struct mhi_event { struct mhi_ring ring; struct db_cfg db_cfg; struct tasklet_struct task; + struct work_struct work; spinlock_t lock; int (*process_event)(struct mhi_controller *mhi_cntrl, struct mhi_event *mhi_event, @@ -359,6 +360,8 @@ void mhi_reset_chan(struct mhi_controller *mhi_cntrl, /* Event processing methods */ void mhi_ctrl_ev_task(unsigned long data); void mhi_ev_task(unsigned long data); +void mhi_process_ev_work(struct work_struct *work); +void mhi_process_sleeping_events(struct mhi_controller *mhi_cntrl); int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl, struct mhi_event *mhi_event, u32 event_quota); int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 116f86685851..ec9c7e12f9ba 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -426,6 +426,30 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl) } } +void mhi_process_sleeping_events(struct mhi_controller *mhi_cntrl) +{ + struct mhi_event *mhi_event; + struct mhi_event_ctxt *er_ctxt; + struct mhi_ring *ev_ring; + int i; + + mhi_event = mhi_cntrl->mhi_event; + for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { + if (mhi_event->offload_ev || mhi_event->priority != + MHI_ER_PRIORITY_HI_SLEEP) + continue; + + er_ctxt = &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index]; + ev_ring = &mhi_event->ring; + + /* Only proceed if event ring has pending events */ + if (ev_ring->rp == mhi_to_virtual(ev_ring, er_ctxt->rp)) + continue; + + queue_work(mhi_cntrl->hiprio_wq, &mhi_event->work); + } +} + irqreturn_t mhi_irq_handler(int irq_number, void *priv) { struct mhi_event *mhi_event = priv; @@ -467,6 +491,9 @@ irqreturn_t mhi_irq_handler(int irq_number, void *priv) case MHI_ER_PRIORITY_DEFAULT_NOSLEEP: tasklet_schedule(&mhi_event->task); break; + case MHI_ER_PRIORITY_HI_SLEEP: + queue_work(mhi_cntrl->hiprio_wq, &mhi_event->work); + break; default: dev_dbg(dev, "skip unknown priority event\n"); break; @@ -1095,6 +1122,24 @@ void mhi_ctrl_ev_task(unsigned long data) } } +void mhi_process_ev_work(struct work_struct *work) +{ + struct mhi_event *mhi_event = container_of(work, struct mhi_event, + work); + struct mhi_controller *mhi_cntrl = mhi_event->mhi_cntrl; + struct device *dev = mhi_cntrl->cntrl_dev; + + dev_dbg(dev, "Enter with pm_state:%s MHI_STATE:%s ee:%s\n", + to_mhi_pm_state_str(mhi_cntrl->pm_state), + mhi_state_str(mhi_cntrl->dev_state), + TO_MHI_EXEC_STR(mhi_cntrl->ee)); + + if (unlikely(MHI_EVENT_ACCESS_INVALID(mhi_cntrl->pm_state))) + return; + + mhi_event->process_event(mhi_cntrl, mhi_event, U32_MAX); +} + static bool mhi_is_ring_full(struct mhi_controller *mhi_cntrl, struct mhi_ring *ring) { diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index cda374bfc9ef..03c6a3529127 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -432,6 +432,8 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) read_unlock_bh(&mhi_cntrl->pm_lock); + mhi_process_sleeping_events(mhi_cntrl); + /* * The MHI devices are only created when the client device switches its * Execution Environment (EE) to either SBL or AMSS states @@ -497,7 +499,10 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) if (mhi_event->offload_ev) continue; disable_irq(mhi_cntrl->irq[mhi_event->irq]); - tasklet_kill(&mhi_event->task); + if (mhi_event->priority == MHI_ER_PRIORITY_HI_SLEEP) + cancel_work_sync(&mhi_event->work); + else + tasklet_kill(&mhi_event->task); } /* Release lock and wait for all pending threads to complete */ @@ -630,7 +635,10 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { if (mhi_event->offload_ev) continue; - tasklet_kill(&mhi_event->task); + if (mhi_event->priority == MHI_ER_PRIORITY_HI_SLEEP) + cancel_work_sync(&mhi_event->work); + else + tasklet_kill(&mhi_event->task); } /* Release lock and wait for all pending threads to complete */ @@ -766,6 +774,9 @@ void mhi_pm_st_worker(struct work_struct *work) write_lock_irq(&mhi_cntrl->pm_lock); mhi_cntrl->ee = MHI_EE_SBL; write_unlock_irq(&mhi_cntrl->pm_lock); + + mhi_process_sleeping_events(mhi_cntrl); + /* * The MHI devices are only created when the client * device switches its Execution Environment (EE) to diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 7c182fda4d7c..3dc3ef2bca65 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -202,10 +202,12 @@ enum mhi_er_data_type { * enum mhi_er_priority - Event ring processing priority * @MHI_ER_PRIORITY_DEFAULT_NOSLEEP: processed by tasklet * @MHI_ER_PRIORITY_HI_NOSLEEP: processed by hi-priority tasklet + * @MHI_ER_PRIORITY_HI_SLEEP: processed by hi-priority wq */ enum mhi_er_priority { MHI_ER_PRIORITY_DEFAULT_NOSLEEP, MHI_ER_PRIORITY_HI_NOSLEEP, + MHI_ER_PRIORITY_HI_SLEEP, }; /** From 6375f3b44a6ca22eff7f815873c1d89f6c647ec7 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 18 Dec 2020 11:26:10 -0800 Subject: [PATCH 02/34] bus: mhi: host: Add session ID to MHI controller Session ID to be used during BHI transfers to recognize a particular session are currently not being stored in the MHI controller structure. Store them to allow for tracking and other future usage. Change-Id: I45a55f39226be3a21ff1e3317a899da1a63f3439 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/boot.c | 8 ++++---- include/linux/mhi.h | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index c712a2654aec..7c24f2c822b7 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -185,7 +185,7 @@ static int mhi_fw_load_bhie(struct mhi_controller *mhi_cntrl, void __iomem *base = mhi_cntrl->bhie; struct device *dev = &mhi_cntrl->mhi_dev->dev; rwlock_t *pm_lock = &mhi_cntrl->pm_lock; - u32 tx_status, sequence_id; + u32 tx_status; int ret; read_lock_bh(pm_lock); @@ -194,9 +194,9 @@ static int mhi_fw_load_bhie(struct mhi_controller *mhi_cntrl, return -EIO; } - sequence_id = MHI_RANDOM_U32_NONZERO(BHIE_TXVECSTATUS_SEQNUM_BMSK); + mhi_cntrl->session_id = MHI_RANDOM_U32_NONZERO(BHIE_TXVECSTATUS_SEQNUM_BMSK); dev_dbg(dev, "Starting image download via BHIe. Sequence ID: %u\n", - sequence_id); + mhi_cntrl->session_id); mhi_write_reg(mhi_cntrl, base, BHIE_TXVECADDR_HIGH_OFFS, upper_32_bits(mhi_buf->dma_addr)); @@ -206,7 +206,7 @@ static int mhi_fw_load_bhie(struct mhi_controller *mhi_cntrl, mhi_write_reg(mhi_cntrl, base, BHIE_TXVECSIZE_OFFS, mhi_buf->len); ret = mhi_write_reg_field(mhi_cntrl, base, BHIE_TXVECDB_OFFS, - BHIE_TXVECDB_SEQNUM_BMSK, sequence_id); + BHIE_TXVECDB_SEQNUM_BMSK, mhi_cntrl->session_id); read_unlock_bh(pm_lock); if (ret) diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 3dc3ef2bca65..bac68bbd7f68 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -429,6 +429,7 @@ struct mhi_controller { u32 minor_version; u32 serial_number; u32 oem_pk_hash[MHI_MAX_OEM_PK_HASH_SEGMENTS]; + u32 session_id; struct mhi_event *mhi_event; struct mhi_cmd *mhi_cmd; From 37cdc4bc4f59a47bf1ee9308768ffcf2abd37040 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Tue, 22 Dec 2020 11:49:22 -0800 Subject: [PATCH 03/34] bus: mhi: host: Introduce and use fast suspend counter MHI fast suspend state change counter can be used to track the number of times device enters the state. Introduce and use it for accurate tracking of MHI low power states. Change-Id: Ibaa0428d5ba13b7776a0c9af58a357f59bb9eda5 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/debugfs.c | 4 ++-- include/linux/mhi.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/bus/mhi/host/debugfs.c b/drivers/bus/mhi/host/debugfs.c index cfec7811dfbb..55dd7375c06f 100644 --- a/drivers/bus/mhi/host/debugfs.c +++ b/drivers/bus/mhi/host/debugfs.c @@ -25,8 +25,8 @@ static int mhi_debugfs_states_show(struct seq_file *m, void *d) mhi_cntrl->wake_set ? "true" : "false"); /* counters */ - seq_printf(m, "M0: %u M2: %u M3: %u", mhi_cntrl->M0, mhi_cntrl->M2, - mhi_cntrl->M3); + seq_printf(m, "M0: %u M2: %u M3: %u, M3_fast: %u", mhi_cntrl->M0, + mhi_cntrl->M2, mhi_cntrl->M3, mhi_cntrl->M3_fast); seq_printf(m, " device wake: %u pending packets: %u\n", atomic_read(&mhi_cntrl->dev_wake), diff --git a/include/linux/mhi.h b/include/linux/mhi.h index bac68bbd7f68..3ba339d087b8 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -354,7 +354,7 @@ struct mhi_controller_config { * @dev_state: MHI device state * @dev_wake: Device wakeup count * @pending_pkts: Pending packets for the controller - * @M0, M2, M3: Counters to track number of device MHI state changes + * @M0, M2, M3, M3_fast: Counters to track number of device MHI state changes * @transition_list: List of MHI state transitions * @transition_lock: Lock for protecting MHI state transition list * @wlock: Lock for protecting device wakeup @@ -444,7 +444,7 @@ struct mhi_controller { enum mhi_state dev_state; atomic_t dev_wake; atomic_t pending_pkts; - u32 M0, M2, M3; + u32 M0, M2, M3, M3_fast; struct list_head transition_list; spinlock_t transition_lock; spinlock_t wlock; From d11c150a81f00d42482920466395ce027c45d1cf Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Mon, 28 Dec 2020 18:32:58 -0800 Subject: [PATCH 04/34] bus: mhi: host: Use parent device to request firmware Parent device must be used to request firmware from the file- system otherwise the request does not go through. Make these necessary changes to allow boot-up for all MHI controllers. Change-Id: Ia78398c5d2d472a2f6f7e3e652f62b75927bd379 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/boot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 7c24f2c822b7..4383bfc5598c 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -441,7 +441,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) goto error_fw_load; } - ret = request_firmware(&firmware, fw_name, dev); + ret = request_firmware(&firmware, fw_name, dev->parent); if (ret) { if (!mhi_cntrl->fallback_fw_image) { dev_err(dev, "Error loading firmware: %d\n", ret); @@ -450,7 +450,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) ret = request_firmware(&firmware, mhi_cntrl->fallback_fw_image, - dev); + dev->parent); if (ret) { dev_err(dev, "Error loading fallback firmware: %d\n", ret); From bd9e89fec71bcb5f60f23608649671566579ccb4 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Tue, 19 Jan 2021 15:58:09 -0800 Subject: [PATCH 05/34] bus: mhi: host: Add UL and DL event ring IDs to MHI device Offload channels where the client drivers manage their own context information need event ring information in the MHI device structure that is currently not exposed to them. Add those to enable these drivers to function properly. Change-Id: Icc80344518591ca74c75ab932ac15eca9a77d0ad Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/main.c | 6 +++++- include/linux/mhi.h | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index ec9c7e12f9ba..0dc847c18191 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * */ @@ -378,11 +378,13 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl) case DMA_TO_DEVICE: mhi_dev->ul_chan = mhi_chan; mhi_dev->ul_chan_id = mhi_chan->chan; + mhi_dev->ul_event_id = mhi_chan->er_index; break; case DMA_FROM_DEVICE: /* We use dl_chan as offload channels */ mhi_dev->dl_chan = mhi_chan; mhi_dev->dl_chan_id = mhi_chan->chan; + mhi_dev->dl_event_id = mhi_chan->er_index; break; default: dev_err(dev, "Direction not supported\n"); @@ -401,9 +403,11 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl) if (mhi_chan->dir == DMA_TO_DEVICE) { mhi_dev->ul_chan = mhi_chan; mhi_dev->ul_chan_id = mhi_chan->chan; + mhi_dev->ul_event_id = mhi_chan->er_index; } else { mhi_dev->dl_chan = mhi_chan; mhi_dev->dl_chan_id = mhi_chan->chan; + mhi_dev->dl_event_id = mhi_chan->er_index; } get_device(&mhi_dev->dev); mhi_chan->mhi_dev = mhi_dev; diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 3ba339d087b8..a2b2bc7b59c5 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -491,7 +491,9 @@ struct mhi_controller { * @dev: Driver model device node for the MHI device * @dev_type: MHI device type * @ul_chan_id: MHI channel id for UL transfer + * @ul_event_id: MHI event ring id for UL transfer * @dl_chan_id: MHI channel id for DL transfer + * @ul_event_id: MHI event ring id for DL transfer * @dev_wake: Device wakeup counter */ struct mhi_device { @@ -503,7 +505,9 @@ struct mhi_device { struct device dev; enum mhi_device_type dev_type; int ul_chan_id; + int ul_event_id; int dl_chan_id; + int dl_event_id; u32 dev_wake; }; From 141a2b8fb2af6540ce1e22c7779513d79c38edb6 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 29 Jan 2021 01:27:47 -0800 Subject: [PATCH 06/34] bus: mhi: host: Add support for subsystem failure reason Add support for controllers to enable retrieval of the subsystem failure reason if an error from device is reported. Change-Id: I27d88ceaeeb512fc578b78bcf85e7ba7cb27a4ff Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/common.h | 1 + drivers/bus/mhi/host/main.c | 11 +++++++++++ drivers/bus/mhi/host/pm.c | 5 ++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h index f794b9c8049e..da2f1214f2eb 100644 --- a/drivers/bus/mhi/common.h +++ b/drivers/bus/mhi/common.h @@ -250,6 +250,7 @@ enum mhi_cmd_type { MHI_CMD_RESET_CHAN = 16, MHI_CMD_STOP_CHAN = 17, MHI_CMD_START_CHAN = 18, + MHI_CMD_SFR_CFG = 73, }; #define EV_CTX_RESERVED_MASK GENMASK(7, 0) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 0dc847c18191..9e127a060dac 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -812,6 +812,12 @@ static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl, cmd_pkt = mhi_to_virtual(mhi_ring, ptr); + if (MHI_TRE_GET_CMD_TYPE(cmd_pkt) == MHI_CMD_SFR_CFG) { + mhi_misc_cmd_completion(mhi_cntrl, MHI_CMD_SFR_CFG, + MHI_TRE_GET_EV_CODE(tre)); + return; + } + chan = MHI_TRE_GET_CMD_CHID(cmd_pkt); if (chan < mhi_cntrl->max_chan && @@ -1349,6 +1355,11 @@ int mhi_send_cmd(struct mhi_controller *mhi_cntrl, cmd_tre->dword[0] = MHI_TRE_CMD_START_DWORD0; cmd_tre->dword[1] = MHI_TRE_CMD_START_DWORD1(chan); break; + case MHI_CMD_SFR_CFG: + mhi_misc_cmd_configure(mhi_cntrl, MHI_CMD_SFR_CFG, + &cmd_tre->ptr, &cmd_tre->dword[0], + &cmd_tre->dword[1]); + break; default: dev_err(dev, "Command not supported\n"); break; diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index 03c6a3529127..0121557f9855 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * */ @@ -432,6 +432,7 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) read_unlock_bh(&mhi_cntrl->pm_lock); + mhi_misc_mission_mode(mhi_cntrl); mhi_process_sleeping_events(mhi_cntrl); /* @@ -507,6 +508,7 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) /* Release lock and wait for all pending threads to complete */ mutex_unlock(&mhi_cntrl->pm_mutex); + mhi_misc_disable(mhi_cntrl); dev_dbg(dev, "Waiting for all pending threads to complete\n"); wake_up_all(&mhi_cntrl->state_event); @@ -643,6 +645,7 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) /* Release lock and wait for all pending threads to complete */ mutex_unlock(&mhi_cntrl->pm_mutex); + mhi_misc_disable(mhi_cntrl); dev_dbg(dev, "Waiting for all pending threads to complete\n"); wake_up_all(&mhi_cntrl->state_event); From 9446d19cc3029192f175d5fc4ac980621e347cde Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 22 Jan 2021 10:52:03 -0800 Subject: [PATCH 07/34] bus: mhi: Add support for MHI DTR signaling driver DTR signaling client driver needs certain entries in the MHI device structure and an mhi_callback entry. Add those to support DTR signaling. Change-Id: Id74395348200e84bc9af0b251799c06eeb738193 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- include/linux/mhi.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/mhi.h b/include/linux/mhi.h index a2b2bc7b59c5..faac0044bd96 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -38,6 +38,7 @@ struct mhi_buf_info; * @MHI_CB_FATAL_ERROR: MHI device entered fatal error state * @MHI_CB_BW_REQ: Received a bandwidth switch request from device * @MHI_CB_FALLBACK_IMG: MHI device was loaded with the provided fallback image + * @MHI_CB_DTR_SIGNAL: DTR signaling update */ enum mhi_callback { MHI_CB_IDLE, @@ -50,6 +51,7 @@ enum mhi_callback { MHI_CB_FATAL_ERROR, MHI_CB_BW_REQ, MHI_CB_FALLBACK_IMG, + MHI_CB_DTR_SIGNAL, }; /** @@ -495,6 +497,7 @@ struct mhi_controller { * @dl_chan_id: MHI channel id for DL transfer * @ul_event_id: MHI event ring id for DL transfer * @dev_wake: Device wakeup counter + * @tiocm: Device current terminal settings */ struct mhi_device { const struct mhi_device_id *id; @@ -509,6 +512,7 @@ struct mhi_device { int dl_chan_id; int dl_event_id; u32 dev_wake; + u32 tiocm; }; /** From b7f5b28137950688a8d23bd3a3b6e691f540e852 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 29 Jan 2021 17:20:13 -0800 Subject: [PATCH 08/34] bus: mhi: host: Enable use of time synchronization misc feature Allow the miscellaneous driver to use the time synchronization feature by providing core support. Change-Id: I63cad0be5f303f07dc785862d48dc64d2ca0c33b Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/init.c | 3 +++ include/linux/mhi.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index cb57f23f7875..7e830b9a0e95 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -712,6 +712,9 @@ static int parse_ev_cfg(struct mhi_controller *mhi_cntrl, case MHI_ER_BW_SCALE: mhi_event->process_event = mhi_process_misc_bw_ev_ring; break; + case MHI_ER_TIMESYNC: + mhi_event->process_event = mhi_process_misc_tsync_ev_ring; + break; default: dev_err(dev, "Event Ring type not supported\n"); goto error_ev_cfg; diff --git a/include/linux/mhi.h b/include/linux/mhi.h index faac0044bd96..c587a250a4e6 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -193,11 +193,13 @@ enum mhi_ch_ee_mask { * @MHI_ER_DATA: Only client data over this ring * @MHI_ER_CTRL: MHI control data and client data * @MHI_ER_BW_SCALE: MHI controller bandwidth scale functionality + * @MHI_ER_TIMESYNC: MHI controller time synchronization DB mode functionality */ enum mhi_er_data_type { MHI_ER_DATA, MHI_ER_CTRL, MHI_ER_BW_SCALE, + MHI_ER_TIMESYNC, }; /** From 4056a947ac99226c40e35aa2b491028f6e379f5b Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Mon, 4 Apr 2022 10:23:50 -0700 Subject: [PATCH 09/34] bus: mhi: host: Fix DTR MHI dev pointer and circular dependency There is a typo and a wrong struct type was used for the DTR driver features. Update it and use the correct mhi_device type in place of the dtr_device pointer. Also fix a circular dependency on DTR and MHI misc by using the traditional status callback route to notify the DTR client driver. Changes for misc.c,mhi_misc.h are already present in commit f1f4164c4f15 ("bus: mhi: host: Add snapshot of MHI bus misc driver"), and for mhi_dtr.c in commit 0ff9eadd9cb2 ("bus: mhi: devices: Add snapshot of MHI devices driver"). Change-Id: I877d0ed009bbde30605bbd306deaf53588f1611f Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- include/linux/mhi.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/mhi.h b/include/linux/mhi.h index c587a250a4e6..470f27326a66 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -39,6 +39,7 @@ struct mhi_buf_info; * @MHI_CB_BW_REQ: Received a bandwidth switch request from device * @MHI_CB_FALLBACK_IMG: MHI device was loaded with the provided fallback image * @MHI_CB_DTR_SIGNAL: DTR signaling update + * @MHI_CB_DTR_START_CHANNELS: DTR signal for client driver to start channels */ enum mhi_callback { MHI_CB_IDLE, @@ -52,6 +53,7 @@ enum mhi_callback { MHI_CB_BW_REQ, MHI_CB_FALLBACK_IMG, MHI_CB_DTR_SIGNAL, + MHI_CB_DTR_START_CHANNELS, }; /** From bf693df5a081b711b2049ba52c6bec866b74ca35 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Mon, 19 Apr 2021 13:08:42 -0700 Subject: [PATCH 10/34] bus: mhi: host: Log data and control events for debug Certain log messages will help improve the debug experience when attempting to solve issues related to tracking data or control packets in MHI. Add logs to improve this aspect. Change-Id: Ic8608d68e37436b23e7c2364cb9e38db22c3844f Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 9e127a060dac..c5172a68db5d 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -869,6 +869,9 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, while (dev_rp != local_rp) { enum mhi_pkt_type type = MHI_TRE_GET_EV_TYPE(local_rp); + dev_dbg(dev, "Processing Event:0x%llx 0x%08x 0x%08x\n", + local_rp->ptr, local_rp->dword[0], local_rp->dword[1]); + switch (type) { case MHI_PKT_TYPE_BW_REQ_EVENT: { @@ -1013,6 +1016,7 @@ int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl, struct mhi_ring *ev_ring = &mhi_event->ring; struct mhi_event_ctxt *er_ctxt = &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index]; + struct device *dev = &mhi_cntrl->mhi_dev->dev; int count = 0; u32 chan; struct mhi_chan *mhi_chan; @@ -1033,6 +1037,9 @@ int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl, while (dev_rp != local_rp && event_quota > 0) { enum mhi_pkt_type type = MHI_TRE_GET_EV_TYPE(local_rp); + dev_dbg(dev, "Processing Event:0x%llx 0x%08x 0x%08x\n", + local_rp->ptr, local_rp->dword[0], local_rp->dword[1]); + chan = MHI_TRE_GET_EV_CHID(local_rp); WARN_ON(chan >= mhi_cntrl->max_chan); From b5c5f9c659a0d34c2f5b683446975b4d358955d7 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Mon, 19 Apr 2021 16:02:01 -0700 Subject: [PATCH 11/34] bus: mhi: host: Panic or exit on certain use cases Add missing checks in the MHI core driver to panic on certain use cases such as a bad or malformed TRE or unexpected states and exit from out of order command completions. Change-Id: I873ed04c4fce57b1ec42175666ffadd496ad3fdf Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/main.c | 10 ++++++++-- drivers/bus/mhi/host/pm.c | 8 ++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index c5172a68db5d..827ce89b2cd1 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -717,7 +717,7 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl, } case MHI_EV_CC_BAD_TRE: default: - dev_err(dev, "Unknown event 0x%x\n", ev_code); + panic("Unknown event 0x%x\n", ev_code); break; } /* switch(MHI_EV_READ_CODE(EV_TRB_CODE,event)) */ @@ -798,6 +798,7 @@ static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl, struct mhi_ring_element *tre) { dma_addr_t ptr = MHI_TRE_GET_EV_PTR(tre); + struct device *dev = &mhi_cntrl->mhi_dev->dev; struct mhi_cmd *cmd_ring = &mhi_cntrl->mhi_cmd[PRIMARY_CMD_RING]; struct mhi_ring *mhi_ring = &cmd_ring->ring; struct mhi_ring_element *cmd_pkt; @@ -812,10 +813,14 @@ static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl, cmd_pkt = mhi_to_virtual(mhi_ring, ptr); + if (cmd_pkt != mhi_ring->rp) + panic("Out of order cmd completion: 0x%llx. Expected: 0x%llx\n", + cmd_pkt, mhi_ring->rp); + if (MHI_TRE_GET_CMD_TYPE(cmd_pkt) == MHI_CMD_SFR_CFG) { mhi_misc_cmd_completion(mhi_cntrl, MHI_CMD_SFR_CFG, MHI_TRE_GET_EV_CODE(tre)); - return; + goto exit_cmd_completion; } chan = MHI_TRE_GET_CMD_CHID(cmd_pkt); @@ -832,6 +837,7 @@ static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl, "Completion packet for invalid channel ID: %d\n", chan); } +exit_cmd_completion: mhi_del_ring_element(mhi_cntrl, mhi_ring); } diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index 0121557f9855..e09fd2956f2d 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -919,12 +919,8 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) return -EIO; - if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) { - dev_warn(dev, "Resuming from non M3 state (%s)\n", - mhi_state_str(mhi_get_mhi_state(mhi_cntrl))); - if (!force) - return -EINVAL; - } + if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) + panic("mhi_pm_state != M3"); /* Notify clients about exiting LPM */ list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, node) { From 2a3dece5e13e7d9a2e22faa89e71b166330d3fa6 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Thu, 16 Sep 2021 16:36:12 -0700 Subject: [PATCH 12/34] bus: mhi: host: Address pending BW requests for legacy mode It cannot be guaranteed that certain legacy mode controllers stay in M0 while a BW request is being processed. Ensure that those pending BW requests are addressed when M0 entry occurs after a BW request is processed but not responded to. Change-Id: I15ebc4e61e59ceeb5e8740b60bb95606945b0b3c Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/pm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index e09fd2956f2d..1e730889fb4b 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -298,6 +298,8 @@ int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl) if (mhi_cmd->ring.rp != mhi_cmd->ring.wp) mhi_ring_cmd_db(mhi_cntrl, mhi_cmd); spin_unlock_irq(&mhi_cmd->lock); + /* ring misc doorbells for certain controllers */ + mhi_misc_dbs_pending(mhi_cntrl); } /* Ring channel DB registers */ From 9204f9fa1ef22b6d21300f9728688b4a20900acd Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Mon, 14 Jun 2021 21:00:13 -0700 Subject: [PATCH 13/34] bus: mhi: host: Disable preemption while processing data events If data processing of an event is scheduled out because core is busy handling multiple irqs, this can starves the processing of MHI M0 state change event on another core. Fix this issue by disabling irq on the core processing data events. Change-Id: I4d784d2c343d4a9c50741f3e72df4c373993ae79 Signed-off-by: Hemant Kumar Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 827ce89b2cd1..980a43cf7dc0 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -1090,13 +1090,14 @@ int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl, void mhi_ev_task(unsigned long data) { + unsigned long flags; struct mhi_event *mhi_event = (struct mhi_event *)data; struct mhi_controller *mhi_cntrl = mhi_event->mhi_cntrl; /* process all pending events */ - spin_lock_bh(&mhi_event->lock); + spin_lock_irqsave(&mhi_event->lock, flags); mhi_event->process_event(mhi_cntrl, mhi_event, U32_MAX); - spin_unlock_bh(&mhi_event->lock); + spin_unlock_irqrestore(&mhi_event->lock, flags); } void mhi_ctrl_ev_task(unsigned long data) From d5d939f536333313bca97b078bf3fc916caff98f Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Thu, 24 Jun 2021 15:30:14 -0700 Subject: [PATCH 14/34] bus: mhi: host: Panic if suspend ack times out If suspend ack does not arrive on time, MHI host currently bails out silently. Panic if this happens such that issues can be pin- pointed to root causes. Change-Id: Ic2201aafc2a55d572311ec9ee8a8b9c8a60a1da4 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/pm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index 1e730889fb4b..b6ae6d7913eb 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -884,7 +884,11 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state), msecs_to_jiffies(mhi_cntrl->timeout_ms)); - if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { + if (!ret) { + mhi_debug_reg_dump(mhi_cntrl); + panic("Timedout waiting for M3 ACK"); + return -EIO; + } else if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { dev_err(dev, "Did not enter M3 state, MHI state: %s, PM state: %s\n", mhi_state_str(mhi_cntrl->dev_state), From e85735437fefe95b823eb726e934997a8dfb6a89 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Thu, 1 Jul 2021 12:05:40 -0700 Subject: [PATCH 15/34] bus: mhi: core: Use mhi_soc_reset() API in place of register write Currently, a direct register write is used when ramdump collection in panic path occurs. Replace that with new mhi_soc_reset() API such that a controller defined reset() function is exercised if one is present and the regular SOC reset is done if it is not. Change-Id: I6590598b63211ef8c12fa666e2ce0f690ddaf1c9 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/boot.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 4383bfc5598c..49bf041cd3e0 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * */ @@ -118,9 +118,7 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) /* Hardware reset so force device to enter RDDM */ dev_dbg(dev, "Did not enter RDDM, do a host req reset\n"); - mhi_write_reg(mhi_cntrl, mhi_cntrl->regs, - MHI_SOC_RESET_REQ_OFFSET, - MHI_SOC_RESET_REQ); + mhi_soc_reset(mhi_cntrl); udelay(delayus); } From f82f2340d80ec35caf6160c3130547dc30348b13 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Mon, 23 Aug 2021 18:54:28 -0700 Subject: [PATCH 16/34] bus: mhi: core: Add support to offload device wake DB write Wake doorbell register write operation is done with spin lock held. This adds implicit CPU memory barrier after the write which goes over the link. In case the endpoint is in L1SS sleep (retention), it takes around 2.5 ms for link to comeback and respond to this write operation. Due to memory barrier CPU would stall for 2.5ms and this starves any other task waiting to run on same core. Fix this issue by offloading device wake doorbell write to a high priority work queue. This offloading is enabled only for device supporting legacy M state mode. Change-Id: I4447cf1afa4bc2c95991e003196ecd1e45926c66 Signed-off-by: Hemant Kumar Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/pm.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index b6ae6d7913eb..b4854cf4f772 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -413,6 +413,8 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) wake_up_all(&mhi_cntrl->state_event); + mhi_reset_reg_write_q(mhi_cntrl); + device_for_each_child(&mhi_cntrl->mhi_dev->dev, ¤t_ee, mhi_destroy_device); mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_MISSION_MODE); @@ -466,6 +468,8 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) dev_dbg(dev, "Processing disable transition with PM state: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state)); + mhi_reset_reg_write_q(mhi_cntrl); + mutex_lock(&mhi_cntrl->pm_mutex); /* Trigger MHI RESET so that the device will not access host memory */ @@ -879,6 +883,9 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) write_unlock_irq(&mhi_cntrl->pm_lock); dev_dbg(dev, "Waiting for M3 completion\n"); + /* finish reg writes before D3 cold */ + mhi_force_reg_write(mhi_cntrl); + ret = wait_event_timeout(mhi_cntrl->state_event, mhi_cntrl->dev_state == MHI_STATE_M3 || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state), @@ -995,6 +1002,8 @@ int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl) mhi_trigger_resume(mhi_cntrl); read_unlock_bh(&mhi_cntrl->pm_lock); + mhi_force_reg_write(mhi_cntrl); + ret = wait_event_timeout(mhi_cntrl->state_event, mhi_cntrl->pm_state == MHI_PM_M0 || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state), @@ -1024,7 +1033,10 @@ static void mhi_assert_dev_wake(struct mhi_controller *mhi_cntrl, bool force) atomic_inc(&mhi_cntrl->dev_wake); if (MHI_WAKE_DB_FORCE_SET_VALID(mhi_cntrl->pm_state) && !mhi_cntrl->wake_set) { - mhi_write_db(mhi_cntrl, mhi_cntrl->wake_db, 1); + if (mhi_cntrl->db_access & MHI_PM_M2) + mhi_write_db(mhi_cntrl, mhi_cntrl->wake_db, 1); + else + mhi_write_offload_wakedb(mhi_cntrl, 1); mhi_cntrl->wake_set = true; } spin_unlock_irqrestore(&mhi_cntrl->wlock, flags); @@ -1040,7 +1052,10 @@ static void mhi_assert_dev_wake(struct mhi_controller *mhi_cntrl, bool force) if ((atomic_inc_return(&mhi_cntrl->dev_wake) == 1) && MHI_WAKE_DB_SET_VALID(mhi_cntrl->pm_state) && !mhi_cntrl->wake_set) { - mhi_write_db(mhi_cntrl, mhi_cntrl->wake_db, 1); + if (mhi_cntrl->db_access & MHI_PM_M2) + mhi_write_db(mhi_cntrl, mhi_cntrl->wake_db, 1); + else + mhi_write_offload_wakedb(mhi_cntrl, 1); mhi_cntrl->wake_set = true; } spin_unlock_irqrestore(&mhi_cntrl->wlock, flags); @@ -1064,7 +1079,10 @@ static void mhi_deassert_dev_wake(struct mhi_controller *mhi_cntrl, if ((atomic_dec_return(&mhi_cntrl->dev_wake) == 0) && MHI_WAKE_DB_CLEAR_VALID(mhi_cntrl->pm_state) && !override && mhi_cntrl->wake_set) { - mhi_write_db(mhi_cntrl, mhi_cntrl->wake_db, 0); + if (mhi_cntrl->db_access & MHI_PM_M2) + mhi_write_db(mhi_cntrl, mhi_cntrl->wake_db, 0); + else + mhi_write_offload_wakedb(mhi_cntrl, 0); mhi_cntrl->wake_set = false; } spin_unlock_irqrestore(&mhi_cntrl->wlock, flags); From d933db57d7054ec28cc754ecb88a6a58534d38d7 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Thu, 16 Sep 2021 17:03:01 -0700 Subject: [PATCH 17/34] bus: mhi: host: Skip power down if RDDM is supported and power up fails Skip power down if RDDM is supported and power up fails as the CNSS handling requires it. Change-Id: I88a2f9e0ea29dd04f76a3a6facb421ac61789bce Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index b4854cf4f772..4841984fefc4 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -1238,7 +1238,7 @@ int mhi_sync_power_up(struct mhi_controller *mhi_cntrl) msecs_to_jiffies(mhi_cntrl->timeout_ms)); ret = (MHI_IN_MISSION_MODE(mhi_cntrl->ee)) ? 0 : -ETIMEDOUT; - if (ret) + if (ret && !mhi_cntrl->rddm_image) mhi_power_down(mhi_cntrl, false); return ret; From d0737d448db37f9b12d1311db796bfe799e7be17 Mon Sep 17 00:00:00 2001 From: Vivek Pernamitta Date: Mon, 27 Sep 2021 14:03:30 -0700 Subject: [PATCH 18/34] bus: mhi: host: Provide an API to perform host reset request Adding new API to perform host reset request to device to collect device side dumps. Use mhi_soc_reset() API in place of register write Currently, a direct register write is used when ramdump collection in panic path occurs. Replace that with new mhi_soc_reset() API such that a controller defined reset() function is exercised if one is present and the regular SOC reset is done if it is not. Change-Id: Ibd15b231072a9b811ced0031387d605184806e9a Signed-off-by: Bhaumik Bhatt Signed-off-by: Vivek Pernamitta Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/boot.c | 56 ++++++++++++++++++++++----------- drivers/bus/mhi/host/internal.h | 3 +- drivers/bus/mhi/host/misc.c | 18 +++++++++++ 3 files changed, 58 insertions(+), 19 deletions(-) diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 49bf041cd3e0..6b30eb14d619 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -59,17 +59,48 @@ int mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, return 0; } +/* check RDDM image is downloaded */ +int mhi_rddm_download_status(struct mhi_controller *mhi_cntrl) +{ + u32 rx_status; + enum mhi_ee_type ee; + const u32 delayus = 5000; + void __iomem *base = mhi_cntrl->bhie; + u32 retry = (mhi_cntrl->timeout_ms * 1000) / delayus; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + int ret = 0; + + while (retry--) { + ret = mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, + BHIE_RXVECSTATUS_STATUS_BMSK, + &rx_status); + if (ret) + return -EIO; + + if (rx_status == BHIE_RXVECSTATUS_STATUS_XFER_COMPL) { + MHI_LOG(dev, "RDDM dumps collected successfully"); + return 0; + } + + udelay(delayus); + } + + ee = mhi_get_exec_env(mhi_cntrl); + ret = mhi_read_reg(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, &rx_status); + MHI_ERR(dev, "ret: %d, RXVEC_STATUS: 0x%x, EE:%s\n", ret, rx_status, + TO_MHI_EXEC_STR(ee)); + + return -EIO; +} + /* Collect RDDM buffer during kernel panic */ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) { int ret; - u32 rx_status; enum mhi_ee_type ee; const u32 delayus = 2000; - u32 retry = (mhi_cntrl->timeout_ms * 1000) / delayus; const u32 rddm_timeout_us = 200000; int rddm_retry = rddm_timeout_us / delayus; - void __iomem *base = mhi_cntrl->bhie; struct device *dev = &mhi_cntrl->mhi_dev->dev; dev_dbg(dev, "Entered with pm_state:%s dev_state:%s ee:%s\n", @@ -129,23 +160,12 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) "Waiting for RDDM image download via BHIe, current EE:%s\n", TO_MHI_EXEC_STR(ee)); - while (retry--) { - ret = mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, - BHIE_RXVECSTATUS_STATUS_BMSK, &rx_status); - if (ret) - return -EIO; - - if (rx_status == BHIE_RXVECSTATUS_STATUS_XFER_COMPL) - return 0; - - udelay(delayus); + ret = mhi_rddm_download_status(mhi_cntrl); + if (!ret) { + MHI_LOG(dev, "RDDM dumps collected successfully"); + return 0; } - ee = mhi_get_exec_env(mhi_cntrl); - ret = mhi_read_reg(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, &rx_status); - - dev_err(dev, "RXVEC_STATUS: 0x%x\n", rx_status); - error_exit_rddm: dev_err(dev, "RDDM transfer failed. Current EE: %s\n", TO_MHI_EXEC_STR(ee)); diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index b88330658270..07fdf4ac063a 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * */ @@ -296,6 +296,7 @@ int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl); int mhi_send_cmd(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan, enum mhi_cmd_type cmd); int mhi_download_amss_image(struct mhi_controller *mhi_cntrl); +int mhi_rddm_download_status(struct mhi_controller *mhi_cntrl); static inline bool mhi_is_active(struct mhi_controller *mhi_cntrl) { return (mhi_cntrl->dev_state >= MHI_STATE_M0 && diff --git a/drivers/bus/mhi/host/misc.c b/drivers/bus/mhi/host/misc.c index 511502d88f9f..1f8ca24854b6 100644 --- a/drivers/bus/mhi/host/misc.c +++ b/drivers/bus/mhi/host/misc.c @@ -1890,6 +1890,24 @@ int mhi_get_remote_time(struct mhi_device *mhi_dev, } EXPORT_SYMBOL(mhi_get_remote_time); +/* MHI host reset request*/ +int mhi_force_reset(struct mhi_controller *mhi_cntrl) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + + MHI_VERB(dev, "Entered with pm_state:%s dev_state:%s ee:%s\n", + to_mhi_pm_state_str(mhi_cntrl->pm_state), + mhi_state_str(mhi_cntrl->dev_state), + TO_MHI_EXEC_STR(mhi_cntrl->ee)); + + /* notify critical clients in absence of RDDM */ + mhi_report_error(mhi_cntrl); + + mhi_soc_reset(mhi_cntrl); + return mhi_rddm_download_status(mhi_cntrl); +} +EXPORT_SYMBOL(mhi_force_reset); + /* Get SoC info before registering mhi controller */ int mhi_get_soc_info(struct mhi_controller *mhi_cntrl) { From 38dced66d3b8803488f055b1e3cf3145497c61b7 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Wed, 13 Oct 2021 12:51:30 -0700 Subject: [PATCH 19/34] bus: mhi: host: Add RDDM check in mhi_pm_resume() If a device crash occurs when in suspended state, the interrupt handler cannot access registers to act on it. Once controller is done with PCIe resume and calls mhi_pm_resume(), MHI host can check for the RDDM entry and handle it as needed. Change-Id: I6127b75b51c3ef932e601391daebd0657e1a04eb Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/pm.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index 4841984fefc4..d6a15e370166 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -820,6 +820,28 @@ void mhi_pm_st_worker(struct work_struct *work) } } +static bool mhi_in_rddm(struct mhi_controller *mhi_cntrl) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + + if (mhi_cntrl->rddm_image && mhi_get_exec_env(mhi_cntrl) == MHI_EE_RDDM + && mhi_is_active(mhi_cntrl)) { + mhi_cntrl->ee = MHI_EE_RDDM; + + MHI_ERR(dev, "RDDM event occurred!\n"); + + /* notify critical clients with early notifications */ + mhi_report_error(mhi_cntrl); + + mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_RDDM); + wake_up_all(&mhi_cntrl->state_event); + + return true; + } + + return false; +} + int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) { struct mhi_chan *itr, *tmp; @@ -935,6 +957,9 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) panic("mhi_pm_state != M3"); + if (mhi_in_rddm(mhi_cntrl)) + return 0; + /* Notify clients about exiting LPM */ list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, node) { mutex_lock(&itr->mutex); @@ -965,6 +990,8 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) msecs_to_jiffies(mhi_cntrl->timeout_ms)); if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { + if (mhi_in_rddm(mhi_cntrl)) + return 0; dev_err(dev, "Did not enter M0 state, MHI state: %s, PM state: %s\n", mhi_state_str(mhi_cntrl->dev_state), From 20a444391a58320cb54e4b7810b53186d07088b8 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Tue, 12 Oct 2021 13:47:35 -0700 Subject: [PATCH 20/34] bus: mhi: core: Fix race between channel preparation and M0 event There is a race condition where mhi_prepare_channel() updates the read and write pointers as the base address and in parallel, if an M0 transition occurs, the tasklet goes ahead and rings doorbells for all channels with a delta in TRE rings assuming they are already enabled. This causes a null pointer access. Fix it by adding a channel enabled check before ringing channel doorbells. Change-Id: Idd1f39627a509590e892bf5c853761d351d3d823 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/pm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index d6a15e370166..f12abb9c5cf8 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -316,7 +316,8 @@ int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl) read_lock_irq(&mhi_chan->lock); /* Only ring DB if ring is not empty */ - if (tre_ring->base && tre_ring->wp != tre_ring->rp) + if (tre_ring->base && tre_ring->wp != tre_ring->rp && + mhi_chan->ch_state == MHI_CH_STATE_ENABLED) mhi_ring_chan_db(mhi_cntrl, mhi_chan); read_unlock_irq(&mhi_chan->lock); } From 4cdf3aac4db863fa77dfe40647b82d0bfa4632e7 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 20 Nov 2020 10:00:15 -0800 Subject: [PATCH 21/34] bus: mhi: host: Enable support for miscellaneous MHI features Add a new MHI_BUS_MISC Kconfig entry and support to build miscellaneous MHI features in Makefile if enabled. It can be enabled only if necessary for certain controllers and is tied to module init/exit and MHI registration. Change-Id: I36429eed9e786681150aceb494bcd06cf3d09ca9 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/init.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index 7e830b9a0e95..85b39d69fdac 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -1021,6 +1021,14 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl, mhi_cntrl->mhi_dev = mhi_dev; + ret = mhi_misc_register_controller(mhi_cntrl); + if (ret) { + dev_err(mhi_cntrl->cntrl_dev, + "Could not enable miscellaneous features\n"); + mhi_cntrl->mhi_dev = NULL; + goto err_release_dev; + } + mhi_create_debugfs(mhi_cntrl); return 0; @@ -1050,6 +1058,8 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl) unsigned int i; mhi_deinit_free_irq(mhi_cntrl); + mhi_misc_unregister_controller(mhi_cntrl); + /* Free the memory controller wanted to preserve for BHIe images */ if (mhi_cntrl->img_pre_alloc) { mhi_cntrl->img_pre_alloc = false; @@ -1445,12 +1455,14 @@ struct bus_type mhi_bus_type = { static int __init mhi_init(void) { + mhi_misc_init(); mhi_debugfs_init(); return bus_register(&mhi_bus_type); } static void __exit mhi_exit(void) { + mhi_misc_exit(); mhi_debugfs_exit(); bus_unregister(&mhi_bus_type); } From ba41ac151c12e89e896a5aaf432343a662bc17d3 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 14 May 2021 12:05:10 -0700 Subject: [PATCH 22/34] bus: mhi: host: Add spinlock to protect WP access when queueing TREs Protect WP accesses such that multiple threads queueing buffers for incoming data do not race and access the same WP twice. Ensure read and write locks for the channel are not taken in succession by dropping the read lock from parse_xfer_event() such that a callback given to client can potentially queue buffers and acquire the write lock in that process. Any queueing of buffers should be done without channel read lock acquired as it can result in multiple locks and a soft lockup. Change-Id: Iaa5849da70acd6ece06469312186edc194c7f050 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 980a43cf7dc0..083507774089 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -673,6 +673,8 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl, mhi_del_ring_element(mhi_cntrl, tre_ring); local_rp = tre_ring->rp; + read_unlock_bh(&mhi_chan->lock); + /* notify client */ mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); @@ -698,6 +700,8 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl, kfree(buf_info->cb_buf); } } + + read_lock_bh(&mhi_chan->lock); } break; } /* CC_EOT */ @@ -1270,6 +1274,9 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan, int eot, eob, chain, bei; int ret; + /* Protect accesses for reading and incrementing WP */ + write_lock_bh(&mhi_chan->lock); + buf_ring = &mhi_chan->buf_ring; tre_ring = &mhi_chan->tre_ring; @@ -1305,6 +1312,8 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan, mhi_add_ring_element(mhi_cntrl, tre_ring); mhi_add_ring_element(mhi_cntrl, buf_ring); + write_unlock_bh(&mhi_chan->lock); + return 0; } From 48799e0f4d80697f7de37ffd13ea7c8bb9d6632e Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Tue, 30 Nov 2021 11:25:53 -0800 Subject: [PATCH 23/34] bus: mhi: host: Add update transfer state APIs Add update transfer state APIs and do not check for channel state in the channel context as device can update it once MHI master reset has taken place. Instead, rely on local channel and PM states prior to sending any channel update commands. Change-Id: Ib3416323e0f1b01ff37c9bd176e72daa4dea9d8d Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/main.c | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 083507774089..60d84444ac1f 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -1763,6 +1763,47 @@ void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) } EXPORT_SYMBOL_GPL(mhi_unprepare_from_transfer); +static int mhi_update_transfer_state(struct mhi_device *mhi_dev, + enum mhi_ch_state_type to_state) +{ + struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; + struct mhi_chan *mhi_chan; + int dir, ret; + + for (dir = 0; dir < 2; dir++) { + mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; + + if (!mhi_chan) + continue; + + /* + * Bail out if one of the channels fails as client will reset + * both upon failure + */ + mutex_lock(&mhi_chan->mutex); + ret = mhi_update_channel_state(mhi_cntrl, mhi_chan, to_state); + if (ret) { + mutex_unlock(&mhi_chan->mutex); + return ret; + } + mutex_unlock(&mhi_chan->mutex); + } + + return 0; +} + +int mhi_stop_transfer(struct mhi_device *mhi_dev) +{ + return mhi_update_transfer_state(mhi_dev, MHI_CH_STATE_TYPE_STOP); +} +EXPORT_SYMBOL(mhi_stop_transfer); + +int mhi_start_transfer(struct mhi_device *mhi_dev) +{ + return mhi_update_transfer_state(mhi_dev, MHI_CH_STATE_TYPE_START); +} +EXPORT_SYMBOL(mhi_start_transfer); + int mhi_poll(struct mhi_device *mhi_dev, u32 budget) { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; From 90fc13e21324aa17f51ffa90f5d0cedf12f2cb1f Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Thu, 23 Dec 2021 14:02:47 -0800 Subject: [PATCH 24/34] bus: mhi: host: Allow configuration of bidrectional channels Certain offload channels such as ones for satellite driver usecases are required to be configured as bidrectional channels. Allow it to ensure devices are created for them and the channels are probed. Added __attribute__((__fallthrough__)) statements to suppress compiler error. Change-Id: I782e3e933765099e8ee9eb1670cce321a3dffd8b Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 60d84444ac1f..2a790dd43278 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -380,6 +380,12 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl) mhi_dev->ul_chan_id = mhi_chan->chan; mhi_dev->ul_event_id = mhi_chan->er_index; break; + case DMA_NONE: + __attribute__((__fallthrough__)); + case DMA_BIDIRECTIONAL: + mhi_dev->ul_chan_id = mhi_chan->chan; + mhi_dev->ul_event_id = mhi_chan->er_index; + __attribute__((__fallthrough__)); case DMA_FROM_DEVICE: /* We use dl_chan as offload channels */ mhi_dev->dl_chan = mhi_chan; From e541397ebd45c0edffd0b7ebb28cdfd35b7fbd32 Mon Sep 17 00:00:00 2001 From: Vivek Pernamitta Date: Wed, 29 Dec 2021 15:17:30 +0530 Subject: [PATCH 25/34] bus: mhi: host: Release mhi_chan write lock on map_single fails Release mhi_chan write lock before returning on map_single callback failure. Change-Id: Iab4bcc878ff5ed7d11c6e943f949ab39dc77b829 Signed-off-by: Vivek Pernamitta Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 2a790dd43278..3c5a433a152d 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -1300,8 +1300,10 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan, if (!info->pre_mapped) { ret = mhi_cntrl->map_single(mhi_cntrl, buf_info); - if (ret) + if (ret) { + write_unlock_bh(&mhi_chan->lock); return ret; + } } eob = !!(flags & MHI_EOB); From 7b8b0f1c27244bd4ebbe4c769df9d1b83228a913 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 18 Feb 2022 16:03:42 -0800 Subject: [PATCH 26/34] bus: mhi: core: Update debug print for TRE generation Include channel number and update the TRE WP print to read the IOVA properly in order to improve readability. Change-Id: I80d9c7c2d8722efabb47ccf4b580bd65ab3c9728 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/debugfs.c | 8 +++++--- drivers/bus/mhi/host/internal.h | 1 + drivers/bus/mhi/host/main.c | 13 ++++++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/bus/mhi/host/debugfs.c b/drivers/bus/mhi/host/debugfs.c index 55dd7375c06f..b2cac7775d40 100644 --- a/drivers/bus/mhi/host/debugfs.c +++ b/drivers/bus/mhi/host/debugfs.c @@ -71,7 +71,8 @@ static int mhi_debugfs_events_show(struct seq_file *m, void *d) seq_printf(m, " rp: 0x%llx wp: 0x%llx", le64_to_cpu(er_ctxt->rp), le64_to_cpu(er_ctxt->wp)); - seq_printf(m, " local rp: 0x%pK db: 0x%pad\n", ring->rp, + seq_printf(m, " local rp: 0x%llx db: 0x%pad\n", + (u64)mhi_to_physical(ring, ring->rp), &mhi_event->db_cfg.db_val); } @@ -119,8 +120,9 @@ static int mhi_debugfs_channels_show(struct seq_file *m, void *d) le64_to_cpu(chan_ctxt->rbase), le64_to_cpu(chan_ctxt->rlen), le64_to_cpu(chan_ctxt->rp), le64_to_cpu(chan_ctxt->wp)); - seq_printf(m, " local rp: 0x%pK local wp: 0x%pK db: 0x%pad\n", - ring->rp, ring->wp, + seq_printf(m, " local rp: 0x%llx local wp: 0x%llx db: 0x%pad\n", + (u64)mhi_to_physical(ring, ring->rp), + (u64)mhi_to_physical(ring, ring->wp), &mhi_chan->db_cfg.db_val); } diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index 07fdf4ac063a..8db7f597c34f 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -335,6 +335,7 @@ void mhi_write_db(struct mhi_controller *mhi_cntrl, void __iomem *db_addr, void mhi_ring_cmd_db(struct mhi_controller *mhi_cntrl, struct mhi_cmd *mhi_cmd); void mhi_ring_chan_db(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan); +dma_addr_t mhi_to_physical(struct mhi_ring *ring, void *addr); /* Initialization methods */ int mhi_init_mmio(struct mhi_controller *mhi_cntrl); diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 3c5a433a152d..47b6fea1b5c5 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -246,6 +246,11 @@ static void *mhi_to_virtual(struct mhi_ring *ring, dma_addr_t addr) return (addr - ring->iommu_base) + ring->base; } +dma_addr_t mhi_to_physical(struct mhi_ring *ring, void *addr) +{ + return (addr - ring->base) + ring->iommu_base; +} + static void mhi_add_ring_element(struct mhi_controller *mhi_cntrl, struct mhi_ring *ring) { @@ -885,7 +890,8 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, while (dev_rp != local_rp) { enum mhi_pkt_type type = MHI_TRE_GET_EV_TYPE(local_rp); - dev_dbg(dev, "Processing Event:0x%llx 0x%08x 0x%08x\n", + dev_dbg(dev, "RP:0x%llx Processing Event:0x%llx 0x%08x 0x%08x\n", + (u64)mhi_to_physical(ev_ring, local_rp), local_rp->ptr, local_rp->dword[0], local_rp->dword[1]); switch (type) { @@ -1274,6 +1280,7 @@ EXPORT_SYMBOL_GPL(mhi_queue_dma); int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan, struct mhi_buf_info *info, enum mhi_flags flags) { + struct device *dev = &mhi_chan->mhi_dev->dev; struct mhi_ring *buf_ring, *tre_ring; struct mhi_ring_element *mhi_tre; struct mhi_buf_info *buf_info; @@ -1316,6 +1323,10 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan, mhi_tre->dword[0] = MHI_TRE_DATA_DWORD0(info->len); mhi_tre->dword[1] = MHI_TRE_DATA_DWORD1(bei, eot, eob, chain); + MHI_VERB(dev, "Chan: %d WP: 0x%llx TRE: 0x%llx 0x%08x 0x%08x\n", + mhi_chan->chan, (u64)mhi_to_physical(tre_ring, mhi_tre), + mhi_tre->ptr, mhi_tre->dword[0], mhi_tre->dword[1]); + /* increment WP */ mhi_add_ring_element(mhi_cntrl, tre_ring); mhi_add_ring_element(mhi_cntrl, buf_ring); From 1c0cd2d26a1cfd14a12592496220e3515c2f913f Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Thu, 10 Mar 2022 19:57:39 -0800 Subject: [PATCH 27/34] bus: mhi: host: Take irqsave lock after TRE is generated Take irqsave lock after TRE is generated to avoid deadlock due to core getting interrupts enabled as local_bh_enable must not be called with irqs disabled based on upstream patch. Change-Id: Id0c34ccddbfa99700ec32319d141cecd3dfbe1f1 Signed-off-by: Hemant Kumar Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/main.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 47b6fea1b5c5..7437959242cc 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -1204,17 +1204,15 @@ static int mhi_queue(struct mhi_device *mhi_dev, struct mhi_buf_info *buf_info, if (unlikely(MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))) return -EIO; - read_lock_irqsave(&mhi_cntrl->pm_lock, flags); - ret = mhi_is_ring_full(mhi_cntrl, tre_ring); - if (unlikely(ret)) { - ret = -EAGAIN; - goto exit_unlock; - } + if (unlikely(ret)) + return -EAGAIN; ret = mhi_gen_tre(mhi_cntrl, mhi_chan, buf_info, mflags); if (unlikely(ret)) - goto exit_unlock; + return ret; + + read_lock_irqsave(&mhi_cntrl->pm_lock, flags); /* Packet is queued, take a usage ref to exit M3 if necessary * for host->device buffer, balanced put is done on buffer completion @@ -1234,7 +1232,6 @@ static int mhi_queue(struct mhi_device *mhi_dev, struct mhi_buf_info *buf_info, if (dir == DMA_FROM_DEVICE) mhi_cntrl->runtime_put(mhi_cntrl); -exit_unlock: read_unlock_irqrestore(&mhi_cntrl->pm_lock, flags); return ret; From 09138d73842cb8a98749f4d8ad7981ba9053ae25 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Tue, 29 Mar 2022 17:35:14 -0700 Subject: [PATCH 28/34] bus: mhi: misc: DTR race condition updates Data terminal ready driver should not be started until other client drivers are probed so that they can get the necessary notifications when updates are made available to them by the device via incoming messages. Adjust flow of the driver and ensure DTR driver starts after all other devices are created by core driver. Change-Id: I9e0bcb87a3b59a66fede0c82ded94a704d16c2a1 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index f12abb9c5cf8..9755f9fe0667 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -437,7 +437,6 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) read_unlock_bh(&mhi_cntrl->pm_lock); - mhi_misc_mission_mode(mhi_cntrl); mhi_process_sleeping_events(mhi_cntrl); /* @@ -445,6 +444,7 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) * Execution Environment (EE) to either SBL or AMSS states */ mhi_create_devices(mhi_cntrl); + mhi_misc_mission_mode(mhi_cntrl); read_lock_bh(&mhi_cntrl->pm_lock); From 56533953379dc48bc8a8b58a8b143b2a47868c90 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 1 Apr 2022 12:46:48 -0700 Subject: [PATCH 29/34] Revert "bus: mhi: core: Fix MHI runtime_pm behavior" This reverts commit 4547a749be997eb12ea7edcf361ec2a5329f7aec. This is done to ensure internal usecases with WLAN are not impacted with high power usage. Runtime PM get also results in a WoW exit and is also unnecessary as we already have the if suspended check and the pending packets counter in place to take care of rejecting suspends if they occur. The only major benefit of this patch was to ensure controller is able to mark last busy timestamp for runtime PM. If needed, support for it can be added in a future patch to allow controller to update the timestamp. Change-Id: I3e16ab3631468edd0fda3657adf0f5ae55f0be16 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/main.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 7437959242cc..ddd18700a670 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -689,11 +689,8 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl, /* notify client */ mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); - if (mhi_chan->dir == DMA_TO_DEVICE) { + if (mhi_chan->dir == DMA_TO_DEVICE) atomic_dec(&mhi_cntrl->pending_pkts); - /* Release the reference got from mhi_queue() */ - mhi_cntrl->runtime_put(mhi_cntrl); - } /* * Recycle the buffer if buffer is pre-allocated, @@ -1214,11 +1211,9 @@ static int mhi_queue(struct mhi_device *mhi_dev, struct mhi_buf_info *buf_info, read_lock_irqsave(&mhi_cntrl->pm_lock, flags); - /* Packet is queued, take a usage ref to exit M3 if necessary - * for host->device buffer, balanced put is done on buffer completion - * for device->host buffer, balanced put is after ringing the DB - */ - mhi_cntrl->runtime_get(mhi_cntrl); + /* trigger M3 exit if necessary */ + if (MHI_PM_IN_SUSPEND_STATE(mhi_cntrl->pm_state)) + mhi_trigger_resume(mhi_cntrl); /* Assert dev_wake (to exit/prevent M1/M2)*/ mhi_cntrl->wake_toggle(mhi_cntrl); @@ -1229,9 +1224,6 @@ static int mhi_queue(struct mhi_device *mhi_dev, struct mhi_buf_info *buf_info, if (likely(MHI_DB_ACCESS_VALID(mhi_cntrl))) mhi_ring_chan_db(mhi_cntrl, mhi_chan); - if (dir == DMA_FROM_DEVICE) - mhi_cntrl->runtime_put(mhi_cntrl); - read_unlock_irqrestore(&mhi_cntrl->pm_lock, flags); return ret; @@ -1679,11 +1671,8 @@ static void mhi_reset_data_chan(struct mhi_controller *mhi_cntrl, while (tre_ring->rp != tre_ring->wp) { struct mhi_buf_info *buf_info = buf_ring->rp; - if (mhi_chan->dir == DMA_TO_DEVICE) { + if (mhi_chan->dir == DMA_TO_DEVICE) atomic_dec(&mhi_cntrl->pending_pkts); - /* Release the reference got from mhi_queue() */ - mhi_cntrl->runtime_put(mhi_cntrl); - } if (!buf_info->pre_mapped) mhi_cntrl->unmap_single(mhi_cntrl, buf_info); From f74335f06b7423c30d74f3f9b577d4f1c3db8092 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 1 Apr 2022 12:59:09 -0700 Subject: [PATCH 30/34] bus: mhi: host: Add optional runtime PM last busy update API This optional runtime PM last busy update callback to the controller is provided to keep the busy timestamps up to date from MHI core driver such that it can reset the autosuspend timer for runtime PM. Change-Id: Ifc9abce860739b92d29fc257afd169d08a738379 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/main.c | 4 ++++ include/linux/mhi.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index ddd18700a670..e8d689e5f9b3 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -1209,6 +1209,10 @@ static int mhi_queue(struct mhi_device *mhi_dev, struct mhi_buf_info *buf_info, if (unlikely(ret)) return ret; + /* Let controller mark last busy for runtime PM framework if needed */ + if (mhi_cntrl->runtime_last_busy) + mhi_cntrl->runtime_last_busy(mhi_cntrl); + read_lock_irqsave(&mhi_cntrl->pm_lock, flags); /* trigger M3 exit if necessary */ diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 470f27326a66..b5ac410138d8 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -374,6 +374,7 @@ struct mhi_controller_config { * @wake_toggle: CB function to assert and de-assert device wake (optional) * @runtime_get: CB function to controller runtime resume (required) * @runtime_put: CB function to decrement pm usage (required) + * @runtime_last_busy: CB function for controller to mark last busy (optional) * @map_single: CB function to create TRE buffer * @unmap_single: CB function to destroy TRE buffer * @read_reg: Read a MHI register via the physical link (required) @@ -466,6 +467,7 @@ struct mhi_controller { void (*wake_toggle)(struct mhi_controller *mhi_cntrl); int (*runtime_get)(struct mhi_controller *mhi_cntrl); void (*runtime_put)(struct mhi_controller *mhi_cntrl); + void (*runtime_last_busy)(struct mhi_controller *mhi_cntrl); int (*map_single)(struct mhi_controller *mhi_cntrl, struct mhi_buf_info *buf); void (*unmap_single)(struct mhi_controller *mhi_cntrl, From 8407d797f064168a0ac8462564bb9068b5f0e2a0 Mon Sep 17 00:00:00 2001 From: Lazarus Motha Date: Thu, 2 Jun 2022 13:34:50 -0700 Subject: [PATCH 31/34] mhi: host: Notify MHI clients about fatal error Currently fatal error notification is done from fast resume path. This does not cover RDDM EE change via BHI Intvec. As a result of the some critical clients are unable to perform cleanup and does not come up after recovery. In case if RDDM EE change never comes notify clients from mhi force reset context. Change-Id: Iea1f1d86e9a28c08e8d58100715004f3b2abfd96 Signed-off-by: Hemant Kumar Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index e8d689e5f9b3..9baae90e4fbe 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -552,6 +552,9 @@ irqreturn_t mhi_intvec_threaded_handler(int irq_number, void *priv) case MHI_EE_RDDM: /* proceed if power down is not already in progress */ if (mhi_cntrl->rddm_image && mhi_is_active(mhi_cntrl)) { + /* notify critical clients with early notifications */ + mhi_report_error(mhi_cntrl); + mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_RDDM); mhi_cntrl->ee = ee; wake_up_all(&mhi_cntrl->state_event); From 5a1870bb6baddcd455329f190cbcf03244b99739 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Wed, 15 Jun 2022 16:01:20 -0700 Subject: [PATCH 32/34] mhi: host: Skip MHI reset if device is in RDDM In RDDM EE, device can not process MHI reset issued by host. In case of MHI power off, host is issuing MHI reset and polls for it to get cleared until it times out. Since this timeout can not be avoided in case of RDDM, skip the MHI reset in this scenarios. Change-Id: Ide4311ba8705861179bfbfef650f00fa0f97c062 Signed-off-by: Hemant Kumar Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/pm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index 9755f9fe0667..78c2b483080a 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -473,8 +473,13 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) mutex_lock(&mhi_cntrl->pm_mutex); - /* Trigger MHI RESET so that the device will not access host memory */ - if (!MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state)) { + /* + * Trigger MHI RESET so that the device will not access host memory. + * skip MHI reset if device is in RDDM. + */ + if ((!MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state)) && + (mhi_cntrl->rddm_image && + mhi_get_exec_env(mhi_cntrl) != MHI_EE_RDDM)) { dev_dbg(dev, "Triggering MHI Reset in device\n"); mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); From 4f5e1c26d93257f692c56eb07793a4b227bc2ed1 Mon Sep 17 00:00:00 2001 From: Lazarus Motha Date: Tue, 27 Sep 2022 17:30:25 -0700 Subject: [PATCH 33/34] bus: mhi: host: Process invalid BW requests sent by device When an invalid BW request is sent by the device to the host to proccess, a value of 0x1 is written to the bw_scale_db register. Change-Id: I362e9b308142fe5a9107d46789d26cb38933e858 Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/misc.c | 6 ++++-- drivers/bus/mhi/host/misc.h | 7 ++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/bus/mhi/host/misc.c b/drivers/bus/mhi/host/misc.c index 1f8ca24854b6..82153ae6b89e 100644 --- a/drivers/bus/mhi/host/misc.c +++ b/drivers/bus/mhi/host/misc.c @@ -1364,7 +1364,7 @@ int mhi_process_misc_bw_ev_ring(struct mhi_controller *mhi_cntrl, struct mhi_link_info link_info, *cur_info = &mhi_cntrl->mhi_link_info; struct device *dev = &mhi_cntrl->mhi_dev->dev; struct mhi_private *mhi_priv = dev_get_drvdata(dev); - u32 result = MHI_BW_SCALE_NACK; + enum mhi_bw_scale_req_status result = MHI_BW_SCALE_NACK; int ret = -EINVAL; if (!MHI_IN_MISSION_MODE(mhi_cntrl->ee)) @@ -1428,7 +1428,9 @@ int mhi_process_misc_bw_ev_ring(struct mhi_controller *mhi_cntrl, ret = mhi_priv->bw_scale(mhi_cntrl, &link_info); if (!ret) { *cur_info = link_info; - result = 0; + result = MHI_BW_SCALE_SUCCESS; + } else if (ret == -EINVAL) { + result = MHI_BW_SCALE_INVALID; } write_lock_bh(&mhi_cntrl->pm_lock); diff --git a/drivers/bus/mhi/host/misc.h b/drivers/bus/mhi/host/misc.h index 59bda8be22bd..acc1e108419b 100644 --- a/drivers/bus/mhi/host/misc.h +++ b/drivers/bus/mhi/host/misc.h @@ -44,7 +44,12 @@ #define MHI_BW_SCALE_RESULT(status, seq) (((status) & 0xF) << 8 | \ ((seq) & 0xFF)) -#define MHI_BW_SCALE_NACK 0xF + +enum mhi_bw_scale_req_status { + MHI_BW_SCALE_SUCCESS = 0x0, + MHI_BW_SCALE_INVALID = 0x1, + MHI_BW_SCALE_NACK = 0xF, +}; /* subsystem failure reason cfg command */ #define MHI_TRE_CMD_SFR_CFG_PTR(ptr) (ptr) From 2321eb00ec742274df59ca8bf973e92deb720616 Mon Sep 17 00:00:00 2001 From: Lazarus Motha Date: Tue, 27 Sep 2022 18:04:40 -0700 Subject: [PATCH 34/34] bus: mhi: host: Enable and update IPC logging usage Move to IPC logs for the MHI host driver to enable better and persistent logging that can ensure bootup logs are not lost and allow ease of pulling logs from crashdumps. Change-Id: I334335f56acb850f418e5a37b0538545c5b9ea30 Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/boot.c | 48 +++++++++--------- drivers/bus/mhi/host/init.c | 34 ++++++------- drivers/bus/mhi/host/main.c | 76 ++++++++++++++-------------- drivers/bus/mhi/host/pm.c | 98 ++++++++++++++++++------------------- 4 files changed, 128 insertions(+), 128 deletions(-) diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 6b30eb14d619..14f771c1a3ec 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -35,7 +35,7 @@ int mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, bhi_vec->size = mhi_buf->len; } - dev_dbg(dev, "BHIe programming for RDDM\n"); + MHI_VERB(dev, "BHIe programming for RDDM\n"); mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_HIGH_OFFS, upper_32_bits(mhi_buf->dma_addr)); @@ -49,11 +49,11 @@ int mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, ret = mhi_write_reg_field(mhi_cntrl, base, BHIE_RXVECDB_OFFS, BHIE_RXVECDB_SEQNUM_BMSK, sequence_id); if (ret) { - dev_err(dev, "Failed to write sequence ID for BHIE_RXVECDB\n"); + MHI_ERR(dev, "Failed to write sequence ID for BHIE_RXVECDB\n"); return ret; } - dev_dbg(dev, "Address: %p and len: 0x%zx sequence: %u\n", + MHI_VERB(dev, "Address: %p and len: 0x%zx sequence: %u\n", &mhi_buf->dma_addr, mhi_buf->len, sequence_id); return 0; @@ -103,7 +103,7 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) int rddm_retry = rddm_timeout_us / delayus; struct device *dev = &mhi_cntrl->mhi_dev->dev; - dev_dbg(dev, "Entered with pm_state:%s dev_state:%s ee:%s\n", + MHI_VERB(dev, "Entered with pm_state:%s dev_state:%s ee:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), mhi_state_str(mhi_cntrl->dev_state), TO_MHI_EXEC_STR(mhi_cntrl->ee)); @@ -133,10 +133,10 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) goto error_exit_rddm; if (ee != MHI_EE_RDDM) { - dev_dbg(dev, "Trigger device into RDDM mode using SYS ERR\n"); + MHI_VERB(dev, "Trigger device into RDDM mode using SYS ERR\n"); mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR); - dev_dbg(dev, "Waiting for device to enter RDDM\n"); + MHI_VERB(dev, "Waiting for device to enter RDDM\n"); while (rddm_retry--) { ee = mhi_get_exec_env(mhi_cntrl); if (ee == MHI_EE_RDDM) @@ -147,7 +147,7 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) if (rddm_retry <= 0) { /* Hardware reset so force device to enter RDDM */ - dev_dbg(dev, + MHI_VERB(dev, "Did not enter RDDM, do a host req reset\n"); mhi_soc_reset(mhi_cntrl); udelay(delayus); @@ -156,7 +156,7 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) ee = mhi_get_exec_env(mhi_cntrl); } - dev_dbg(dev, + MHI_VERB(dev, "Waiting for RDDM image download via BHIe, current EE:%s\n", TO_MHI_EXEC_STR(ee)); @@ -167,7 +167,7 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) } error_exit_rddm: - dev_err(dev, "RDDM transfer failed. Current EE: %s\n", + MHI_ERR(dev, "RDDM transfer failed. Current EE: %s\n", TO_MHI_EXEC_STR(ee)); return -EIO; @@ -183,7 +183,7 @@ int mhi_download_rddm_image(struct mhi_controller *mhi_cntrl, bool in_panic) if (in_panic) return __mhi_download_rddm_in_panic(mhi_cntrl); - dev_dbg(dev, "Waiting for RDDM image download via BHIe\n"); + MHI_VERB(dev, "Waiting for RDDM image download via BHIe\n"); /* Wait for the image download to complete */ wait_event_timeout(mhi_cntrl->state_event, @@ -213,7 +213,7 @@ static int mhi_fw_load_bhie(struct mhi_controller *mhi_cntrl, } mhi_cntrl->session_id = MHI_RANDOM_U32_NONZERO(BHIE_TXVECSTATUS_SEQNUM_BMSK); - dev_dbg(dev, "Starting image download via BHIe. Sequence ID: %u\n", + MHI_VERB(dev, "Starting image download via BHIe. Sequence ID: %u\n", mhi_cntrl->session_id); mhi_write_reg(mhi_cntrl, base, BHIE_TXVECADDR_HIGH_OFFS, upper_32_bits(mhi_buf->dma_addr)); @@ -272,7 +272,7 @@ static int mhi_fw_load_bhi(struct mhi_controller *mhi_cntrl, } session_id = MHI_RANDOM_U32_NONZERO(BHI_TXDB_SEQNUM_BMSK); - dev_dbg(dev, "Starting image download via BHI. Session ID: %u\n", + MHI_VERB(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, @@ -293,7 +293,7 @@ static int mhi_fw_load_bhi(struct mhi_controller *mhi_cntrl, goto invalid_pm_state; if (tx_status == BHI_STATUS_ERROR) { - dev_err(dev, "Image transfer failed\n"); + MHI_ERR(dev, "Image transfer failed\n"); read_lock_bh(pm_lock); if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) { for (i = 0; error_reg[i].name; i++) { @@ -301,7 +301,7 @@ static int mhi_fw_load_bhi(struct mhi_controller *mhi_cntrl, error_reg[i].offset, &val); if (ret) break; - dev_err(dev, "Reg: %s value: 0x%x\n", + MHI_ERR(dev, "Reg: %s value: 0x%x\n", error_reg[i].name, val); } } @@ -426,7 +426,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) int i, ret; if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { - dev_err(dev, "Device MHI is not in valid state\n"); + MHI_ERR(dev, "Device MHI is not in valid state\n"); return; } @@ -434,13 +434,13 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_SERIALNU, &mhi_cntrl->serial_number); if (ret) - dev_err(dev, "Could not capture serial number via BHI\n"); + MHI_ERR(dev, "Could not capture serial number via BHI\n"); for (i = 0; i < ARRAY_SIZE(mhi_cntrl->oem_pk_hash); i++) { ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_OEMPKHASH(i), &mhi_cntrl->oem_pk_hash[i]); if (ret) { - dev_err(dev, "Could not capture OEM PK HASH via BHI\n"); + MHI_ERR(dev, "Could not capture OEM PK HASH via BHI\n"); break; } } @@ -454,7 +454,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) if (!fw_name || (mhi_cntrl->fbc_download && (!mhi_cntrl->sbl_size || !mhi_cntrl->seg_len))) { - dev_err(dev, + MHI_ERR(dev, "No firmware image defined or !sbl_size || !seg_len\n"); goto error_fw_load; } @@ -462,7 +462,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) ret = request_firmware(&firmware, fw_name, dev->parent); if (ret) { if (!mhi_cntrl->fallback_fw_image) { - dev_err(dev, "Error loading firmware: %d\n", ret); + MHI_ERR(dev, "Error loading firmware: %d\n", ret); goto error_fw_load; } @@ -470,7 +470,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) mhi_cntrl->fallback_fw_image, dev->parent); if (ret) { - dev_err(dev, "Error loading fallback firmware: %d\n", + MHI_ERR(dev, "Error loading fallback firmware: %d\n", ret); goto error_fw_load; } @@ -497,7 +497,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 image over BHI, ret: %d\n", ret); + MHI_ERR(dev, "MHI did not load image over BHI, ret: %d\n", ret); release_firmware(firmware); goto error_fw_load; } @@ -534,11 +534,11 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) /* Transitioning into MHI RESET->READY state */ ret = mhi_ready_state_transition(mhi_cntrl); if (ret) { - dev_err(dev, "MHI did not enter READY state\n"); + MHI_ERR(dev, "MHI did not enter READY state\n"); goto error_ready_state; } - dev_info(dev, "Wait for device to enter SBL or Mission mode\n"); + MHI_LOG(dev, "Wait for device to enter SBL or Mission mode\n"); return; error_ready_state: @@ -563,7 +563,7 @@ int mhi_download_amss_image(struct mhi_controller *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); + MHI_ERR(dev, "MHI did not load AMSS, ret:%d\n", ret); mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR; wake_up_all(&mhi_cntrl->state_event); } diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index 85b39d69fdac..3878d875bf5e 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -190,7 +190,7 @@ int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl) continue; if (mhi_event->irq >= mhi_cntrl->nr_irqs) { - dev_err(dev, "irq %d not available for event ring\n", + MHI_ERR(dev, "irq %d not available for event ring\n", mhi_event->irq); ret = -EINVAL; goto error_request; @@ -201,7 +201,7 @@ int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl) irq_flags, "mhi", mhi_event); if (ret) { - dev_err(dev, "Error requesting irq:%d for ev:%d\n", + MHI_ERR(dev, "Error requesting irq:%d for ev:%d\n", mhi_cntrl->irq[mhi_event->irq], i); goto error_request; } @@ -507,12 +507,12 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) {0, 0} }; - dev_dbg(dev, "Initializing MHI registers\n"); + MHI_VERB(dev, "Initializing MHI registers\n"); /* Read channel db offset */ ret = mhi_read_reg(mhi_cntrl, base, CHDBOFF, &val); if (ret) { - dev_err(dev, "Unable to read CHDBOFF register\n"); + MHI_ERR(dev, "Unable to read CHDBOFF register\n"); return -EIO; } @@ -528,7 +528,7 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) /* Read event ring db offset */ ret = mhi_read_reg(mhi_cntrl, base, ERDBOFF, &val); if (ret) { - dev_err(dev, "Unable to read ERDBOFF register\n"); + MHI_ERR(dev, "Unable to read ERDBOFF register\n"); return -EIO; } @@ -552,14 +552,14 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) ret = mhi_write_reg_field(mhi_cntrl, base, MHICFG, MHICFG_NER_MASK, mhi_cntrl->total_ev_rings); if (ret) { - dev_err(dev, "Unable to write MHICFG register\n"); + MHI_ERR(dev, "Unable to write MHICFG register\n"); return ret; } ret = mhi_write_reg_field(mhi_cntrl, base, MHICFG, MHICFG_NHWER_MASK, mhi_cntrl->hw_ev_rings); if (ret) { - dev_err(dev, "Unable to write MHICFG register\n"); + MHI_ERR(dev, "Unable to write MHICFG register\n"); return ret; } @@ -680,7 +680,7 @@ static int parse_ev_cfg(struct mhi_controller *mhi_cntrl, /* This event ring has a dedicated channel */ mhi_event->chan = event_cfg->channel; if (mhi_event->chan >= mhi_cntrl->max_chan) { - dev_err(dev, + MHI_ERR(dev, "Event Ring channel not available\n"); goto error_ev_cfg; } @@ -716,7 +716,7 @@ static int parse_ev_cfg(struct mhi_controller *mhi_cntrl, mhi_event->process_event = mhi_process_misc_tsync_ev_ring; break; default: - dev_err(dev, "Event Ring type not supported\n"); + MHI_ERR(dev, "Event Ring type not supported\n"); goto error_ev_cfg; } @@ -769,7 +769,7 @@ static int parse_ch_cfg(struct mhi_controller *mhi_cntrl, chan = ch_cfg->num; if (chan >= mhi_cntrl->max_chan) { - dev_err(dev, "Channel %d not available\n", chan); + MHI_ERR(dev, "Channel %d not available\n", chan); goto error_chan_cfg; } @@ -816,7 +816,7 @@ static int parse_ch_cfg(struct mhi_controller *mhi_cntrl, * should be DMA_FROM_DEVICE */ if (mhi_chan->pre_alloc && mhi_chan->dir != DMA_FROM_DEVICE) { - dev_err(dev, "Invalid channel configuration\n"); + MHI_ERR(dev, "Invalid channel configuration\n"); goto error_chan_cfg; } @@ -826,14 +826,14 @@ static int parse_ch_cfg(struct mhi_controller *mhi_cntrl, */ if ((mhi_chan->dir == DMA_BIDIRECTIONAL || mhi_chan->dir == DMA_NONE) && !mhi_chan->offload_ch) { - dev_err(dev, "Invalid channel configuration\n"); + MHI_ERR(dev, "Invalid channel configuration\n"); goto error_chan_cfg; } if (!mhi_chan->offload_ch) { mhi_chan->db_cfg.brstmode = ch_cfg->doorbell; if (MHI_INVALID_BRSTMODE(mhi_chan->db_cfg.brstmode)) { - dev_err(dev, "Invalid Door bell mode\n"); + MHI_ERR(dev, "Invalid Door bell mode\n"); goto error_chan_cfg; } } @@ -1119,12 +1119,12 @@ int mhi_prepare_for_power_up(struct mhi_controller *mhi_cntrl) ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->regs, BHIOFF, &bhi_off); if (ret) { - dev_err(dev, "Error getting BHI offset\n"); + MHI_ERR(dev, "Error getting BHI offset\n"); goto error_reg_offset; } if (bhi_off >= mhi_cntrl->reg_len) { - dev_err(dev, "BHI offset: 0x%x is out of range: 0x%zx\n", + MHI_ERR(dev, "BHI offset: 0x%x is out of range: 0x%zx\n", bhi_off, mhi_cntrl->reg_len); ret = -EINVAL; goto error_reg_offset; @@ -1135,12 +1135,12 @@ int mhi_prepare_for_power_up(struct mhi_controller *mhi_cntrl) ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->regs, BHIEOFF, &bhie_off); if (ret) { - dev_err(dev, "Error getting BHIE offset\n"); + MHI_ERR(dev, "Error getting BHIE offset\n"); goto error_reg_offset; } if (bhie_off >= mhi_cntrl->reg_len) { - dev_err(dev, + MHI_ERR(dev, "BHIe offset: 0x%x is out of range: 0x%zx\n", bhie_off, mhi_cntrl->reg_len); ret = -EINVAL; diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 9baae90e4fbe..c14dd41298ae 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -325,7 +325,7 @@ int mhi_destroy_device(struct device *dev, void *data) put_device(&dl_chan->mhi_dev->dev); } - dev_dbg(&mhi_cntrl->mhi_dev->dev, "destroy device for chan:%s\n", + MHI_VERB(dev, "destroy device for chan:%s\n", mhi_dev->name); /* Notify the client and remove the device from MHI bus */ @@ -398,7 +398,7 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl) mhi_dev->dl_event_id = mhi_chan->er_index; break; default: - dev_err(dev, "Direction not supported\n"); + MHI_ERR(dev, "Direction not supported\n"); put_device(&mhi_dev->dev); return; } @@ -477,7 +477,7 @@ irqreturn_t mhi_irq_handler(int irq_number, void *priv) void *dev_rp; if (!is_valid_ring_ptr(ev_ring, ptr)) { - dev_err(&mhi_cntrl->mhi_dev->dev, + MHI_ERR(dev, "Event ring rp points outside of the event ring\n"); return IRQ_HANDLED; } @@ -510,7 +510,7 @@ irqreturn_t mhi_irq_handler(int irq_number, void *priv) queue_work(mhi_cntrl->hiprio_wq, &mhi_event->work); break; default: - dev_dbg(dev, "skip unknown priority event\n"); + MHI_VERB(dev, "skip unknown priority event\n"); break; } @@ -533,13 +533,13 @@ irqreturn_t mhi_intvec_threaded_handler(int irq_number, void *priv) state = mhi_get_mhi_state(mhi_cntrl); ee = mhi_get_exec_env(mhi_cntrl); - dev_dbg(dev, "local ee: %s state: %s device ee: %s state: %s\n", + MHI_VERB(dev, "local ee: %s state: %s device ee: %s state: %s\n", TO_MHI_EXEC_STR(mhi_cntrl->ee), mhi_state_str(mhi_cntrl->dev_state), TO_MHI_EXEC_STR(ee), mhi_state_str(state)); if (state == MHI_STATE_SYS_ERR) { - dev_dbg(dev, "System error detected\n"); + MHI_VERB(dev, "System error detected\n"); pm_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_SYS_ERR_DETECT); } @@ -652,7 +652,7 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl, u16 xfer_len; if (!is_valid_ring_ptr(tre_ring, ptr)) { - dev_err(&mhi_cntrl->mhi_dev->dev, + MHI_ERR(dev, "Event element points outside of the tre ring\n"); break; } @@ -705,7 +705,7 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl, mhi_chan->dir, buf_info->cb_buf, buf_info->len, MHI_EOT)) { - dev_err(dev, + MHI_ERR(dev, "Error recycling buffer for chan:%d\n", mhi_chan->chan); kfree(buf_info->cb_buf); @@ -821,7 +821,7 @@ static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl, u32 chan; if (!is_valid_ring_ptr(mhi_ring, ptr)) { - dev_err(&mhi_cntrl->mhi_dev->dev, + MHI_ERR(dev, "Event element points outside of the cmd ring\n"); return; } @@ -848,7 +848,7 @@ static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl, complete(&mhi_chan->completion); write_unlock_bh(&mhi_chan->lock); } else { - dev_err(&mhi_cntrl->mhi_dev->dev, + MHI_ERR(dev, "Completion packet for invalid channel ID: %d\n", chan); } @@ -879,7 +879,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, return -EIO; if (!is_valid_ring_ptr(ev_ring, ptr)) { - dev_err(&mhi_cntrl->mhi_dev->dev, + MHI_ERR(dev, "Event ring rp points outside of the event ring\n"); return -EIO; } @@ -890,7 +890,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, while (dev_rp != local_rp) { enum mhi_pkt_type type = MHI_TRE_GET_EV_TYPE(local_rp); - dev_dbg(dev, "RP:0x%llx Processing Event:0x%llx 0x%08x 0x%08x\n", + MHI_VERB(dev, "RP:0x%llx Processing Event:0x%llx 0x%08x 0x%08x\n", (u64)mhi_to_physical(ev_ring, local_rp), local_rp->ptr, local_rp->dword[0], local_rp->dword[1]); @@ -906,7 +906,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, link_info->target_link_width = MHI_TRE_GET_EV_LINKWIDTH(local_rp); write_unlock_irq(&mhi_cntrl->pm_lock); - dev_dbg(dev, "Received BW_REQ event\n"); + MHI_VERB(dev, "Received BW_REQ event\n"); mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_BW_REQ); break; } @@ -916,7 +916,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, new_state = MHI_TRE_GET_EV_STATE(local_rp); - dev_dbg(dev, "State change event to state: %s\n", + MHI_VERB(dev, "State change event to state: %s\n", mhi_state_str(new_state)); switch (new_state) { @@ -933,7 +933,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, { enum mhi_pm_state pm_state; - dev_dbg(dev, "System error detected\n"); + MHI_VERB(dev, "System error detected\n"); write_lock_irq(&mhi_cntrl->pm_lock); pm_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_SYS_ERR_DETECT); @@ -943,7 +943,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, break; } default: - dev_err(dev, "Invalid state: %s\n", + MHI_ERR(dev, "Invalid state: %s\n", mhi_state_str(new_state)); } @@ -957,7 +957,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, enum dev_st_transition st = DEV_ST_TRANSITION_MAX; enum mhi_ee_type event = MHI_TRE_GET_EV_EXECENV(local_rp); - dev_dbg(dev, "Received EE event: %s\n", + MHI_VERB(dev, "Received EE event: %s\n", TO_MHI_EXEC_STR(event)); switch (event) { case MHI_EE_SBL: @@ -978,7 +978,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, wake_up_all(&mhi_cntrl->state_event); break; default: - dev_err(dev, + MHI_ERR(dev, "Unhandled EE event: 0x%x\n", type); } if (st != DEV_ST_TRANSITION_MAX) @@ -1004,7 +1004,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, } break; default: - dev_err(dev, "Unhandled event type: %d\n", type); + MHI_ERR(dev, "Unhandled event type: %d\n", type); break; } @@ -1013,7 +1013,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, ptr = le64_to_cpu(er_ctxt->rp); if (!is_valid_ring_ptr(ev_ring, ptr)) { - dev_err(&mhi_cntrl->mhi_dev->dev, + MHI_ERR(dev, "Event ring rp points outside of the event ring\n"); return -EIO; } @@ -1048,7 +1048,7 @@ int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl, return -EIO; if (!is_valid_ring_ptr(ev_ring, ptr)) { - dev_err(&mhi_cntrl->mhi_dev->dev, + MHI_ERR(dev, "Event ring rp points outside of the event ring\n"); return -EIO; } @@ -1059,7 +1059,7 @@ int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl, while (dev_rp != local_rp && event_quota > 0) { enum mhi_pkt_type type = MHI_TRE_GET_EV_TYPE(local_rp); - dev_dbg(dev, "Processing Event:0x%llx 0x%08x 0x%08x\n", + MHI_VERB(dev, "Processing Event:0x%llx 0x%08x 0x%08x\n", local_rp->ptr, local_rp->dword[0], local_rp->dword[1]); chan = MHI_TRE_GET_EV_CHID(local_rp); @@ -1088,7 +1088,7 @@ int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl, ptr = le64_to_cpu(er_ctxt->rp); if (!is_valid_ring_ptr(ev_ring, ptr)) { - dev_err(&mhi_cntrl->mhi_dev->dev, + MHI_ERR(dev, "Event ring rp points outside of the event ring\n"); return -EIO; } @@ -1152,7 +1152,7 @@ void mhi_ctrl_ev_task(unsigned long data) write_lock_irq(&mhi_cntrl->pm_lock); state = mhi_get_mhi_state(mhi_cntrl); if (state == MHI_STATE_SYS_ERR) { - dev_dbg(dev, "System error detected\n"); + MHI_VERB(dev, "System error detected\n"); pm_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_SYS_ERR_DETECT); } @@ -1169,7 +1169,7 @@ void mhi_process_ev_work(struct work_struct *work) struct mhi_controller *mhi_cntrl = mhi_event->mhi_cntrl; struct device *dev = mhi_cntrl->cntrl_dev; - dev_dbg(dev, "Enter with pm_state:%s MHI_STATE:%s ee:%s\n", + MHI_VERB(dev, "Enter with pm_state:%s MHI_STATE:%s ee:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), mhi_state_str(mhi_cntrl->dev_state), TO_MHI_EXEC_STR(mhi_cntrl->ee)); @@ -1399,7 +1399,7 @@ int mhi_send_cmd(struct mhi_controller *mhi_cntrl, &cmd_tre->dword[1]); break; default: - dev_err(dev, "Command not supported\n"); + MHI_ERR(dev, "Command not supported\n"); break; } @@ -1422,7 +1422,7 @@ static int mhi_update_channel_state(struct mhi_controller *mhi_cntrl, enum mhi_cmd_type cmd = MHI_CMD_NOP; int ret; - dev_dbg(dev, "%d: Updating channel state to: %s\n", mhi_chan->chan, + MHI_VERB(dev, "%d: Updating channel state to: %s\n", mhi_chan->chan, TO_CH_STATE_TYPE_STR(to_state)); switch (to_state) { @@ -1453,7 +1453,7 @@ static int mhi_update_channel_state(struct mhi_controller *mhi_cntrl, cmd = MHI_CMD_START_CHAN; break; default: - dev_err(dev, "%d: Channel state update to %s not allowed\n", + MHI_ERR(dev, "%d: Channel state update to %s not allowed\n", mhi_chan->chan, TO_CH_STATE_TYPE_STR(to_state)); return -EINVAL; } @@ -1467,7 +1467,7 @@ static int mhi_update_channel_state(struct mhi_controller *mhi_cntrl, reinit_completion(&mhi_chan->completion); ret = mhi_send_cmd(mhi_cntrl, mhi_chan, cmd); if (ret) { - dev_err(dev, "%d: Failed to send %s channel command\n", + MHI_ERR(dev, "%d: Failed to send %s channel command\n", mhi_chan->chan, TO_CH_STATE_TYPE_STR(to_state)); goto exit_channel_update; } @@ -1475,7 +1475,7 @@ static int mhi_update_channel_state(struct mhi_controller *mhi_cntrl, ret = wait_for_completion_timeout(&mhi_chan->completion, msecs_to_jiffies(mhi_cntrl->timeout_ms)); if (!ret || mhi_chan->ccs != MHI_EV_CC_SUCCESS) { - dev_err(dev, + MHI_ERR(dev, "%d: Failed to receive %s channel command completion\n", mhi_chan->chan, TO_CH_STATE_TYPE_STR(to_state)); ret = -EIO; @@ -1491,7 +1491,7 @@ static int mhi_update_channel_state(struct mhi_controller *mhi_cntrl, write_unlock_irq(&mhi_chan->lock); } - dev_dbg(dev, "%d: Channel state change to %s successful\n", + MHI_VERB(dev, "%d: Channel state change to %s successful\n", mhi_chan->chan, TO_CH_STATE_TYPE_STR(to_state)); exit_channel_update: @@ -1510,7 +1510,7 @@ static void mhi_unprepare_channel(struct mhi_controller *mhi_cntrl, mutex_lock(&mhi_chan->mutex); if (!(BIT(mhi_cntrl->ee) & mhi_chan->ee_mask)) { - dev_dbg(dev, "Current EE: %s Required EE Mask: 0x%x\n", + MHI_VERB(dev, "Current EE: %s Required EE Mask: 0x%x\n", TO_MHI_EXEC_STR(mhi_cntrl->ee), mhi_chan->ee_mask); goto exit_unprepare_channel; } @@ -1519,7 +1519,7 @@ static void mhi_unprepare_channel(struct mhi_controller *mhi_cntrl, ret = mhi_update_channel_state(mhi_cntrl, mhi_chan, MHI_CH_STATE_TYPE_RESET); if (ret) - dev_err(dev, "%d: Failed to reset channel, still resetting\n", + MHI_ERR(dev, "%d: Failed to reset channel, still resetting\n", mhi_chan->chan); exit_unprepare_channel: @@ -1531,7 +1531,7 @@ static void mhi_unprepare_channel(struct mhi_controller *mhi_cntrl, mhi_reset_chan(mhi_cntrl, mhi_chan); mhi_deinit_chan_ctxt(mhi_cntrl, mhi_chan); } - dev_dbg(dev, "%d: successfully reset\n", mhi_chan->chan); + MHI_VERB(dev, "%d: successfully reset\n", mhi_chan->chan); mutex_unlock(&mhi_chan->mutex); } @@ -1543,7 +1543,7 @@ int mhi_prepare_channel(struct mhi_controller *mhi_cntrl, struct device *dev = &mhi_chan->mhi_dev->dev; if (!(BIT(mhi_cntrl->ee) & mhi_chan->ee_mask)) { - dev_err(dev, "Current EE: %s Required EE Mask: 0x%x\n", + MHI_ERR(dev, "Current EE: %s Required EE Mask: 0x%x\n", TO_MHI_EXEC_STR(mhi_cntrl->ee), mhi_chan->ee_mask); return -ENOTCONN; } @@ -1633,7 +1633,7 @@ static void mhi_mark_stale_events(struct mhi_controller *mhi_cntrl, unsigned long flags; dma_addr_t ptr; - dev_dbg(dev, "Marking all events for chan: %d as stale\n", chan); + MHI_VERB(dev, "Marking all events for chan: %d as stale\n", chan); ev_ring = &mhi_event->ring; @@ -1642,7 +1642,7 @@ static void mhi_mark_stale_events(struct mhi_controller *mhi_cntrl, ptr = le64_to_cpu(er_ctxt->rp); if (!is_valid_ring_ptr(ev_ring, ptr)) { - dev_err(&mhi_cntrl->mhi_dev->dev, + MHI_ERR(dev, "Event ring rp points outside of the event ring\n"); dev_rp = ev_ring->rp; } else { @@ -1660,7 +1660,7 @@ static void mhi_mark_stale_events(struct mhi_controller *mhi_cntrl, local_rp = ev_ring->base; } - dev_dbg(dev, "Finished marking events as stale events\n"); + MHI_VERB(dev, "Finished marking events as stale events\n"); spin_unlock_irqrestore(&mhi_event->lock, flags); } diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index 78c2b483080a..85a464241968 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -141,7 +141,7 @@ void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl, enum mhi_state state) } if (ret) - dev_err(dev, "Failed to set MHI state to: %s\n", + MHI_ERR(dev, "Failed to set MHI state to: %s\n", mhi_state_str(state)); } @@ -205,7 +205,7 @@ int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl) /* Check if device entered error state */ if (MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state)) { - dev_err(dev, "Device link is not accessible\n"); + MHI_ERR(dev, "Device link is not accessible\n"); return -EIO; } @@ -213,25 +213,25 @@ int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl) ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, MHICTRL_RESET_MASK, 0, interval_us); if (ret) { - dev_err(dev, "Device failed to clear MHI Reset\n"); + MHI_ERR(dev, "Device failed to clear MHI Reset\n"); return ret; } ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHISTATUS, MHISTATUS_READY_MASK, 1, interval_us); if (ret) { - dev_err(dev, "Device failed to enter MHI Ready\n"); + MHI_ERR(dev, "Device failed to enter MHI Ready\n"); return ret; } - dev_dbg(dev, "Device in READY State\n"); + MHI_VERB(dev, "Device in READY State\n"); write_lock_irq(&mhi_cntrl->pm_lock); cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_POR); mhi_cntrl->dev_state = MHI_STATE_READY; write_unlock_irq(&mhi_cntrl->pm_lock); if (cur_state != MHI_PM_POR) { - dev_err(dev, "Error moving to state %s from %s\n", + MHI_ERR(dev, "Error moving to state %s from %s\n", to_mhi_pm_state_str(MHI_PM_POR), to_mhi_pm_state_str(cur_state)); return -EIO; @@ -239,14 +239,14 @@ int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl) read_lock_bh(&mhi_cntrl->pm_lock); if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) { - dev_err(dev, "Device registers not accessible\n"); + MHI_ERR(dev, "Device registers not accessible\n"); goto error_mmio; } /* Configure MMIO registers */ ret = mhi_init_mmio(mhi_cntrl); if (ret) { - dev_err(dev, "Error configuring MMIO registers\n"); + MHI_ERR(dev, "Error configuring MMIO registers\n"); goto error_mmio; } @@ -277,7 +277,7 @@ int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl) cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_M0); write_unlock_irq(&mhi_cntrl->pm_lock); if (unlikely(cur_state != MHI_PM_M0)) { - dev_err(dev, "Unable to transition to M0 state\n"); + MHI_ERR(dev, "Unable to transition to M0 state\n"); return -EIO; } mhi_cntrl->M0++; @@ -353,7 +353,7 @@ void mhi_pm_m1_transition(struct mhi_controller *mhi_cntrl) /* If there are any pending resources, exit M2 immediately */ if (unlikely(atomic_read(&mhi_cntrl->pending_pkts) || atomic_read(&mhi_cntrl->dev_wake))) { - dev_dbg(dev, + MHI_VERB(dev, "Exiting M2, pending_pkts: %d dev_wake: %d\n", atomic_read(&mhi_cntrl->pending_pkts), atomic_read(&mhi_cntrl->dev_wake)); @@ -380,7 +380,7 @@ int mhi_pm_m3_transition(struct mhi_controller *mhi_cntrl) state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_M3); write_unlock_irq(&mhi_cntrl->pm_lock); if (state != MHI_PM_M3) { - dev_err(dev, "Unable to transition to M3 state\n"); + MHI_ERR(dev, "Unable to transition to M3 state\n"); return -EIO; } @@ -397,7 +397,7 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) enum mhi_ee_type ee = MHI_EE_MAX, current_ee = mhi_cntrl->ee; int ret; - dev_dbg(dev, "Processing Mission Mode transition\n"); + MHI_VERB(dev, "Processing Mission Mode transition\n"); write_lock_irq(&mhi_cntrl->pm_lock); if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) @@ -466,7 +466,7 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) struct device *dev = &mhi_cntrl->mhi_dev->dev; int ret, i; - dev_dbg(dev, "Processing disable transition with PM state: %s\n", + MHI_VERB(dev, "Processing disable transition with PM state: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state)); mhi_reset_reg_write_q(mhi_cntrl); @@ -480,14 +480,14 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) if ((!MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state)) && (mhi_cntrl->rddm_image && mhi_get_exec_env(mhi_cntrl) != MHI_EE_RDDM)) { - dev_dbg(dev, "Triggering MHI Reset in device\n"); + MHI_VERB(dev, "Triggering MHI Reset in device\n"); mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); /* Wait for the reset bit to be cleared by the device */ ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, MHICTRL_RESET_MASK, 0, 25000); if (ret) - dev_err(dev, "Device failed to clear MHI Reset\n"); + MHI_ERR(dev, "Device failed to clear MHI Reset\n"); /* * Device will clear BHI_INTVEC as a part of RESET processing, @@ -501,11 +501,11 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) MHISTATUS, MHISTATUS_READY_MASK, 1, 25000); if (ret) - dev_err(dev, "Device failed to enter READY state\n"); + MHI_ERR(dev, "Device failed to enter READY state\n"); } } - dev_dbg(dev, + MHI_VERB(dev, "Waiting for all pending event ring processing to complete\n"); mhi_event = mhi_cntrl->mhi_event; for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { @@ -521,10 +521,10 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) /* Release lock and wait for all pending threads to complete */ mutex_unlock(&mhi_cntrl->pm_mutex); mhi_misc_disable(mhi_cntrl); - dev_dbg(dev, "Waiting for all pending threads to complete\n"); + MHI_VERB(dev, "Waiting for all pending threads to complete\n"); wake_up_all(&mhi_cntrl->state_event); - dev_dbg(dev, "Reset all active channels and remove MHI devices\n"); + MHI_VERB(dev, "Reset all active channels and remove MHI devices\n"); device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_destroy_device); mutex_lock(&mhi_cntrl->pm_mutex); @@ -533,7 +533,7 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) WARN_ON(atomic_read(&mhi_cntrl->pending_pkts)); /* Reset the ev rings and cmd rings */ - dev_dbg(dev, "Resetting EV CTXT and CMD CTXT\n"); + MHI_VERB(dev, "Resetting EV CTXT and CMD CTXT\n"); mhi_cmd = mhi_cntrl->mhi_cmd; cmd_ctxt = mhi_cntrl->mhi_ctxt->cmd_ctxt; for (i = 0; i < NR_OF_CMD_RINGS; i++, mhi_cmd++, cmd_ctxt++) { @@ -566,11 +566,11 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_DISABLE); write_unlock_irq(&mhi_cntrl->pm_lock); if (unlikely(cur_state != MHI_PM_DISABLE)) - dev_err(dev, "Error moving from PM state: %s to: %s\n", + MHI_ERR(dev, "Error moving from PM state: %s to: %s\n", to_mhi_pm_state_str(cur_state), to_mhi_pm_state_str(MHI_PM_DISABLE)); - dev_dbg(dev, "Exiting with PM state: %s, MHI state: %s\n", + MHI_VERB(dev, "Exiting with PM state: %s, MHI state: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), mhi_state_str(mhi_cntrl->dev_state)); @@ -589,7 +589,7 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) struct device *dev = &mhi_cntrl->mhi_dev->dev; int ret, i; - dev_dbg(dev, "Transitioning from PM state: %s to: %s\n", + MHI_VERB(dev, "Transitioning from PM state: %s to: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), to_mhi_pm_state_str(MHI_PM_SYS_ERR_PROCESS)); @@ -603,7 +603,7 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) write_unlock_irq(&mhi_cntrl->pm_lock); if (cur_state != MHI_PM_SYS_ERR_PROCESS) { - dev_err(dev, "Failed to transition from PM state: %s to: %s\n", + MHI_ERR(dev, "Failed to transition from PM state: %s to: %s\n", to_mhi_pm_state_str(cur_state), to_mhi_pm_state_str(MHI_PM_SYS_ERR_PROCESS)); goto exit_sys_error_transition; @@ -620,7 +620,7 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) u32 in_reset = -1; unsigned long timeout = msecs_to_jiffies(mhi_cntrl->timeout_ms); - dev_dbg(dev, "Triggering MHI Reset in device\n"); + MHI_VERB(dev, "Triggering MHI Reset in device\n"); mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); /* Wait for the reset bit to be cleared by the device */ @@ -632,7 +632,7 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) &in_reset) || !in_reset, timeout); if (!ret || in_reset) { - dev_err(dev, "Device failed to exit MHI Reset state\n"); + MHI_ERR(dev, "Device failed to exit MHI Reset state\n"); goto exit_sys_error_transition; } @@ -643,7 +643,7 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); } - dev_dbg(dev, + MHI_VERB(dev, "Waiting for all pending event ring processing to complete\n"); mhi_event = mhi_cntrl->mhi_event; for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { @@ -658,10 +658,10 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) /* Release lock and wait for all pending threads to complete */ mutex_unlock(&mhi_cntrl->pm_mutex); mhi_misc_disable(mhi_cntrl); - dev_dbg(dev, "Waiting for all pending threads to complete\n"); + MHI_VERB(dev, "Waiting for all pending threads to complete\n"); wake_up_all(&mhi_cntrl->state_event); - dev_dbg(dev, "Reset all active channels and remove MHI devices\n"); + MHI_VERB(dev, "Reset all active channels and remove MHI devices\n"); device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_destroy_device); mutex_lock(&mhi_cntrl->pm_mutex); @@ -670,7 +670,7 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) WARN_ON(atomic_read(&mhi_cntrl->pending_pkts)); /* Reset the ev rings and cmd rings */ - dev_dbg(dev, "Resetting EV CTXT and CMD CTXT\n"); + MHI_VERB(dev, "Resetting EV CTXT and CMD CTXT\n"); mhi_cmd = mhi_cntrl->mhi_cmd; cmd_ctxt = mhi_cntrl->mhi_ctxt->cmd_ctxt; for (i = 0; i < NR_OF_CMD_RINGS; i++, mhi_cmd++, cmd_ctxt++) { @@ -704,7 +704,7 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_POR); write_unlock_irq(&mhi_cntrl->pm_lock); if (cur_state != MHI_PM_POR) { - dev_err(dev, "Error moving to state %s from %s\n", + MHI_ERR(dev, "Error moving to state %s from %s\n", to_mhi_pm_state_str(MHI_PM_POR), to_mhi_pm_state_str(cur_state)); goto exit_sys_error_transition; @@ -717,7 +717,7 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) mhi_queue_state_transition(mhi_cntrl, next_state); exit_sys_error_transition: - dev_dbg(dev, "Exiting with PM state: %s, MHI state: %s\n", + MHI_VERB(dev, "Exiting with PM state: %s, MHI state: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), mhi_state_str(mhi_cntrl->dev_state)); @@ -751,7 +751,7 @@ void mhi_pm_sys_err_handler(struct mhi_controller *mhi_cntrl) /* skip if controller supports RDDM */ if (mhi_cntrl->rddm_image) { - dev_dbg(dev, "Controller supports RDDM, skip SYS_ERROR\n"); + MHI_VERB(dev, "Controller supports RDDM, skip SYS_ERROR\n"); return; } @@ -774,7 +774,7 @@ void mhi_pm_st_worker(struct work_struct *work) list_for_each_entry_safe(itr, tmp, &head, node) { list_del(&itr->node); - dev_dbg(dev, "Handling state transition: %s\n", + MHI_VERB(dev, "Handling state transition: %s\n", TO_DEV_STATE_TRANS_STR(itr->state)); switch (itr->state) { @@ -882,7 +882,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) read_unlock_bh(&mhi_cntrl->pm_lock); if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { - dev_err(dev, + MHI_ERR(dev, "Could not enter M0/M1 state"); return -EIO; } @@ -895,11 +895,11 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) return -EBUSY; } - dev_dbg(dev, "Allowing M3 transition\n"); + MHI_VERB(dev, "Allowing M3 transition\n"); new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_M3_ENTER); if (new_state != MHI_PM_M3_ENTER) { write_unlock_irq(&mhi_cntrl->pm_lock); - dev_err(dev, + MHI_ERR(dev, "Error setting to PM state: %s from: %s\n", to_mhi_pm_state_str(MHI_PM_M3_ENTER), to_mhi_pm_state_str(mhi_cntrl->pm_state)); @@ -909,7 +909,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) /* Set MHI to M3 and wait for completion */ mhi_set_mhi_state(mhi_cntrl, MHI_STATE_M3); write_unlock_irq(&mhi_cntrl->pm_lock); - dev_dbg(dev, "Waiting for M3 completion\n"); + MHI_VERB(dev, "Waiting for M3 completion\n"); /* finish reg writes before D3 cold */ mhi_force_reg_write(mhi_cntrl); @@ -924,7 +924,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) panic("Timedout waiting for M3 ACK"); return -EIO; } else if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { - dev_err(dev, + MHI_ERR(dev, "Did not enter M3 state, MHI state: %s, PM state: %s\n", mhi_state_str(mhi_cntrl->dev_state), to_mhi_pm_state_str(mhi_cntrl->pm_state)); @@ -950,7 +950,7 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) enum mhi_pm_state cur_state; int ret; - dev_dbg(dev, "Entered with PM state: %s, MHI state: %s\n", + MHI_VERB(dev, "Entered with PM state: %s, MHI state: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), mhi_state_str(mhi_cntrl->dev_state)); @@ -978,7 +978,7 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_M3_EXIT); if (cur_state != MHI_PM_M3_EXIT) { write_unlock_irq(&mhi_cntrl->pm_lock); - dev_info(dev, + MHI_LOG(dev, "Error setting to PM state: %s from: %s\n", to_mhi_pm_state_str(MHI_PM_M3_EXIT), to_mhi_pm_state_str(mhi_cntrl->pm_state)); @@ -998,7 +998,7 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { if (mhi_in_rddm(mhi_cntrl)) return 0; - dev_err(dev, + MHI_ERR(dev, "Did not enter M0 state, MHI state: %s, PM state: %s\n", mhi_state_str(mhi_cntrl->dev_state), to_mhi_pm_state_str(mhi_cntrl->pm_state)); @@ -1131,7 +1131,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) u32 interval_us = 25000; /* poll register field every 25 milliseconds */ int ret, i; - dev_info(dev, "Requested to power ON\n"); + MHI_LOG(dev, "Requested to power ON\n"); /* Supply default wake routines if not provided by controller driver */ if (!mhi_cntrl->wake_get || !mhi_cntrl->wake_put || @@ -1155,14 +1155,14 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) /* Confirm that the device is in valid exec env */ if (!MHI_POWER_UP_CAPABLE(current_ee)) { - dev_err(dev, "%s is not a valid EE for power on\n", + MHI_ERR(dev, "%s is not a valid EE for power on\n", TO_MHI_EXEC_STR(current_ee)); ret = -EIO; goto error_exit; } state = mhi_get_mhi_state(mhi_cntrl); - dev_dbg(dev, "Attempting power on with EE: %s, state: %s\n", + MHI_VERB(dev, "Attempting power on with EE: %s, state: %s\n", TO_MHI_EXEC_STR(current_ee), mhi_state_str(state)); if (state == MHI_STATE_SYS_ERR) { @@ -1170,7 +1170,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, MHICTRL_RESET_MASK, 0, interval_us); if (ret) { - dev_info(dev, "Failed to reset MHI due to syserr state\n"); + MHI_LOG(dev, "Failed to reset MHI due to syserr state\n"); goto error_exit; } @@ -1199,7 +1199,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) mutex_unlock(&mhi_cntrl->pm_mutex); - dev_info(dev, "Power on setup success\n"); + MHI_LOG(dev, "Power on setup success\n"); return 0; @@ -1231,7 +1231,7 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) cur_state = mhi_tryset_pm_state(mhi_cntrl, transition_state); if (cur_state != transition_state) { - dev_err(dev, "Failed to move to state: %s from: %s\n", + MHI_ERR(dev, "Failed to move to state: %s from: %s\n", to_mhi_pm_state_str(transition_state), to_mhi_pm_state_str(mhi_cntrl->pm_state)); /* Force link down or error fatal detected state */ @@ -1287,7 +1287,7 @@ int mhi_force_rddm_mode(struct mhi_controller *mhi_cntrl) if (mhi_cntrl->ee == MHI_EE_RDDM) return 0; - dev_dbg(dev, "Triggering SYS_ERR to force RDDM state\n"); + MHI_VERB(dev, "Triggering SYS_ERR to force RDDM state\n"); mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR); /* Wait for RDDM event */