diff options
author | Kylene Jo Hall <kjhall@us.ibm.com> | 2005-11-07 03:59:25 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 10:53:36 -0500 |
commit | e2a8f7a129aff5173c238c8896f004e07a2a3abe (patch) | |
tree | ad6be2d5d3799c356cbb92f7859b01c9b038ccfb | |
parent | ccb6e363a68144cdfdaa6d964d63d620c8ac9a9b (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.c | 48 |
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 | |||
366 | err_rel_reg: | ||
367 | release_region(tpm_nsc.base, 2); | ||
368 | err_unreg_dev: | ||
369 | platform_device_unregister(pdev); | ||
370 | err_free_dev: | ||
371 | kfree(pdev); | ||
372 | err_unreg_drv: | ||
373 | driver_unregister(&nsc_drv); | ||
374 | return rc; | ||
377 | } | 375 | } |
378 | 376 | ||
379 | static void __exit cleanup_nsc(void) | 377 | static void __exit cleanup_nsc(void) |