linux/drivers/char/tpm/tpm_infineon.c
<<
>>
Prefs
   1/*
   2 * Description:
   3 * Device Driver for the Infineon Technologies
   4 * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module
   5 * Specifications at www.trustedcomputinggroup.org
   6 *
   7 * Copyright (C) 2005, Marcel Selhorst <tpmdd@selhorst.net>
   8 * Sirrix AG - security technologies <tpmdd@sirrix.com> and
   9 * Applied Data Security Group, Ruhr-University Bochum, Germany
  10 * Project-Homepage: http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/ 
  11 *
  12 * This program is free software; you can redistribute it and/or
  13 * modify it under the terms of the GNU General Public License as
  14 * published by the Free Software Foundation, version 2 of the
  15 * License.
  16 */
  17
  18#include <linux/init.h>
  19#include <linux/pnp.h>
  20#include "tpm.h"
  21
  22/* Infineon specific definitions */
  23/* maximum number of WTX-packages */
  24#define TPM_MAX_WTX_PACKAGES    50
  25/* msleep-Time for WTX-packages */
  26#define TPM_WTX_MSLEEP_TIME     20
  27/* msleep-Time --> Interval to check status register */
  28#define TPM_MSLEEP_TIME         3
  29/* gives number of max. msleep()-calls before throwing timeout */
  30#define TPM_MAX_TRIES           5000
  31#define TPM_INFINEON_DEV_VEN_VALUE      0x15D1
  32
  33#define TPM_INF_IO_PORT         0x0
  34#define TPM_INF_IO_MEM          0x1
  35
  36#define TPM_INF_ADDR            0x0
  37#define TPM_INF_DATA            0x1
  38
  39struct tpm_inf_dev {
  40        int iotype;
  41
  42        void __iomem *mem_base; /* MMIO ioremap'd addr */
  43        unsigned long map_base; /* phys MMIO base */
  44        unsigned long map_size; /* MMIO region size */
  45        unsigned int index_off; /* index register offset */
  46
  47        unsigned int data_regs; /* Data registers */
  48        unsigned int data_size;
  49
  50        unsigned int config_port;       /* IO Port config index reg */
  51        unsigned int config_size;
  52};
  53
  54static struct tpm_inf_dev tpm_dev;
  55
  56static inline void tpm_data_out(unsigned char data, unsigned char offset)
  57{
  58        if (tpm_dev.iotype == TPM_INF_IO_PORT)
  59                outb(data, tpm_dev.data_regs + offset);
  60        else
  61                writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset);
  62}
  63
  64static inline unsigned char tpm_data_in(unsigned char offset)
  65{
  66        if (tpm_dev.iotype == TPM_INF_IO_PORT)
  67                return inb(tpm_dev.data_regs + offset);
  68        else
  69                return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset);
  70}
  71
  72static inline void tpm_config_out(unsigned char data, unsigned char offset)
  73{
  74        if (tpm_dev.iotype == TPM_INF_IO_PORT)
  75                outb(data, tpm_dev.config_port + offset);
  76        else
  77                writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset);
  78}
  79
  80static inline unsigned char tpm_config_in(unsigned char offset)
  81{
  82        if (tpm_dev.iotype == TPM_INF_IO_PORT)
  83                return inb(tpm_dev.config_port + offset);
  84        else
  85                return readb(tpm_dev.mem_base + tpm_dev.index_off + offset);
  86}
  87
  88/* TPM header definitions */
  89enum infineon_tpm_header {
  90        TPM_VL_VER = 0x01,
  91        TPM_VL_CHANNEL_CONTROL = 0x07,
  92        TPM_VL_CHANNEL_PERSONALISATION = 0x0A,
  93        TPM_VL_CHANNEL_TPM = 0x0B,
  94        TPM_VL_CONTROL = 0x00,
  95        TPM_INF_NAK = 0x15,
  96        TPM_CTRL_WTX = 0x10,
  97        TPM_CTRL_WTX_ABORT = 0x18,
  98        TPM_CTRL_WTX_ABORT_ACK = 0x18,
  99        TPM_CTRL_ERROR = 0x20,
 100        TPM_CTRL_CHAININGACK = 0x40,
 101        TPM_CTRL_CHAINING = 0x80,
 102        TPM_CTRL_DATA = 0x04,
 103        TPM_CTRL_DATA_CHA = 0x84,
 104        TPM_CTRL_DATA_CHA_ACK = 0xC4
 105};
 106
 107enum infineon_tpm_register {
 108        WRFIFO = 0x00,
 109        RDFIFO = 0x01,
 110        STAT = 0x02,
 111        CMD = 0x03
 112};
 113
 114enum infineon_tpm_command_bits {
 115        CMD_DIS = 0x00,
 116        CMD_LP = 0x01,
 117        CMD_RES = 0x02,
 118        CMD_IRQC = 0x06
 119};
 120
 121enum infineon_tpm_status_bits {
 122        STAT_XFE = 0x00,
 123        STAT_LPA = 0x01,
 124        STAT_FOK = 0x02,
 125        STAT_TOK = 0x03,
 126        STAT_IRQA = 0x06,
 127        STAT_RDA = 0x07
 128};
 129
 130/* some outgoing values */
 131enum infineon_tpm_values {
 132        CHIP_ID1 = 0x20,
 133        CHIP_ID2 = 0x21,
 134        TPM_DAR = 0x30,
 135        RESET_LP_IRQC_DISABLE = 0x41,
 136        ENABLE_REGISTER_PAIR = 0x55,
 137        IOLIMH = 0x60,
 138        IOLIML = 0x61,
 139        DISABLE_REGISTER_PAIR = 0xAA,
 140        IDVENL = 0xF1,
 141        IDVENH = 0xF2,
 142        IDPDL = 0xF3,
 143        IDPDH = 0xF4
 144};
 145
 146static int number_of_wtx;
 147
 148static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
 149{
 150        int status;
 151        int check = 0;
 152        int i;
 153
 154        if (clear_wrfifo) {
 155                for (i = 0; i < 4096; i++) {
 156                        status = tpm_data_in(WRFIFO);
 157                        if (status == 0xff) {
 158                                if (check == 5)
 159                                        break;
 160                                else
 161                                        check++;
 162                        }
 163                }
 164        }
 165        /* Note: The values which are currently in the FIFO of the TPM
 166           are thrown away since there is no usage for them. Usually,
 167           this has nothing to say, since the TPM will give its answer
 168           immediately or will be aborted anyway, so the data here is
 169           usually garbage and useless.
 170           We have to clean this, because the next communication with
 171           the TPM would be rubbish, if there is still some old data
 172           in the Read FIFO.
 173         */
 174        i = 0;
 175        do {
 176                status = tpm_data_in(RDFIFO);
 177                status = tpm_data_in(STAT);
 178                i++;
 179                if (i == TPM_MAX_TRIES)
 180                        return -EIO;
 181        } while ((status & (1 << STAT_RDA)) != 0);
 182        return 0;
 183}
 184
 185static int wait(struct tpm_chip *chip, int wait_for_bit)
 186{
 187        int status;
 188        int i;
 189        for (i = 0; i < TPM_MAX_TRIES; i++) {
 190                status = tpm_data_in(STAT);
 191                /* check the status-register if wait_for_bit is set */
 192                if (status & 1 << wait_for_bit)
 193                        break;
 194                msleep(TPM_MSLEEP_TIME);
 195        }
 196        if (i == TPM_MAX_TRIES) {       /* timeout occurs */
 197                if (wait_for_bit == STAT_XFE)
 198                        dev_err(chip->dev, "Timeout in wait(STAT_XFE)\n");
 199                if (wait_for_bit == STAT_RDA)
 200                        dev_err(chip->dev, "Timeout in wait(STAT_RDA)\n");
 201                return -EIO;
 202        }
 203        return 0;
 204};
 205
 206static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
 207{
 208        wait(chip, STAT_XFE);
 209        tpm_data_out(sendbyte, WRFIFO);
 210}
 211
 212    /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
 213       calculation time, it sends a WTX-package, which has to be acknowledged
 214       or aborted. This usually occurs if you are hammering the TPM with key
 215       creation. Set the maximum number of WTX-packages in the definitions
 216       above, if the number is reached, the waiting-time will be denied
 217       and the TPM command has to be resend.
 218     */
 219
 220static void tpm_wtx(struct tpm_chip *chip)
 221{
 222        number_of_wtx++;
 223        dev_info(chip->dev, "Granting WTX (%02d / %02d)\n",
 224                 number_of_wtx, TPM_MAX_WTX_PACKAGES);
 225        wait_and_send(chip, TPM_VL_VER);
 226        wait_and_send(chip, TPM_CTRL_WTX);
 227        wait_and_send(chip, 0x00);
 228        wait_and_send(chip, 0x00);
 229        msleep(TPM_WTX_MSLEEP_TIME);
 230}
 231
 232static void tpm_wtx_abort(struct tpm_chip *chip)
 233{
 234        dev_info(chip->dev, "Aborting WTX\n");
 235        wait_and_send(chip, TPM_VL_VER);
 236        wait_and_send(chip, TPM_CTRL_WTX_ABORT);
 237        wait_and_send(chip, 0x00);
 238        wait_and_send(chip, 0x00);
 239        number_of_wtx = 0;
 240        msleep(TPM_WTX_MSLEEP_TIME);
 241}
 242
 243static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count)
 244{
 245        int i;
 246        int ret;
 247        u32 size = 0;
 248        number_of_wtx = 0;
 249
 250recv_begin:
 251        /* start receiving header */
 252        for (i = 0; i < 4; i++) {
 253                ret = wait(chip, STAT_RDA);
 254                if (ret)
 255                        return -EIO;
 256                buf[i] = tpm_data_in(RDFIFO);
 257        }
 258
 259        if (buf[0] != TPM_VL_VER) {
 260                dev_err(chip->dev,
 261                        "Wrong transport protocol implementation!\n");
 262                return -EIO;
 263        }
 264
 265        if (buf[1] == TPM_CTRL_DATA) {
 266                /* size of the data received */
 267                size = ((buf[2] << 8) | buf[3]);
 268
 269                for (i = 0; i < size; i++) {
 270                        wait(chip, STAT_RDA);
 271                        buf[i] = tpm_data_in(RDFIFO);
 272                }
 273
 274                if ((size == 0x6D00) && (buf[1] == 0x80)) {
 275                        dev_err(chip->dev, "Error handling on vendor layer!\n");
 276                        return -EIO;
 277                }
 278
 279                for (i = 0; i < size; i++)
 280                        buf[i] = buf[i + 6];
 281
 282                size = size - 6;
 283                return size;
 284        }
 285
 286        if (buf[1] == TPM_CTRL_WTX) {
 287                dev_info(chip->dev, "WTX-package received\n");
 288                if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
 289                        tpm_wtx(chip);
 290                        goto recv_begin;
 291                } else {
 292                        tpm_wtx_abort(chip);
 293                        goto recv_begin;
 294                }
 295        }
 296
 297        if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
 298                dev_info(chip->dev, "WTX-abort acknowledged\n");
 299                return size;
 300        }
 301
 302        if (buf[1] == TPM_CTRL_ERROR) {
 303                dev_err(chip->dev, "ERROR-package received:\n");
 304                if (buf[4] == TPM_INF_NAK)
 305                        dev_err(chip->dev,
 306                                "-> Negative acknowledgement"
 307                                " - retransmit command!\n");
 308                return -EIO;
 309        }
 310        return -EIO;
 311}
 312
 313static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
 314{
 315        int i;
 316        int ret;
 317        u8 count_high, count_low, count_4, count_3, count_2, count_1;
 318
 319        /* Disabling Reset, LP and IRQC */
 320        tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
 321
 322        ret = empty_fifo(chip, 1);
 323        if (ret) {
 324                dev_err(chip->dev, "Timeout while clearing FIFO\n");
 325                return -EIO;
 326        }
 327
 328        ret = wait(chip, STAT_XFE);
 329        if (ret)
 330                return -EIO;
 331
 332        count_4 = (count & 0xff000000) >> 24;
 333        count_3 = (count & 0x00ff0000) >> 16;
 334        count_2 = (count & 0x0000ff00) >> 8;
 335        count_1 = (count & 0x000000ff);
 336        count_high = ((count + 6) & 0xffffff00) >> 8;
 337        count_low = ((count + 6) & 0x000000ff);
 338
 339        /* Sending Header */
 340        wait_and_send(chip, TPM_VL_VER);
 341        wait_and_send(chip, TPM_CTRL_DATA);
 342        wait_and_send(chip, count_high);
 343        wait_and_send(chip, count_low);
 344
 345        /* Sending Data Header */
 346        wait_and_send(chip, TPM_VL_VER);
 347        wait_and_send(chip, TPM_VL_CHANNEL_TPM);
 348        wait_and_send(chip, count_4);
 349        wait_and_send(chip, count_3);
 350        wait_and_send(chip, count_2);
 351        wait_and_send(chip, count_1);
 352
 353        /* Sending Data */
 354        for (i = 0; i < count; i++) {
 355                wait_and_send(chip, buf[i]);
 356        }
 357        return count;
 358}
 359
 360static void tpm_inf_cancel(struct tpm_chip *chip)
 361{
 362        /*
 363           Since we are using the legacy mode to communicate
 364           with the TPM, we have no cancel functions, but have
 365           a workaround for interrupting the TPM through WTX.
 366         */
 367}
 368
 369static u8 tpm_inf_status(struct tpm_chip *chip)
 370{
 371        return tpm_data_in(STAT);
 372}
 373
 374static const struct tpm_class_ops tpm_inf = {
 375        .recv = tpm_inf_recv,
 376        .send = tpm_inf_send,
 377        .cancel = tpm_inf_cancel,
 378        .status = tpm_inf_status,
 379        .req_complete_mask = 0,
 380        .req_complete_val = 0,
 381};
 382
 383static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
 384        /* Infineon TPMs */
 385        {"IFX0101", 0},
 386        {"IFX0102", 0},
 387        {"", 0}
 388};
 389
 390MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl);
 391
 392static int tpm_inf_pnp_probe(struct pnp_dev *dev,
 393                                       const struct pnp_device_id *dev_id)
 394{
 395        int rc = 0;
 396        u8 iol, ioh;
 397        int vendorid[2];
 398        int version[2];
 399        int productid[2];
 400        char chipname[20];
 401        struct tpm_chip *chip;
 402
 403        /* read IO-ports through PnP */
 404        if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
 405            !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
 406
 407                tpm_dev.iotype = TPM_INF_IO_PORT;
 408
 409                tpm_dev.config_port = pnp_port_start(dev, 0);
 410                tpm_dev.config_size = pnp_port_len(dev, 0);
 411                tpm_dev.data_regs = pnp_port_start(dev, 1);
 412                tpm_dev.data_size = pnp_port_len(dev, 1);
 413                if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) {
 414                        rc = -EINVAL;
 415                        goto err_last;
 416                }
 417                dev_info(&dev->dev, "Found %s with ID %s\n",
 418                         dev->name, dev_id->id);
 419                if (!((tpm_dev.data_regs >> 8) & 0xff)) {
 420                        rc = -EINVAL;
 421                        goto err_last;
 422                }
 423                /* publish my base address and request region */
 424                if (request_region(tpm_dev.data_regs, tpm_dev.data_size,
 425                                   "tpm_infineon0") == NULL) {
 426                        rc = -EINVAL;
 427                        goto err_last;
 428                }
 429                if (request_region(tpm_dev.config_port, tpm_dev.config_size,
 430                                   "tpm_infineon0") == NULL) {
 431                        release_region(tpm_dev.data_regs, tpm_dev.data_size);
 432                        rc = -EINVAL;
 433                        goto err_last;
 434                }
 435        } else if (pnp_mem_valid(dev, 0) &&
 436                   !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
 437
 438                tpm_dev.iotype = TPM_INF_IO_MEM;
 439
 440                tpm_dev.map_base = pnp_mem_start(dev, 0);
 441                tpm_dev.map_size = pnp_mem_len(dev, 0);
 442
 443                dev_info(&dev->dev, "Found %s with ID %s\n",
 444                         dev->name, dev_id->id);
 445
 446                /* publish my base address and request region */
 447                if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size,
 448                                       "tpm_infineon0") == NULL) {
 449                        rc = -EINVAL;
 450                        goto err_last;
 451                }
 452
 453                tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size);
 454                if (tpm_dev.mem_base == NULL) {
 455                        release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
 456                        rc = -EINVAL;
 457                        goto err_last;
 458                }
 459
 460                /*
 461                 * The only known MMIO based Infineon TPM system provides
 462                 * a single large mem region with the device config
 463                 * registers at the default TPM_ADDR.  The data registers
 464                 * seem like they could be placed anywhere within the MMIO
 465                 * region, but lets just put them at zero offset.
 466                 */
 467                tpm_dev.index_off = TPM_ADDR;
 468                tpm_dev.data_regs = 0x0;
 469        } else {
 470                rc = -EINVAL;
 471                goto err_last;
 472        }
 473
 474        /* query chip for its vendor, its version number a.s.o. */
 475        tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
 476        tpm_config_out(IDVENL, TPM_INF_ADDR);
 477        vendorid[1] = tpm_config_in(TPM_INF_DATA);
 478        tpm_config_out(IDVENH, TPM_INF_ADDR);
 479        vendorid[0] = tpm_config_in(TPM_INF_DATA);
 480        tpm_config_out(IDPDL, TPM_INF_ADDR);
 481        productid[1] = tpm_config_in(TPM_INF_DATA);
 482        tpm_config_out(IDPDH, TPM_INF_ADDR);
 483        productid[0] = tpm_config_in(TPM_INF_DATA);
 484        tpm_config_out(CHIP_ID1, TPM_INF_ADDR);
 485        version[1] = tpm_config_in(TPM_INF_DATA);
 486        tpm_config_out(CHIP_ID2, TPM_INF_ADDR);
 487        version[0] = tpm_config_in(TPM_INF_DATA);
 488
 489        switch ((productid[0] << 8) | productid[1]) {
 490        case 6:
 491                snprintf(chipname, sizeof(chipname), " (SLD 9630 TT 1.1)");
 492                break;
 493        case 11:
 494                snprintf(chipname, sizeof(chipname), " (SLB 9635 TT 1.2)");
 495                break;
 496        default:
 497                snprintf(chipname, sizeof(chipname), " (unknown chip)");
 498                break;
 499        }
 500
 501        if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
 502
 503                /* configure TPM with IO-ports */
 504                tpm_config_out(IOLIMH, TPM_INF_ADDR);
 505                tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
 506                tpm_config_out(IOLIML, TPM_INF_ADDR);
 507                tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
 508
 509                /* control if IO-ports are set correctly */
 510                tpm_config_out(IOLIMH, TPM_INF_ADDR);
 511                ioh = tpm_config_in(TPM_INF_DATA);
 512                tpm_config_out(IOLIML, TPM_INF_ADDR);
 513                iol = tpm_config_in(TPM_INF_DATA);
 514
 515                if ((ioh << 8 | iol) != tpm_dev.data_regs) {
 516                        dev_err(&dev->dev,
 517                                "Could not set IO-data registers to 0x%x\n",
 518                                tpm_dev.data_regs);
 519                        rc = -EIO;
 520                        goto err_release_region;
 521                }
 522
 523                /* activate register */
 524                tpm_config_out(TPM_DAR, TPM_INF_ADDR);
 525                tpm_config_out(0x01, TPM_INF_DATA);
 526                tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
 527
 528                /* disable RESET, LP and IRQC */
 529                tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
 530
 531                /* Finally, we're done, print some infos */
 532                dev_info(&dev->dev, "TPM found: "
 533                         "config base 0x%lx, "
 534                         "data base 0x%lx, "
 535                         "chip version 0x%02x%02x, "
 536                         "vendor id 0x%x%x (Infineon), "
 537                         "product id 0x%02x%02x"
 538                         "%s\n",
 539                         tpm_dev.iotype == TPM_INF_IO_PORT ?
 540                         tpm_dev.config_port :
 541                         tpm_dev.map_base + tpm_dev.index_off,
 542                         tpm_dev.iotype == TPM_INF_IO_PORT ?
 543                         tpm_dev.data_regs :
 544                         tpm_dev.map_base + tpm_dev.data_regs,
 545                         version[0], version[1],
 546                         vendorid[0], vendorid[1],
 547                         productid[0], productid[1], chipname);
 548
 549                if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf)))
 550                        goto err_release_region;
 551
 552                return 0;
 553        } else {
 554                rc = -ENODEV;
 555                goto err_release_region;
 556        }
 557
 558err_release_region:
 559        if (tpm_dev.iotype == TPM_INF_IO_PORT) {
 560                release_region(tpm_dev.data_regs, tpm_dev.data_size);
 561                release_region(tpm_dev.config_port, tpm_dev.config_size);
 562        } else {
 563                iounmap(tpm_dev.mem_base);
 564                release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
 565        }
 566
 567err_last:
 568        return rc;
 569}
 570
 571static void tpm_inf_pnp_remove(struct pnp_dev *dev)
 572{
 573        struct tpm_chip *chip = pnp_get_drvdata(dev);
 574
 575        if (chip) {
 576                if (tpm_dev.iotype == TPM_INF_IO_PORT) {
 577                        release_region(tpm_dev.data_regs, tpm_dev.data_size);
 578                        release_region(tpm_dev.config_port,
 579                                       tpm_dev.config_size);
 580                } else {
 581                        iounmap(tpm_dev.mem_base);
 582                        release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
 583                }
 584                tpm_dev_vendor_release(chip);
 585                tpm_remove_hardware(chip->dev);
 586        }
 587}
 588
 589static int tpm_inf_pnp_suspend(struct pnp_dev *dev, pm_message_t pm_state)
 590{
 591        struct tpm_chip *chip = pnp_get_drvdata(dev);
 592        int rc;
 593        if (chip) {
 594                u8 savestate[] = {
 595                        0, 193, /* TPM_TAG_RQU_COMMAND */
 596                        0, 0, 0, 10,    /* blob length (in bytes) */
 597                        0, 0, 0, 152    /* TPM_ORD_SaveState */
 598                };
 599                dev_info(&dev->dev, "saving TPM state\n");
 600                rc = tpm_inf_send(chip, savestate, sizeof(savestate));
 601                if (rc < 0) {
 602                        dev_err(&dev->dev, "error while saving TPM state\n");
 603                        return rc;
 604                }
 605        }
 606        return 0;
 607}
 608
 609static int tpm_inf_pnp_resume(struct pnp_dev *dev)
 610{
 611        /* Re-configure TPM after suspending */
 612        tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
 613        tpm_config_out(IOLIMH, TPM_INF_ADDR);
 614        tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
 615        tpm_config_out(IOLIML, TPM_INF_ADDR);
 616        tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
 617        /* activate register */
 618        tpm_config_out(TPM_DAR, TPM_INF_ADDR);
 619        tpm_config_out(0x01, TPM_INF_DATA);
 620        tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
 621        /* disable RESET, LP and IRQC */
 622        tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
 623        return tpm_pm_resume(&dev->dev);
 624}
 625
 626static struct pnp_driver tpm_inf_pnp_driver = {
 627        .name = "tpm_inf_pnp",
 628        .id_table = tpm_inf_pnp_tbl,
 629        .probe = tpm_inf_pnp_probe,
 630        .suspend = tpm_inf_pnp_suspend,
 631        .resume = tpm_inf_pnp_resume,
 632        .remove = tpm_inf_pnp_remove
 633};
 634
 635static int __init init_inf(void)
 636{
 637        return pnp_register_driver(&tpm_inf_pnp_driver);
 638}
 639
 640static void __exit cleanup_inf(void)
 641{
 642        pnp_unregister_driver(&tpm_inf_pnp_driver);
 643}
 644
 645module_init(init_inf);
 646module_exit(cleanup_inf);
 647
 648MODULE_AUTHOR("Marcel Selhorst <tpmdd@sirrix.com>");
 649MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
 650MODULE_VERSION("1.9.2");
 651MODULE_LICENSE("GPL");
 652