drivers/char/tpm/st33zp24/st33zp24.c

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

File Facts

System
Linux kernel
Corpus path
drivers/char/tpm/st33zp24/st33zp24.c
Extension
.c
Size
13305 bytes
Lines
591
Domain
Driver Families
Bucket
drivers/char
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret >= 0 && condition) {
				if (canceled)
					return -ECANCELED;
				return 0;
			}
		} while (ret == -ERESTARTSYS && freezing(current));

		disable_irq_nosync(tpm_dev->irq);

	} else {
		do {
			msleep(TPM_TIMEOUT);
			status = chip->ops->status(chip);
			if ((status & mask) == mask)
				return 0;
		} while (time_before(jiffies, stop));
	}

	return -ETIME;
}

static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
{
	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
	int size = 0, burstcnt, len, ret;

	while (size < count &&
	       wait_for_stat(chip,
			     TPM_STS_DATA_AVAIL | TPM_STS_VALID,
			     chip->timeout_c,
			     &tpm_dev->read_queue, true) == 0) {
		burstcnt = get_burstcount(chip);
		if (burstcnt < 0)
			return burstcnt;
		len = min_t(int, burstcnt, count - size);
		ret = tpm_dev->ops->recv(tpm_dev->phy_id, TPM_DATA_FIFO,
					 buf + size, len);
		if (ret < 0)
			return ret;

		size += len;
	}
	return size;
}

static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
{
	struct tpm_chip *chip = dev_id;
	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);

	tpm_dev->intrs++;
	wake_up_interruptible(&tpm_dev->read_queue);
	disable_irq_nosync(tpm_dev->irq);

	return IRQ_HANDLED;
}

/*
 * send TPM commands through the I2C bus.
 */
static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
			 size_t bufsiz, size_t len)
{
	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
	u32 status, i, size, ordinal;
	int burstcnt = 0;
	int ret;
	u8 data;

	if (len < TPM_HEADER_SIZE)
		return -EBUSY;

	ret = request_locality(chip);
	if (ret < 0)
		return ret;

	status = st33zp24_status(chip);
	if ((status & TPM_STS_COMMAND_READY) == 0) {
		st33zp24_cancel(chip);
		if (wait_for_stat
		    (chip, TPM_STS_COMMAND_READY, chip->timeout_b,
		     &tpm_dev->read_queue, false) < 0) {
			ret = -ETIME;
			goto out_err;
		}
	}

	for (i = 0; i < len - 1;) {
		burstcnt = get_burstcount(chip);
		if (burstcnt < 0) {

Annotation

Implementation Notes