diff options
author | Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | 2014-12-12 11:46:34 -0800 |
---|---|---|
committer | Peter Huewe <peterhuewe@gmx.de> | 2015-01-17 14:00:09 +0100 |
commit | afb5abc262e962089ef2d7c2bbf71bb6f53a2a78 (patch) | |
tree | 5e59c2de94a0f083634e5ead5cf46c34df79eace /drivers/char/tpm/tpm_i2c_stm_st33.c | |
parent | 87155b7311bfec75b590b823b11f77adf2a16412 (diff) | |
download | blackbird-op-linux-afb5abc262e962089ef2d7c2bbf71bb6f53a2a78.tar.gz blackbird-op-linux-afb5abc262e962089ef2d7c2bbf71bb6f53a2a78.zip |
tpm: two-phase chip management functions
tpm_register_hardware() and tpm_remove_hardware() are called often
before initializing the device. The problem is that the device might
not be fully initialized when it comes visible to the user space.
This patch resolves the issue by diving initialization into two
parts:
- tpmm_chip_alloc() creates struct tpm_chip.
- tpm_chip_register() sets up the character device and sysfs
attributes.
The framework takes care of freeing struct tpm_chip by using the devres
API. The broken release callback has been wiped. ACPI drivers do not
ever get this callback.
Regards to Jason Gunthorpe for carefully reviewing this part of the
code.
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Reviewed-by: Jasob Gunthorpe <jason.gunthorpe@obsidianresearch.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Tested-by: Scot Doyle <lkml14@scotdoyle.com>
Tested-by: Peter Huewe <peterhuewe@gmx.de>
[phuewe: update to upstream changes]
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
Diffstat (limited to 'drivers/char/tpm/tpm_i2c_stm_st33.c')
-rw-r--r-- | drivers/char/tpm/tpm_i2c_stm_st33.c | 14 |
1 files changed, 5 insertions, 9 deletions
diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index 86203b022d13..9a96d3704fe5 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c @@ -735,11 +735,9 @@ tpm_stm_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) if (!tpm_dev) return -ENOMEM; - chip = tpm_register_hardware(&client->dev, &st_i2c_tpm); - if (!chip) { - dev_info(&client->dev, "fail chip\n"); - return -ENODEV; - } + chip = tpmm_chip_alloc(&client->dev, &st_i2c_tpm); + if (IS_ERR(chip)) + return PTR_ERR(chip); TPM_VPRIV(chip) = tpm_dev; tpm_dev->client = client; @@ -807,10 +805,8 @@ tpm_stm_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) tpm_get_timeouts(chip); tpm_do_selftest(chip); - dev_info(chip->dev, "TPM I2C Initialized\n"); - return 0; + return tpm_chip_register(chip); _tpm_clean_answer: - tpm_remove_hardware(chip->dev); dev_info(chip->dev, "TPM I2C initialisation fail\n"); return ret; } @@ -827,7 +823,7 @@ static int tpm_stm_i2c_remove(struct i2c_client *client) (struct tpm_chip *) i2c_get_clientdata(client); if (chip) - tpm_remove_hardware(chip->dev); + tpm_chip_unregister(chip); return 0; } |