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>
This commit is contained in:

committed by
Peter Huewe

parent
87155b7311
commit
afb5abc262
@@ -270,8 +270,11 @@ static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm)
|
||||
static int tpm_ibmvtpm_remove(struct vio_dev *vdev)
|
||||
{
|
||||
struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev);
|
||||
struct tpm_chip *chip = dev_get_drvdata(ibmvtpm->dev);
|
||||
int rc = 0;
|
||||
|
||||
tpm_chip_unregister(chip);
|
||||
|
||||
free_irq(vdev->irq, ibmvtpm);
|
||||
|
||||
do {
|
||||
@@ -290,8 +293,6 @@ static int tpm_ibmvtpm_remove(struct vio_dev *vdev)
|
||||
kfree(ibmvtpm->rtce_buf);
|
||||
}
|
||||
|
||||
tpm_remove_hardware(ibmvtpm->dev);
|
||||
|
||||
kfree(ibmvtpm);
|
||||
|
||||
return 0;
|
||||
@@ -563,11 +564,9 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
|
||||
struct tpm_chip *chip;
|
||||
int rc = -ENOMEM, rc1;
|
||||
|
||||
chip = tpm_register_hardware(dev, &tpm_ibmvtpm);
|
||||
if (!chip) {
|
||||
dev_err(dev, "tpm_register_hardware failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
chip = tpmm_chip_alloc(dev, &tpm_ibmvtpm);
|
||||
if (IS_ERR(chip))
|
||||
return PTR_ERR(chip);
|
||||
|
||||
ibmvtpm = kzalloc(sizeof(struct ibmvtpm_dev), GFP_KERNEL);
|
||||
if (!ibmvtpm) {
|
||||
@@ -637,7 +636,7 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
|
||||
if (rc)
|
||||
goto init_irq_cleanup;
|
||||
|
||||
return rc;
|
||||
return tpm_chip_register(chip);
|
||||
init_irq_cleanup:
|
||||
do {
|
||||
rc1 = plpar_hcall_norets(H_FREE_CRQ, vio_dev->unit_address);
|
||||
@@ -652,8 +651,6 @@ cleanup:
|
||||
kfree(ibmvtpm);
|
||||
}
|
||||
|
||||
tpm_remove_hardware(dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user