drivers/char/tpm/tpm_tis_i2c_cr50.c
Source file repositories/reference/linux-study-clean/drivers/char/tpm/tpm_tis_i2c_cr50.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/tpm/tpm_tis_i2c_cr50.c- Extension
.c- Size
- 21125 bytes
- Lines
- 838
- Domain
- Driver Families
- Bucket
- drivers/char
- 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.
- 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/acpi.hlinux/bug.hlinux/completion.hlinux/i2c.hlinux/interrupt.hlinux/module.hlinux/pm.hlinux/slab.hlinux/wait.htpm_tis_core.h
Detected Declarations
struct tpm_i2c_cr50_priv_datafunction tpm_cr50_i2c_int_handlerfunction tpm_cr50_i2c_wait_tpm_readyfunction tpm_cr50_i2c_enable_tpm_irqfunction tpm_cr50_i2c_disable_tpm_irqfunction tpm_cr50_i2c_transfer_messagefunction tpm_cr50_i2c_readfunction tpm_cr50_i2c_writefunction tpm_cr50_check_localityfunction tpm_cr50_release_localityfunction tpm_cr50_request_localityfunction tpm_cr50_i2c_tis_statusfunction tpm_cr50_i2c_tis_set_readyfunction tpm_cr50_i2c_get_burst_and_statusfunction tpm_cr50_i2c_tis_recvfunction tpm_cr50_i2c_tis_sendfunction tpm_cr50_i2c_req_canceledfunction tpm_cr50_i2c_is_firmware_power_managedfunction tpm_cr50_vid_to_namefunction tpm_cr50_i2c_probefunction tpm_cr50_i2c_remove
Annotated Snippet
struct tpm_i2c_cr50_priv_data {
int irq;
struct completion tpm_ready;
u8 buf[TPM_CR50_MAX_BUFSIZE];
};
/**
* tpm_cr50_i2c_int_handler() - cr50 interrupt handler.
* @dummy: Unused parameter.
* @tpm_info: TPM chip information.
*
* The cr50 interrupt handler signals waiting threads that the
* interrupt has been asserted. It does not do any interrupt triggered
* processing but is instead used to avoid fixed delays.
*
* Return:
* IRQ_HANDLED signifies irq was handled by this device.
*/
static irqreturn_t tpm_cr50_i2c_int_handler(int dummy, void *tpm_info)
{
struct tpm_chip *chip = tpm_info;
struct tpm_i2c_cr50_priv_data *priv = dev_get_drvdata(&chip->dev);
complete(&priv->tpm_ready);
return IRQ_HANDLED;
}
/**
* tpm_cr50_i2c_wait_tpm_ready() - Wait for tpm to signal ready.
* @chip: A TPM chip.
*
* Wait for completion interrupt if available, otherwise use a fixed
* delay for the TPM to be ready.
*
* Return:
* - 0: Success.
* - -errno: A POSIX error code.
*/
static int tpm_cr50_i2c_wait_tpm_ready(struct tpm_chip *chip)
{
struct tpm_i2c_cr50_priv_data *priv = dev_get_drvdata(&chip->dev);
/* Use a safe fixed delay if interrupt is not supported */
if (priv->irq <= 0) {
msleep(TPM_CR50_TIMEOUT_NOIRQ_MS);
return 0;
}
/* Wait for interrupt to indicate TPM is ready to respond */
if (!wait_for_completion_timeout(&priv->tpm_ready, chip->timeout_a)) {
dev_warn(&chip->dev, "Timeout waiting for TPM ready\n");
return -ETIMEDOUT;
}
return 0;
}
/**
* tpm_cr50_i2c_enable_tpm_irq() - Enable TPM irq.
* @chip: A TPM chip.
*/
static void tpm_cr50_i2c_enable_tpm_irq(struct tpm_chip *chip)
{
struct tpm_i2c_cr50_priv_data *priv = dev_get_drvdata(&chip->dev);
if (priv->irq > 0) {
reinit_completion(&priv->tpm_ready);
enable_irq(priv->irq);
}
}
/**
* tpm_cr50_i2c_disable_tpm_irq() - Disable TPM irq.
* @chip: A TPM chip.
*/
static void tpm_cr50_i2c_disable_tpm_irq(struct tpm_chip *chip)
{
struct tpm_i2c_cr50_priv_data *priv = dev_get_drvdata(&chip->dev);
if (priv->irq > 0)
disable_irq(priv->irq);
}
/**
* tpm_cr50_i2c_transfer_message() - Transfer a message over i2c.
* @dev: Device information.
* @adapter: I2C adapter.
* @msg: Message to transfer.
*
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/bug.h`, `linux/completion.h`, `linux/i2c.h`, `linux/interrupt.h`, `linux/module.h`, `linux/pm.h`, `linux/slab.h`.
- Detected declarations: `struct tpm_i2c_cr50_priv_data`, `function tpm_cr50_i2c_int_handler`, `function tpm_cr50_i2c_wait_tpm_ready`, `function tpm_cr50_i2c_enable_tpm_irq`, `function tpm_cr50_i2c_disable_tpm_irq`, `function tpm_cr50_i2c_transfer_message`, `function tpm_cr50_i2c_read`, `function tpm_cr50_i2c_write`, `function tpm_cr50_check_locality`, `function tpm_cr50_release_locality`.
- Atlas domain: Driver Families / drivers/char.
- Implementation status: source implementation candidate.
- 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.