linux/drivers/char/tpm/tpm_crb.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2014 Intel Corporation
 *
 * Authors:
 * Jarkko Sakkinen <[email protected]>
 *
 * Maintained by: <[email protected]>
 *
 * This device driver implements the TPM interface as defined in
 * the TCG CRB 2.0 TPM specification.
 */

#include <linux/acpi.h>
#include <linux/highmem.h>
#include <linux/rculist.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#ifdef CONFIG_ARM64
#include <linux/arm-smccc.h>
#endif
#include "tpm.h"

#define ACPI_SIG_TPM2
#define TPM_CRB_MAX_RESOURCES

static const guid_t crb_acpi_start_guid =;

enum crb_defaults {};

enum crb_loc_ctrl {};

enum crb_loc_state {};

enum crb_ctrl_req {};

enum crb_ctrl_sts {};

enum crb_start {};

enum crb_cancel {};

struct crb_regs_head {} __packed;

struct crb_regs_tail {} __packed;

enum crb_status {};

struct crb_priv {};

struct tpm2_crb_smc {};

struct tpm2_crb_pluton {};

static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
				unsigned long timeout)
{}

static int crb_try_pluton_doorbell(struct crb_priv *priv, bool wait_for_complete)
{}

/**
 * __crb_go_idle - request tpm crb device to go the idle state
 *
 * @dev:  crb device
 * @priv: crb private data
 *
 * Write CRB_CTRL_REQ_GO_IDLE to TPM_CRB_CTRL_REQ
 * The device should respond within TIMEOUT_C by clearing the bit.
 * Anyhow, we do not wait here as a consequent CMD_READY request
 * will be handled correctly even if idle was not completed.
 *
 * The function does nothing for devices with ACPI-start method
 * or SMC-start method.
 *
 * Return: 0 always
 */
static int __crb_go_idle(struct device *dev, struct crb_priv *priv)
{}

static int crb_go_idle(struct tpm_chip *chip)
{}

/**
 * __crb_cmd_ready - request tpm crb device to enter ready state
 *
 * @dev:  crb device
 * @priv: crb private data
 *
 * Write CRB_CTRL_REQ_CMD_READY to TPM_CRB_CTRL_REQ
 * and poll till the device acknowledge it by clearing the bit.
 * The device should respond within TIMEOUT_C.
 *
 * The function does nothing for devices with ACPI-start method
 * or SMC-start method.
 *
 * Return: 0 on success -ETIME on timeout;
 */
static int __crb_cmd_ready(struct device *dev, struct crb_priv *priv)
{}

static int crb_cmd_ready(struct tpm_chip *chip)
{}

static int __crb_request_locality(struct device *dev,
				  struct crb_priv *priv, int loc)
{}

static int crb_request_locality(struct tpm_chip *chip, int loc)
{}

static int __crb_relinquish_locality(struct device *dev,
				     struct crb_priv *priv, int loc)
{}

static int crb_relinquish_locality(struct tpm_chip *chip, int loc)
{}

static u8 crb_status(struct tpm_chip *chip)
{}

static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
{}

static int crb_do_acpi_start(struct tpm_chip *chip)
{}

#ifdef CONFIG_ARM64
/*
 * This is a TPM Command Response Buffer start method that invokes a
 * Secure Monitor Call to requrest the firmware to execute or cancel
 * a TPM 2.0 command.
 */
static int tpm_crb_smc_start(struct device *dev, unsigned long func_id)
{
	struct arm_smccc_res res;

	arm_smccc_smc(func_id, 0, 0, 0, 0, 0, 0, 0, &res);
	if (res.a0 != 0) {
		dev_err(dev,
			FW_BUG "tpm_crb_smc_start() returns res.a0 = 0x%lx\n",
			res.a0);
		return -EIO;
	}

	return 0;
}
#else
static int tpm_crb_smc_start(struct device *dev, unsigned long func_id)
{}
#endif

static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len)
{}

static void crb_cancel(struct tpm_chip *chip)
{}

static bool crb_req_canceled(struct tpm_chip *chip, u8 status)
{}

static const struct tpm_class_ops tpm_crb =;

static int crb_check_resource(struct acpi_resource *ares, void *data)
{}

static void __iomem *crb_map_res(struct device *dev, struct resource *iores,
				 void __iomem **iobase_ptr, u64 start, u32 size)
{}

/*
 * Work around broken BIOSs that return inconsistent values from the ACPI
 * region vs the registers. Trust the ACPI region. Such broken systems
 * probably cannot send large TPM commands since the buffer will be truncated.
 */
static u64 crb_fixup_cmd_size(struct device *dev, struct resource *io_res,
			      u64 start, u64 size)
{}

static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
		      struct acpi_table_tpm2 *buf)
{}

static int crb_map_pluton(struct device *dev, struct crb_priv *priv,
	       struct acpi_table_tpm2 *buf, struct tpm2_crb_pluton *crb_pluton)
{}

static int crb_acpi_add(struct acpi_device *device)
{}

static void crb_acpi_remove(struct acpi_device *device)
{}

static const struct dev_pm_ops crb_pm =;

static const struct acpi_device_id crb_device_ids[] =;
MODULE_DEVICE_TABLE(acpi, crb_device_ids);

static struct acpi_driver crb_acpi_driver =;

module_acpi_driver();
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_VERSION();
MODULE_LICENSE();