*
* Return: always 0 (i.e. success)
*/
-static int tpm_class_shutdown(struct device *dev)
+int tpm_class_shutdown(struct device *dev)
{
struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev);
device_initialize(&chip->dev);
chip->dev.class = tpm_class;
- chip->dev.class->shutdown_pre = tpm_class_shutdown;
chip->dev.release = tpm_dev_release;
chip->dev.parent = pdev;
chip->dev.groups = chip->groups;
}
/*
- * tpm_chip_startup() - performs auto startup and allocates the PCRs
+ * tpm_chip_bootstrap() - Boostrap TPM chip after power on
* @chip: TPM chip to use.
+ *
+ * Initialize TPM chip after power on. This a one-shot function: subsequent
+ * calls will have no effect.
*/
- int tpm_chip_startup(struct tpm_chip *chip)
+ int tpm_chip_bootstrap(struct tpm_chip *chip)
{
int rc;
+ if (chip->flags & TPM_CHIP_FLAG_BOOTSTRAPPED)
+ return 0;
+
rc = tpm_chip_start(chip);
if (rc)
return rc;
stop:
tpm_chip_stop(chip);
+ /*
+ * Unconditionally set, as driver initialization should cease, when the
+ * boostrapping process fails.
+ */
+ chip->flags |= TPM_CHIP_FLAG_BOOTSTRAPPED;
+
return rc;
}
- EXPORT_SYMBOL_GPL(tpm_chip_startup);
+ EXPORT_SYMBOL_GPL(tpm_chip_bootstrap);
/*
* tpm_chip_register() - create a character device for the TPM chip
{
int rc;
+ rc = tpm_chip_bootstrap(chip);
+ if (rc)
+ return rc;
+
tpm_sysfs_add_device(chip);
tpm_bios_log_setup(chip);
unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
int tpm_pm_suspend(struct device *dev);
int tpm_pm_resume(struct device *dev);
+int tpm_class_shutdown(struct device *dev);
static inline void tpm_msleep(unsigned int delay_msec)
{
delay_msec * 1000);
};
- int tpm_chip_startup(struct tpm_chip *chip);
+ int tpm_chip_bootstrap(struct tpm_chip *chip);
int tpm_chip_start(struct tpm_chip *chip);
void tpm_chip_stop(struct tpm_chip *chip);
struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip);