aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKylene Jo Hall <kjhall@us.ibm.com>2005-11-07 03:59:25 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 10:53:36 -0500
commite2a8f7a129aff5173c238c8896f004e07a2a3abe (patch)
treead6be2d5d3799c356cbb92f7859b01c9b038ccfb
parentccb6e363a68144cdfdaa6d964d63d620c8ac9a9b (diff)
[PATCH] tpm: Fix lack of driver_unregister in init failcases
driver_unregister is not being properly called when the init function returns an error case. Restructured the return logic such that this and the other cleanups all happen in one place. Preformed many of the cleanups that Andrew Morton's patch on Thursday made in tpm_atmel.c. Fixed Matthieu's concern about writing before discovery. (akpm: rmk said: This driver is buggy. You must not provide your own release function - it doesn't solve the problem which the warning (which you get when you don't provide one) is telling you about. You should convert your device driver over to the replacement dynamic platform support, once it is merged. IOW, something like: pdev = platform_device_alloc("mydev", id); if (pdev) { err = platform_device_add_resources(pdev, &resources, ARRAY_SIZE(resources)); if (err == 0) err = platform_device_add_data(pdev, &platform_data, sizeof(platform_data)); if (err == 0) err = platform_device_add(pdev); } else { err = -ENOMEM; } if (err) platform_device_put(pdev); ) Signed-off-by: Kylene Jo Hall <kjhall@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/char/tpm/tpm_nsc.c48
1 files changed, 23 insertions, 25 deletions
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 8d125c974a2d..680a8e331887 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -287,10 +287,6 @@ static int __init init_nsc(void)
287 int lo, hi; 287 int lo, hi;
288 int nscAddrBase = TPM_ADDR; 288 int nscAddrBase = TPM_ADDR;
289 289
290 driver_register(&nsc_drv);
291
292 /* select PM channel 1 */
293 tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
294 290
295 /* verify that it is a National part (SID) */ 291 /* verify that it is a National part (SID) */
296 if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { 292 if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
@@ -300,6 +296,8 @@ static int __init init_nsc(void)
300 return -ENODEV; 296 return -ENODEV;
301 } 297 }
302 298
299 driver_register(&nsc_drv);
300
303 hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); 301 hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
304 lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); 302 lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
305 tpm_nsc.base = (hi<<8) | lo; 303 tpm_nsc.base = (hi<<8) | lo;
@@ -307,11 +305,11 @@ static int __init init_nsc(void)
307 /* enable the DPM module */ 305 /* enable the DPM module */
308 tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01); 306 tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
309 307
310 pdev = kmalloc(sizeof(struct platform_device), GFP_KERNEL); 308 pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
311 if ( !pdev ) 309 if (!pdev) {
312 return -ENOMEM; 310 rc = -ENOMEM;
313 311 goto err_unreg_drv;
314 memset(pdev, 0, sizeof(struct platform_device)); 312 }
315 313
316 pdev->name = "tpm_nscl0"; 314 pdev->name = "tpm_nscl0";
317 pdev->id = -1; 315 pdev->id = -1;
@@ -319,26 +317,16 @@ static int __init init_nsc(void)
319 pdev->dev.release = tpm_nsc_remove; 317 pdev->dev.release = tpm_nsc_remove;
320 pdev->dev.driver = &nsc_drv; 318 pdev->dev.driver = &nsc_drv;
321 319
322 if ((rc=platform_device_register(pdev)) < 0) { 320 if ((rc = platform_device_register(pdev)) < 0)
323 kfree(pdev); 321 goto err_free_dev;
324 pdev = NULL;
325 return rc;
326 }
327 322
328 if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) { 323 if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
329 platform_device_unregister(pdev); 324 rc = -EBUSY;
330 kfree(pdev); 325 goto err_unreg_dev;
331 pdev = NULL;
332 return -EBUSY;
333 } 326 }
334 327
335 if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0) { 328 if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
336 release_region(tpm_nsc.base, 2); 329 goto err_rel_reg;
337 platform_device_unregister(pdev);
338 kfree(pdev);
339 pdev = NULL;
340 return rc;
341 }
342 330
343 dev_dbg(&pdev->dev, "NSC TPM detected\n"); 331 dev_dbg(&pdev->dev, "NSC TPM detected\n");
344 dev_dbg(&pdev->dev, 332 dev_dbg(&pdev->dev,
@@ -374,6 +362,16 @@ static int __init init_nsc(void)
374 tpm_read_index(nscAddrBase, 0x27) & 0x1F); 362 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
375 363
376 return 0; 364 return 0;
365
366err_rel_reg:
367 release_region(tpm_nsc.base, 2);
368err_unreg_dev:
369 platform_device_unregister(pdev);
370err_free_dev:
371 kfree(pdev);
372err_unreg_drv:
373 driver_unregister(&nsc_drv);
374 return rc;
377} 375}
378 376
379static void __exit cleanup_nsc(void) 377static void __exit cleanup_nsc(void)