drivers/misc/mei/hw-me.c
Source file repositories/reference/linux-study-clean/drivers/misc/mei/hw-me.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/misc/mei/hw-me.c- Extension
.c- Size
- 42443 bytes
- Lines
- 1820
- Domain
- Driver Families
- Bucket
- drivers/misc
- 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.
- 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/pci.hlinux/kthread.hlinux/interrupt.hlinux/pm_runtime.hlinux/sizes.hlinux/delay.hmei_dev.hhbm.hhw-me.hhw-me-regs.hmei-trace.h
Detected Declarations
function Copyrightfunction mei_me_reg_writefunction mei_me_mecbrw_readfunction mei_me_hcbww_writefunction mei_me_mecsr_readfunction mei_hcsr_readfunction mei_hcsr_writefunction mei_hcsr_setfunction mei_hcsr_set_higfunction mei_me_d0i3c_readfunction mei_me_d0i3c_writefunction mei_me_trc_statusfunction mei_me_fw_statusfunction mei_csc_pg_blockedfunction mei_me_hw_configfunction mei_me_pg_statefunction me_intr_srcfunction me_intr_disablefunction me_intr_clearfunction mei_me_intr_clearfunction mei_me_intr_enablefunction mei_me_intr_disablefunction mei_me_synchronize_irqfunction mei_me_hw_reset_releasefunction mei_me_host_set_readyfunction mei_me_host_is_readyfunction mei_me_hw_is_readyfunction mei_me_hw_is_resettingfunction mei_gsc_pxp_checkfunction mei_me_hw_ready_waitfunction mei_me_hw_startfunction mei_hbuf_filled_slotsfunction mei_me_hbuf_is_emptyfunction mei_me_hbuf_empty_slotsfunction mei_me_hbuf_depthfunction mei_me_hbuf_writefunction mei_me_count_full_read_slotsfunction mei_me_read_slotsfunction mei_me_pg_setfunction mei_me_pg_unsetfunction mei_me_pg_legacy_enter_syncfunction mei_me_pg_legacy_exit_syncfunction mei_me_pg_in_transitionfunction mei_me_pg_is_enabledfunction mei_me_d0i3_setfunction mei_me_d0i3_unsetfunction mei_me_d0i3_enter_syncfunction mei_me_d0i3_enter
Annotated Snippet
if (!(reg & H_D0I3C_I3)) {
ret = -ETIME;
goto out;
}
}
ret = 0;
on:
hw->pg_state = MEI_PG_ON;
out:
dev->pg_event = MEI_PG_EVENT_IDLE;
dev_dbg(&dev->dev, "d0i3 enter ret = %d\n", ret);
return ret;
}
/**
* mei_me_d0i3_enter - perform d0i3 entry procedure
* no hbm PG handshake
* no waiting for confirmation; runs with interrupts
* disabled
*
* @dev: the device structure
*
* Return: 0 on success an error code otherwise
*/
static int mei_me_d0i3_enter(struct mei_device *dev)
{
struct mei_me_hw *hw = to_me_hw(dev);
u32 reg;
reg = mei_me_d0i3c_read(dev);
if (reg & H_D0I3C_I3) {
/* we are in d0i3, nothing to do */
dev_dbg(&dev->dev, "already d0i3 : set not needed\n");
goto on;
}
mei_me_d0i3_set(dev, false);
on:
hw->pg_state = MEI_PG_ON;
dev->pg_event = MEI_PG_EVENT_IDLE;
dev_dbg(&dev->dev, "d0i3 enter\n");
return 0;
}
/**
* mei_me_d0i3_exit_sync - perform d0i3 exit procedure
*
* @dev: the device structure
*
* Return: 0 on success an error code otherwise
*/
static int mei_me_d0i3_exit_sync(struct mei_device *dev)
{
struct mei_me_hw *hw = to_me_hw(dev);
int ret;
u32 reg;
dev->pg_event = MEI_PG_EVENT_INTR_WAIT;
reg = mei_me_d0i3c_read(dev);
if (!(reg & H_D0I3C_I3)) {
/* we are not in d0i3, nothing to do */
dev_dbg(&dev->dev, "d0i3 exit not needed\n");
ret = 0;
goto off;
}
reg = mei_me_d0i3_unset(dev);
if (!(reg & H_D0I3C_CIP)) {
dev_dbg(&dev->dev, "d0i3 exit wait not needed\n");
ret = 0;
goto off;
}
mutex_unlock(&dev->device_lock);
wait_event_timeout(dev->wait_pg,
dev->pg_event == MEI_PG_EVENT_INTR_RECEIVED,
dev->timeouts.d0i3);
mutex_lock(&dev->device_lock);
if (dev->pg_event != MEI_PG_EVENT_INTR_RECEIVED) {
reg = mei_me_d0i3c_read(dev);
if (reg & H_D0I3C_I3) {
ret = -ETIME;
goto out;
}
}
ret = 0;
Annotation
- Immediate include surface: `linux/pci.h`, `linux/kthread.h`, `linux/interrupt.h`, `linux/pm_runtime.h`, `linux/sizes.h`, `linux/delay.h`, `mei_dev.h`, `hbm.h`.
- Detected declarations: `function Copyright`, `function mei_me_reg_write`, `function mei_me_mecbrw_read`, `function mei_me_hcbww_write`, `function mei_me_mecsr_read`, `function mei_hcsr_read`, `function mei_hcsr_write`, `function mei_hcsr_set`, `function mei_hcsr_set_hig`, `function mei_me_d0i3c_read`.
- Atlas domain: Driver Families / drivers/misc.
- 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.