aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm/tpm_atmel.c
diff options
context:
space:
mode:
authorJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2014-12-12 14:46:34 -0500
committerPeter Huewe <peterhuewe@gmx.de>2015-01-17 08:00:09 -0500
commitafb5abc262e962089ef2d7c2bbf71bb6f53a2a78 (patch)
tree5e59c2de94a0f083634e5ead5cf46c34df79eace /drivers/char/tpm/tpm_atmel.c
parent87155b7311bfec75b590b823b11f77adf2a16412 (diff)
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_atmel.c')
-rw-r--r--drivers/char/tpm/tpm_atmel.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index 435c8b9dd2f8..3d4c6c3b0433 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -138,11 +138,11 @@ static void atml_plat_remove(void)
138 struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); 138 struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
139 139
140 if (chip) { 140 if (chip) {
141 tpm_chip_unregister(chip);
141 if (chip->vendor.have_region) 142 if (chip->vendor.have_region)
142 atmel_release_region(chip->vendor.base, 143 atmel_release_region(chip->vendor.base,
143 chip->vendor.region_size); 144 chip->vendor.region_size);
144 atmel_put_base_addr(chip->vendor.iobase); 145 atmel_put_base_addr(chip->vendor.iobase);
145 tpm_remove_hardware(chip->dev);
146 platform_device_unregister(pdev); 146 platform_device_unregister(pdev);
147 } 147 }
148} 148}
@@ -183,8 +183,9 @@ static int __init init_atmel(void)
183 goto err_rel_reg; 183 goto err_rel_reg;
184 } 184 }
185 185
186 if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) { 186 chip = tpmm_chip_alloc(&pdev->dev, &tpm_atmel);
187 rc = -ENODEV; 187 if (IS_ERR(chip)) {
188 rc = PTR_ERR(chip);
188 goto err_unreg_dev; 189 goto err_unreg_dev;
189 } 190 }
190 191
@@ -193,6 +194,10 @@ static int __init init_atmel(void)
193 chip->vendor.have_region = have_region; 194 chip->vendor.have_region = have_region;
194 chip->vendor.region_size = region_size; 195 chip->vendor.region_size = region_size;
195 196
197 rc = tpm_chip_register(chip);
198 if (rc)
199 goto err_unreg_dev;
200
196 return 0; 201 return 0;
197 202
198err_unreg_dev: 203err_unreg_dev: