drivers/bus/mhi/host/main.c
Source file repositories/reference/linux-study-clean/drivers/bus/mhi/host/main.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/bus/mhi/host/main.c- Extension
.c- Size
- 42565 bytes
- Lines
- 1629
- Domain
- Driver Families
- Bucket
- drivers/bus
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hlinux/device.hlinux/dma-direction.hlinux/dma-mapping.hlinux/interrupt.hlinux/list.hlinux/mhi.hlinux/module.hlinux/skbuff.hlinux/slab.hinternal.htrace.h
Detected Declarations
function Copyrightfunction mhi_read_reg_fieldfunction mhi_poll_reg_fieldfunction mhi_write_regfunction mhi_write_reg_fieldfunction mhi_write_dbfunction mhi_db_brstmodefunction mhi_db_brstmode_disablefunction mhi_ring_er_dbfunction mhi_ring_cmd_dbfunction mhi_ring_chan_dbfunction mhi_get_exec_envfunction mhi_get_mhi_statefunction mhi_soc_resetfunction mhi_map_single_no_bbfunction mhi_map_single_use_bbfunction mhi_unmap_single_no_bbfunction mhi_unmap_single_use_bbfunction get_nr_avail_ring_elementsfunction mhi_add_ring_elementfunction mhi_del_ring_elementfunction is_valid_ring_ptrfunction mhi_destroy_devicefunction mhi_unregister_controllerfunction mhi_get_free_desc_countfunction mhi_notifyfunction mhi_create_devicesfunction mhi_irq_handlerfunction mhi_ctxtfunction mhi_intvec_threaded_handlerfunction mhi_intvec_handlerfunction mhi_recycle_ev_ring_elementfunction parse_xfer_eventfunction parse_rsc_eventfunction mhi_process_cmd_completionfunction mhi_process_ctrl_ev_ringfunction mhi_process_data_event_ringfunction mhi_ev_taskfunction mhi_ctrl_ev_taskfunction mhi_is_ring_fullfunction mhi_queuefunction mhi_queue_skbfunction mhi_gen_trefunction mhi_queue_buffunction mhi_queue_is_fullfunction mhi_send_cmdfunction mhi_update_channel_statefunction mhi_unprepare_channel
Annotated Snippet
ret = device_add(&mhi_dev->dev);
if (ret)
put_device(&mhi_dev->dev);
}
}
irqreturn_t mhi_irq_handler(int irq_number, void *dev)
{
struct mhi_event *mhi_event = dev;
struct mhi_controller *mhi_cntrl = mhi_event->mhi_cntrl;
struct mhi_event_ctxt *er_ctxt;
struct mhi_ring *ev_ring = &mhi_event->ring;
dma_addr_t ptr;
void *dev_rp;
/*
* If CONFIG_DEBUG_SHIRQ is set, the IRQ handler will get invoked during __free_irq()
* and by that time mhi_ctxt() would've freed. So check for the existence of mhi_ctxt
* before handling the IRQs.
*/
if (!mhi_cntrl->mhi_ctxt) {
dev_dbg(&mhi_cntrl->mhi_dev->dev,
"mhi_ctxt has been freed\n");
return IRQ_HANDLED;
}
er_ctxt = &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index];
ptr = le64_to_cpu(er_ctxt->rp);
if (!is_valid_ring_ptr(ev_ring, ptr)) {
dev_err(&mhi_cntrl->mhi_dev->dev,
"Event ring rp points outside of the event ring\n");
return IRQ_HANDLED;
}
dev_rp = mhi_to_virtual(ev_ring, ptr);
/* Only proceed if event ring has pending events */
if (ev_ring->rp == dev_rp)
return IRQ_HANDLED;
/* For client managed event ring, notify pending data */
if (mhi_event->cl_manage) {
struct mhi_chan *mhi_chan = mhi_event->mhi_chan;
struct mhi_device *mhi_dev = mhi_chan->mhi_dev;
if (mhi_dev)
mhi_notify(mhi_dev, MHI_CB_PENDING_DATA);
} else {
tasklet_schedule(&mhi_event->task);
}
return IRQ_HANDLED;
}
irqreturn_t mhi_intvec_threaded_handler(int irq_number, void *priv)
{
struct mhi_controller *mhi_cntrl = priv;
struct device *dev = &mhi_cntrl->mhi_dev->dev;
enum mhi_state state;
enum mhi_pm_state pm_state = 0;
enum mhi_ee_type ee;
write_lock_irq(&mhi_cntrl->pm_lock);
if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) {
write_unlock_irq(&mhi_cntrl->pm_lock);
goto exit_intvec;
}
state = mhi_get_mhi_state(mhi_cntrl);
ee = mhi_get_exec_env(mhi_cntrl);
trace_mhi_intvec_states(mhi_cntrl, ee, state);
if (state == MHI_STATE_SYS_ERR) {
dev_dbg(dev, "System error detected\n");
pm_state = mhi_tryset_pm_state(mhi_cntrl,
MHI_PM_SYS_ERR_DETECT);
}
write_unlock_irq(&mhi_cntrl->pm_lock);
if (pm_state != MHI_PM_SYS_ERR_DETECT)
goto exit_intvec;
switch (ee) {
case MHI_EE_RDDM:
/* proceed if power down is not already in progress */
if (mhi_cntrl->rddm_image && mhi_is_active(mhi_cntrl)) {
mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_RDDM);
mhi_cntrl->ee = ee;
mhi_uevent_notify(mhi_cntrl, mhi_cntrl->ee);
Annotation
- Immediate include surface: `linux/delay.h`, `linux/device.h`, `linux/dma-direction.h`, `linux/dma-mapping.h`, `linux/interrupt.h`, `linux/list.h`, `linux/mhi.h`, `linux/module.h`.
- Detected declarations: `function Copyright`, `function mhi_read_reg_field`, `function mhi_poll_reg_field`, `function mhi_write_reg`, `function mhi_write_reg_field`, `function mhi_write_db`, `function mhi_db_brstmode`, `function mhi_db_brstmode_disable`, `function mhi_ring_er_db`, `function mhi_ring_cmd_db`.
- Atlas domain: Driver Families / drivers/bus.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.