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>
这个提交包含在:
Jarkko Sakkinen
2014-12-12 11:46:34 -08:00
提交者 Peter Huewe
父节点 87155b7311
当前提交 afb5abc262
修改 14 个文件,包含 329 行新增338 行删除

查看文件

@@ -138,11 +138,11 @@ static void atml_plat_remove(void)
struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
if (chip) {
tpm_chip_unregister(chip);
if (chip->vendor.have_region)
atmel_release_region(chip->vendor.base,
chip->vendor.region_size);
atmel_put_base_addr(chip->vendor.iobase);
tpm_remove_hardware(chip->dev);
platform_device_unregister(pdev);
}
}
@@ -183,8 +183,9 @@ static int __init init_atmel(void)
goto err_rel_reg;
}
if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
rc = -ENODEV;
chip = tpmm_chip_alloc(&pdev->dev, &tpm_atmel);
if (IS_ERR(chip)) {
rc = PTR_ERR(chip);
goto err_unreg_dev;
}
@@ -193,6 +194,10 @@ static int __init init_atmel(void)
chip->vendor.have_region = have_region;
chip->vendor.region_size = region_size;
rc = tpm_chip_register(chip);
if (rc)
goto err_unreg_dev;
return 0;
err_unreg_dev: