drivers/char/tpm/tpm_ppi.c

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

File Facts

System
Linux kernel
Corpus path
drivers/char/tpm/tpm_ppi.c
Extension
.c
Size
11594 bytes
Lines
431
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

if (len < 0) {
			mutex_unlock(&tpm_ppi_lock);
			return len;
		}

		ppi_cache_populated = true;
	}

	for (i = 0; i <= PPI_TPM_REQ_MAX; i++) {
		ret = ppi_operations_cache[i];
		if (ret >= 0 && ret < ARRAY_SIZE(tpm_ppi_info))
			len += sysfs_emit_at(buf, len, "%d %d: %s\n",
							i, ret, tpm_ppi_info[ret]);
	}
	mutex_unlock(&tpm_ppi_lock);

	return len;
}

static ssize_t tpm_show_ppi_vs_operations(struct device *dev,
					  struct device_attribute *attr,
					  char *buf)
{
	struct tpm_chip *chip = to_tpm_chip(dev);
	ssize_t len = 0;
	u32 ret;
	int i;

	mutex_lock(&tpm_ppi_lock);
	if (!ppi_cache_populated) {
		len = cache_ppi_operations(chip->acpi_dev_handle, buf);
		if (len < 0) {
			mutex_unlock(&tpm_ppi_lock);
			return len;
		}

		ppi_cache_populated = true;
	}

	for (i = PPI_VS_REQ_START; i <= PPI_VS_REQ_END; i++) {
		ret = ppi_operations_cache[i];
		if (ret >= 0 && ret < ARRAY_SIZE(tpm_ppi_info))
			len += sysfs_emit_at(buf, len, "%d %d: %s\n",
							i, ret, tpm_ppi_info[ret]);
	}
	mutex_unlock(&tpm_ppi_lock);

	return len;
}

static DEVICE_ATTR(version, S_IRUGO, tpm_show_ppi_version, NULL);
static DEVICE_ATTR(request, S_IRUGO | S_IWUSR | S_IWGRP,
		   tpm_show_ppi_request, tpm_store_ppi_request);
static DEVICE_ATTR(transition_action, S_IRUGO,
		   tpm_show_ppi_transition_action, NULL);
static DEVICE_ATTR(response, S_IRUGO, tpm_show_ppi_response, NULL);
static DEVICE_ATTR(tcg_operations, S_IRUGO, tpm_show_ppi_tcg_operations, NULL);
static DEVICE_ATTR(vs_operations, S_IRUGO, tpm_show_ppi_vs_operations, NULL);

static struct attribute *ppi_attrs[] = {
	&dev_attr_version.attr,
	&dev_attr_request.attr,
	&dev_attr_transition_action.attr,
	&dev_attr_response.attr,
	&dev_attr_tcg_operations.attr,
	&dev_attr_vs_operations.attr, NULL,
};
static const struct attribute_group ppi_attr_grp = {
	.name = "ppi",
	.attrs = ppi_attrs
};

void tpm_add_ppi(struct tpm_chip *chip)
{
	union acpi_object *obj;

	if (!chip->acpi_dev_handle)
		return;

	if (!acpi_check_dsm(chip->acpi_dev_handle, &tpm_ppi_guid,
			    TPM_PPI_REVISION_ID_1, 1 << TPM_PPI_FN_VERSION))
		return;

	/* Cache PPI version string. */
	obj = acpi_evaluate_dsm_typed(chip->acpi_dev_handle, &tpm_ppi_guid,
				      TPM_PPI_REVISION_ID_1,
				      TPM_PPI_FN_VERSION,
				      NULL, ACPI_TYPE_STRING);
	if (obj) {
		strscpy(chip->ppi_version, obj->string.pointer,

Annotation

Implementation Notes