diff options
Diffstat (limited to 'drivers/char/tpm/tpm_infineon.c')
-rw-r--r-- | drivers/char/tpm/tpm_infineon.c | 61 |
1 files changed, 31 insertions, 30 deletions
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 24095f6ee6da..adfff21beb21 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * License. | 15 | * License. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/init.h> | ||
18 | #include <linux/pnp.h> | 19 | #include <linux/pnp.h> |
19 | #include "tpm.h" | 20 | #include "tpm.h" |
20 | 21 | ||
@@ -104,7 +105,7 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo) | |||
104 | 105 | ||
105 | if (clear_wrfifo) { | 106 | if (clear_wrfifo) { |
106 | for (i = 0; i < 4096; i++) { | 107 | for (i = 0; i < 4096; i++) { |
107 | status = inb(chip->vendor->base + WRFIFO); | 108 | status = inb(chip->vendor.base + WRFIFO); |
108 | if (status == 0xff) { | 109 | if (status == 0xff) { |
109 | if (check == 5) | 110 | if (check == 5) |
110 | break; | 111 | break; |
@@ -124,8 +125,8 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo) | |||
124 | */ | 125 | */ |
125 | i = 0; | 126 | i = 0; |
126 | do { | 127 | do { |
127 | status = inb(chip->vendor->base + RDFIFO); | 128 | status = inb(chip->vendor.base + RDFIFO); |
128 | status = inb(chip->vendor->base + STAT); | 129 | status = inb(chip->vendor.base + STAT); |
129 | i++; | 130 | i++; |
130 | if (i == TPM_MAX_TRIES) | 131 | if (i == TPM_MAX_TRIES) |
131 | return -EIO; | 132 | return -EIO; |
@@ -138,7 +139,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit) | |||
138 | int status; | 139 | int status; |
139 | int i; | 140 | int i; |
140 | for (i = 0; i < TPM_MAX_TRIES; i++) { | 141 | for (i = 0; i < TPM_MAX_TRIES; i++) { |
141 | status = inb(chip->vendor->base + STAT); | 142 | status = inb(chip->vendor.base + STAT); |
142 | /* check the status-register if wait_for_bit is set */ | 143 | /* check the status-register if wait_for_bit is set */ |
143 | if (status & 1 << wait_for_bit) | 144 | if (status & 1 << wait_for_bit) |
144 | break; | 145 | break; |
@@ -157,7 +158,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit) | |||
157 | static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) | 158 | static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) |
158 | { | 159 | { |
159 | wait(chip, STAT_XFE); | 160 | wait(chip, STAT_XFE); |
160 | outb(sendbyte, chip->vendor->base + WRFIFO); | 161 | outb(sendbyte, chip->vendor.base + WRFIFO); |
161 | } | 162 | } |
162 | 163 | ||
163 | /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more | 164 | /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more |
@@ -204,7 +205,7 @@ recv_begin: | |||
204 | ret = wait(chip, STAT_RDA); | 205 | ret = wait(chip, STAT_RDA); |
205 | if (ret) | 206 | if (ret) |
206 | return -EIO; | 207 | return -EIO; |
207 | buf[i] = inb(chip->vendor->base + RDFIFO); | 208 | buf[i] = inb(chip->vendor.base + RDFIFO); |
208 | } | 209 | } |
209 | 210 | ||
210 | if (buf[0] != TPM_VL_VER) { | 211 | if (buf[0] != TPM_VL_VER) { |
@@ -219,7 +220,7 @@ recv_begin: | |||
219 | 220 | ||
220 | for (i = 0; i < size; i++) { | 221 | for (i = 0; i < size; i++) { |
221 | wait(chip, STAT_RDA); | 222 | wait(chip, STAT_RDA); |
222 | buf[i] = inb(chip->vendor->base + RDFIFO); | 223 | buf[i] = inb(chip->vendor.base + RDFIFO); |
223 | } | 224 | } |
224 | 225 | ||
225 | if ((size == 0x6D00) && (buf[1] == 0x80)) { | 226 | if ((size == 0x6D00) && (buf[1] == 0x80)) { |
@@ -268,7 +269,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
268 | u8 count_high, count_low, count_4, count_3, count_2, count_1; | 269 | u8 count_high, count_low, count_4, count_3, count_2, count_1; |
269 | 270 | ||
270 | /* Disabling Reset, LP and IRQC */ | 271 | /* Disabling Reset, LP and IRQC */ |
271 | outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD); | 272 | outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD); |
272 | 273 | ||
273 | ret = empty_fifo(chip, 1); | 274 | ret = empty_fifo(chip, 1); |
274 | if (ret) { | 275 | if (ret) { |
@@ -319,7 +320,7 @@ static void tpm_inf_cancel(struct tpm_chip *chip) | |||
319 | 320 | ||
320 | static u8 tpm_inf_status(struct tpm_chip *chip) | 321 | static u8 tpm_inf_status(struct tpm_chip *chip) |
321 | { | 322 | { |
322 | return inb(chip->vendor->base + STAT); | 323 | return inb(chip->vendor.base + STAT); |
323 | } | 324 | } |
324 | 325 | ||
325 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | 326 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); |
@@ -346,7 +347,7 @@ static struct file_operations inf_ops = { | |||
346 | .release = tpm_release, | 347 | .release = tpm_release, |
347 | }; | 348 | }; |
348 | 349 | ||
349 | static struct tpm_vendor_specific tpm_inf = { | 350 | static const struct tpm_vendor_specific tpm_inf = { |
350 | .recv = tpm_inf_recv, | 351 | .recv = tpm_inf_recv, |
351 | .send = tpm_inf_send, | 352 | .send = tpm_inf_send, |
352 | .cancel = tpm_inf_cancel, | 353 | .cancel = tpm_inf_cancel, |
@@ -375,6 +376,7 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
375 | int version[2]; | 376 | int version[2]; |
376 | int productid[2]; | 377 | int productid[2]; |
377 | char chipname[20]; | 378 | char chipname[20]; |
379 | struct tpm_chip *chip; | ||
378 | 380 | ||
379 | /* read IO-ports through PnP */ | 381 | /* read IO-ports through PnP */ |
380 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && | 382 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && |
@@ -395,14 +397,13 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
395 | goto err_last; | 397 | goto err_last; |
396 | } | 398 | } |
397 | /* publish my base address and request region */ | 399 | /* publish my base address and request region */ |
398 | tpm_inf.base = TPM_INF_BASE; | ||
399 | if (request_region | 400 | if (request_region |
400 | (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { | 401 | (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { |
401 | rc = -EINVAL; | 402 | rc = -EINVAL; |
402 | goto err_last; | 403 | goto err_last; |
403 | } | 404 | } |
404 | if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN, | 405 | if (request_region |
405 | "tpm_infineon0") == NULL) { | 406 | (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) { |
406 | rc = -EINVAL; | 407 | rc = -EINVAL; |
407 | goto err_last; | 408 | goto err_last; |
408 | } | 409 | } |
@@ -442,9 +443,9 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
442 | 443 | ||
443 | /* configure TPM with IO-ports */ | 444 | /* configure TPM with IO-ports */ |
444 | outb(IOLIMH, TPM_INF_ADDR); | 445 | outb(IOLIMH, TPM_INF_ADDR); |
445 | outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA); | 446 | outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA); |
446 | outb(IOLIML, TPM_INF_ADDR); | 447 | outb(IOLIML, TPM_INF_ADDR); |
447 | outb((tpm_inf.base & 0xff), TPM_INF_DATA); | 448 | outb((TPM_INF_BASE & 0xff), TPM_INF_DATA); |
448 | 449 | ||
449 | /* control if IO-ports are set correctly */ | 450 | /* control if IO-ports are set correctly */ |
450 | outb(IOLIMH, TPM_INF_ADDR); | 451 | outb(IOLIMH, TPM_INF_ADDR); |
@@ -452,10 +453,10 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
452 | outb(IOLIML, TPM_INF_ADDR); | 453 | outb(IOLIML, TPM_INF_ADDR); |
453 | iol = inb(TPM_INF_DATA); | 454 | iol = inb(TPM_INF_DATA); |
454 | 455 | ||
455 | if ((ioh << 8 | iol) != tpm_inf.base) { | 456 | if ((ioh << 8 | iol) != TPM_INF_BASE) { |
456 | dev_err(&dev->dev, | 457 | dev_err(&dev->dev, |
457 | "Could not set IO-ports to 0x%lx\n", | 458 | "Could not set IO-ports to 0x%x\n", |
458 | tpm_inf.base); | 459 | TPM_INF_BASE); |
459 | rc = -EIO; | 460 | rc = -EIO; |
460 | goto err_release_region; | 461 | goto err_release_region; |
461 | } | 462 | } |
@@ -466,15 +467,15 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
466 | outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); | 467 | outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); |
467 | 468 | ||
468 | /* disable RESET, LP and IRQC */ | 469 | /* disable RESET, LP and IRQC */ |
469 | outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD); | 470 | outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD); |
470 | 471 | ||
471 | /* Finally, we're done, print some infos */ | 472 | /* Finally, we're done, print some infos */ |
472 | dev_info(&dev->dev, "TPM found: " | 473 | dev_info(&dev->dev, "TPM found: " |
473 | "config base 0x%x, " | 474 | "config base 0x%x, " |
474 | "io base 0x%x, " | 475 | "io base 0x%x, " |
475 | "chip version %02x%02x, " | 476 | "chip version 0x%02x%02x, " |
476 | "vendor id %x%x (Infineon), " | 477 | "vendor id 0x%x%x (Infineon), " |
477 | "product id %02x%02x" | 478 | "product id 0x%02x%02x" |
478 | "%s\n", | 479 | "%s\n", |
479 | TPM_INF_ADDR, | 480 | TPM_INF_ADDR, |
480 | TPM_INF_BASE, | 481 | TPM_INF_BASE, |
@@ -482,11 +483,10 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
482 | vendorid[0], vendorid[1], | 483 | vendorid[0], vendorid[1], |
483 | productid[0], productid[1], chipname); | 484 | productid[0], productid[1], chipname); |
484 | 485 | ||
485 | rc = tpm_register_hardware(&dev->dev, &tpm_inf); | 486 | if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) { |
486 | if (rc < 0) { | ||
487 | rc = -ENODEV; | ||
488 | goto err_release_region; | 487 | goto err_release_region; |
489 | } | 488 | } |
489 | chip->vendor.base = TPM_INF_BASE; | ||
490 | return 0; | 490 | return 0; |
491 | } else { | 491 | } else { |
492 | rc = -ENODEV; | 492 | rc = -ENODEV; |
@@ -494,7 +494,7 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
494 | } | 494 | } |
495 | 495 | ||
496 | err_release_region: | 496 | err_release_region: |
497 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); | 497 | release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); |
498 | release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); | 498 | release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); |
499 | 499 | ||
500 | err_last: | 500 | err_last: |
@@ -506,7 +506,8 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) | |||
506 | struct tpm_chip *chip = pnp_get_drvdata(dev); | 506 | struct tpm_chip *chip = pnp_get_drvdata(dev); |
507 | 507 | ||
508 | if (chip) { | 508 | if (chip) { |
509 | release_region(chip->vendor->base, TPM_INF_PORT_LEN); | 509 | release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); |
510 | release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); | ||
510 | tpm_remove_hardware(chip->dev); | 511 | tpm_remove_hardware(chip->dev); |
511 | } | 512 | } |
512 | } | 513 | } |
@@ -520,7 +521,7 @@ static struct pnp_driver tpm_inf_pnp = { | |||
520 | }, | 521 | }, |
521 | .id_table = tpm_pnp_tbl, | 522 | .id_table = tpm_pnp_tbl, |
522 | .probe = tpm_inf_pnp_probe, | 523 | .probe = tpm_inf_pnp_probe, |
523 | .remove = tpm_inf_pnp_remove, | 524 | .remove = __devexit_p(tpm_inf_pnp_remove), |
524 | }; | 525 | }; |
525 | 526 | ||
526 | static int __init init_inf(void) | 527 | static int __init init_inf(void) |
@@ -538,5 +539,5 @@ module_exit(cleanup_inf); | |||
538 | 539 | ||
539 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); | 540 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); |
540 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); | 541 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); |
541 | MODULE_VERSION("1.7"); | 542 | MODULE_VERSION("1.8"); |
542 | MODULE_LICENSE("GPL"); | 543 | MODULE_LICENSE("GPL"); |