drivers/char/tpm/tpm_infineon.c

Source file repositories/reference/linux-study-clean/drivers/char/tpm/tpm_infineon.c

File Facts

System
Linux kernel
Corpus path
drivers/char/tpm/tpm_infineon.c
Extension
.c
Size
16223 bytes
Lines
633
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct tpm_inf_dev {
	int iotype;

	void __iomem *mem_base;	/* MMIO ioremap'd addr */
	unsigned long map_base;	/* phys MMIO base */
	unsigned long map_size;	/* MMIO region size */
	unsigned int index_off;	/* index register offset */

	unsigned int data_regs;	/* Data registers */
	unsigned int data_size;

	unsigned int config_port;	/* IO Port config index reg */
	unsigned int config_size;
};

static struct tpm_inf_dev tpm_dev;

static inline void tpm_data_out(unsigned char data, unsigned char offset)
{
#ifdef CONFIG_HAS_IOPORT
	if (tpm_dev.iotype == TPM_INF_IO_PORT)
		outb(data, tpm_dev.data_regs + offset);
	else
#endif
		writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset);
}

static inline unsigned char tpm_data_in(unsigned char offset)
{
#ifdef CONFIG_HAS_IOPORT
	if (tpm_dev.iotype == TPM_INF_IO_PORT)
		return inb(tpm_dev.data_regs + offset);
#endif
	return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset);
}

static inline void tpm_config_out(unsigned char data, unsigned char offset)
{
#ifdef CONFIG_HAS_IOPORT
	if (tpm_dev.iotype == TPM_INF_IO_PORT)
		outb(data, tpm_dev.config_port + offset);
	else
#endif
		writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset);
}

static inline unsigned char tpm_config_in(unsigned char offset)
{
#ifdef CONFIG_HAS_IOPORT
	if (tpm_dev.iotype == TPM_INF_IO_PORT)
		return inb(tpm_dev.config_port + offset);
#endif
	return readb(tpm_dev.mem_base + tpm_dev.index_off + offset);
}

/* TPM header definitions */
enum infineon_tpm_header {
	TPM_VL_VER = 0x01,
	TPM_VL_CHANNEL_CONTROL = 0x07,
	TPM_VL_CHANNEL_PERSONALISATION = 0x0A,
	TPM_VL_CHANNEL_TPM = 0x0B,
	TPM_VL_CONTROL = 0x00,
	TPM_INF_NAK = 0x15,
	TPM_CTRL_WTX = 0x10,
	TPM_CTRL_WTX_ABORT = 0x18,
	TPM_CTRL_WTX_ABORT_ACK = 0x18,
	TPM_CTRL_ERROR = 0x20,
	TPM_CTRL_CHAININGACK = 0x40,
	TPM_CTRL_CHAINING = 0x80,
	TPM_CTRL_DATA = 0x04,
	TPM_CTRL_DATA_CHA = 0x84,
	TPM_CTRL_DATA_CHA_ACK = 0xC4
};

enum infineon_tpm_register {
	WRFIFO = 0x00,
	RDFIFO = 0x01,
	STAT = 0x02,
	CMD = 0x03
};

enum infineon_tpm_command_bits {
	CMD_DIS = 0x00,
	CMD_LP = 0x01,
	CMD_RES = 0x02,
	CMD_IRQC = 0x06
};

enum infineon_tpm_status_bits {
	STAT_XFE = 0x00,

Annotation

Implementation Notes