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