drivers/net/wwan/iosm/iosm_ipc_imem.c
Source file repositories/reference/linux-study-clean/drivers/net/wwan/iosm/iosm_ipc_imem.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wwan/iosm/iosm_ipc_imem.c- Extension
.c- Size
- 41370 bytes
- Lines
- 1501
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hiosm_ipc_chnl_cfg.hiosm_ipc_devlink.hiosm_ipc_flash.hiosm_ipc_imem.hiosm_ipc_port.hiosm_ipc_trace.hiosm_ipc_debugfs.h
Detected Declarations
function Copyrightfunction ipc_imem_msg_send_device_sleepfunction ipc_imem_dl_skb_allocfunction ipc_imem_tq_td_alloc_timerfunction ipc_imem_td_alloc_timer_cbfunction ipc_imem_tq_fast_update_timer_cbfunction ipc_imem_fast_update_timer_cbfunction ipc_imem_tq_adb_timer_cbfunction ipc_imem_adb_timer_cbfunction ipc_imem_setup_cp_mux_cap_initfunction ipc_imem_msg_send_feature_setfunction ipc_imem_td_update_timer_startfunction ipc_imem_hrtimer_stopfunction ipc_imem_adb_timer_startfunction ipc_imem_ul_write_tdfunction ipc_imem_ipc_init_checkfunction ipc_imem_dl_skb_processfunction ipc_imem_dl_pipe_processfunction ipc_imem_ul_pipe_processfunction ipc_imem_rom_irq_execfunction ipc_imem_tq_td_update_timer_cbfunction ipc_imem_slp_control_execfunction ipc_imem_tq_startup_timer_cbfunction ipc_imem_startup_timer_cbfunction ipc_imem_get_exec_stage_bufferedfunction ipc_imem_send_mdm_rdy_cbfunction ipc_imem_run_state_workerfunction ipc_imem_handle_irqfunction ipc_mmio_get_ipc_statefunction ipc_imem_tq_irq_cbfunction ipc_imem_ul_sendfunction ipc_imem_phase_update_checkfunction ipc_imem_pipe_openfunction ipc_imem_tq_pipe_td_allocfunction ipc_imem_td_update_timer_cbfunction ipc_imem_phase_updatefunction ipc_imem_pipe_closefunction ipc_imem_channel_closefunction ipc_imem_pm_suspendfunction ipc_imem_pm_s2idle_sleepfunction ipc_imem_pm_resumefunction ipc_imem_channel_freefunction ipc_imem_channel_allocfunction ipc_imem_channel_initfunction ipc_imem_channel_updatefunction ipc_imem_channel_resetfunction ipc_imem_pipe_cleanupfunction ipc_imem_device_ipc_uninit
Annotated Snippet
if (!ipc_imem_check_wwan_ips(channel)) {
hpda_ctrl_pending |=
ipc_protocol_ul_td_send(ipc_imem->ipc_protocol,
pipe, ul_list);
} else {
hpda_pending |=
ipc_protocol_ul_td_send(ipc_imem->ipc_protocol,
pipe, ul_list);
}
}
/* forced HP update needed for non data channels */
if (hpda_ctrl_pending) {
hpda_pending = false;
ipc_protocol_doorbell_trigger(ipc_imem->ipc_protocol,
IPC_HP_UL_WRITE_TD);
}
return hpda_pending;
}
void ipc_imem_ipc_init_check(struct iosm_imem *ipc_imem)
{
int timeout = IPC_MODEM_BOOT_TIMEOUT;
ipc_imem->ipc_requested_state = IPC_MEM_DEVICE_IPC_INIT;
/* Trigger the CP interrupt to enter the init state. */
ipc_doorbell_fire(ipc_imem->pcie, IPC_DOORBELL_IRQ_IPC,
IPC_MEM_DEVICE_IPC_INIT);
/* Wait for the CP update. */
do {
if (ipc_mmio_get_ipc_state(ipc_imem->mmio) ==
ipc_imem->ipc_requested_state) {
/* Prepare the MMIO space */
ipc_mmio_config(ipc_imem->mmio);
/* Trigger the CP irq to enter the running state. */
ipc_imem->ipc_requested_state =
IPC_MEM_DEVICE_IPC_RUNNING;
ipc_doorbell_fire(ipc_imem->pcie, IPC_DOORBELL_IRQ_IPC,
IPC_MEM_DEVICE_IPC_RUNNING);
return;
}
msleep(20);
} while (--timeout);
/* timeout */
dev_err(ipc_imem->dev, "%s: ipc_status(%d) ne. IPC_MEM_DEVICE_IPC_INIT",
ipc_imem_phase_get_string(ipc_imem->phase),
ipc_mmio_get_ipc_state(ipc_imem->mmio));
ipc_uevent_send(ipc_imem->dev, UEVENT_MDM_TIMEOUT);
}
/* Analyze the packet type and distribute it. */
static void ipc_imem_dl_skb_process(struct iosm_imem *ipc_imem,
struct ipc_pipe *pipe, struct sk_buff *skb)
{
u16 port_id;
if (!skb)
return;
/* An AT/control or IP packet is expected. */
switch (pipe->channel->ctype) {
case IPC_CTYPE_CTRL:
port_id = pipe->channel->channel_id;
ipc_pcie_addr_unmap(ipc_imem->pcie, IPC_CB(skb)->len,
IPC_CB(skb)->mapping,
IPC_CB(skb)->direction);
if (port_id == IPC_MEM_CTRL_CHL_ID_7)
ipc_imem_sys_devlink_notify_rx(ipc_imem->ipc_devlink,
skb);
else if (ipc_is_trace_channel(ipc_imem, port_id))
ipc_trace_port_rx(ipc_imem, skb);
else
wwan_port_rx(ipc_imem->ipc_port[port_id]->iosm_port,
skb);
break;
case IPC_CTYPE_WWAN:
if (pipe->channel->if_id == IPC_MEM_MUX_IP_CH_IF_ID)
ipc_mux_dl_decode(ipc_imem->mux, skb);
break;
default:
dev_err(ipc_imem->dev, "Invalid channel type");
break;
}
Annotation
- Immediate include surface: `linux/delay.h`, `iosm_ipc_chnl_cfg.h`, `iosm_ipc_devlink.h`, `iosm_ipc_flash.h`, `iosm_ipc_imem.h`, `iosm_ipc_port.h`, `iosm_ipc_trace.h`, `iosm_ipc_debugfs.h`.
- Detected declarations: `function Copyright`, `function ipc_imem_msg_send_device_sleep`, `function ipc_imem_dl_skb_alloc`, `function ipc_imem_tq_td_alloc_timer`, `function ipc_imem_td_alloc_timer_cb`, `function ipc_imem_tq_fast_update_timer_cb`, `function ipc_imem_fast_update_timer_cb`, `function ipc_imem_tq_adb_timer_cb`, `function ipc_imem_adb_timer_cb`, `function ipc_imem_setup_cp_mux_cap_init`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source 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.