Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Description:
0004  * Device Driver for the Infineon Technologies
0005  * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module
0006  * Specifications at www.trustedcomputinggroup.org
0007  *
0008  * Copyright (C) 2005, Marcel Selhorst <tpmdd@selhorst.net>
0009  * Sirrix AG - security technologies <tpmdd@sirrix.com> and
0010  * Applied Data Security Group, Ruhr-University Bochum, Germany
0011  * Project-Homepage: http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/ 
0012  */
0013 
0014 #include <linux/init.h>
0015 #include <linux/pnp.h>
0016 #include "tpm.h"
0017 
0018 /* Infineon specific definitions */
0019 /* maximum number of WTX-packages */
0020 #define TPM_MAX_WTX_PACKAGES    50
0021 /* msleep-Time for WTX-packages */
0022 #define TPM_WTX_MSLEEP_TIME     20
0023 /* msleep-Time --> Interval to check status register */
0024 #define TPM_MSLEEP_TIME     3
0025 /* gives number of max. msleep()-calls before throwing timeout */
0026 #define TPM_MAX_TRIES       5000
0027 #define TPM_INFINEON_DEV_VEN_VALUE  0x15D1
0028 
0029 #define TPM_INF_IO_PORT     0x0
0030 #define TPM_INF_IO_MEM      0x1
0031 
0032 #define TPM_INF_ADDR        0x0
0033 #define TPM_INF_DATA        0x1
0034 
0035 struct tpm_inf_dev {
0036     int iotype;
0037 
0038     void __iomem *mem_base; /* MMIO ioremap'd addr */
0039     unsigned long map_base; /* phys MMIO base */
0040     unsigned long map_size; /* MMIO region size */
0041     unsigned int index_off; /* index register offset */
0042 
0043     unsigned int data_regs; /* Data registers */
0044     unsigned int data_size;
0045 
0046     unsigned int config_port;   /* IO Port config index reg */
0047     unsigned int config_size;
0048 };
0049 
0050 static struct tpm_inf_dev tpm_dev;
0051 
0052 static inline void tpm_data_out(unsigned char data, unsigned char offset)
0053 {
0054     if (tpm_dev.iotype == TPM_INF_IO_PORT)
0055         outb(data, tpm_dev.data_regs + offset);
0056     else
0057         writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset);
0058 }
0059 
0060 static inline unsigned char tpm_data_in(unsigned char offset)
0061 {
0062     if (tpm_dev.iotype == TPM_INF_IO_PORT)
0063         return inb(tpm_dev.data_regs + offset);
0064     else
0065         return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset);
0066 }
0067 
0068 static inline void tpm_config_out(unsigned char data, unsigned char offset)
0069 {
0070     if (tpm_dev.iotype == TPM_INF_IO_PORT)
0071         outb(data, tpm_dev.config_port + offset);
0072     else
0073         writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset);
0074 }
0075 
0076 static inline unsigned char tpm_config_in(unsigned char offset)
0077 {
0078     if (tpm_dev.iotype == TPM_INF_IO_PORT)
0079         return inb(tpm_dev.config_port + offset);
0080     else
0081         return readb(tpm_dev.mem_base + tpm_dev.index_off + offset);
0082 }
0083 
0084 /* TPM header definitions */
0085 enum infineon_tpm_header {
0086     TPM_VL_VER = 0x01,
0087     TPM_VL_CHANNEL_CONTROL = 0x07,
0088     TPM_VL_CHANNEL_PERSONALISATION = 0x0A,
0089     TPM_VL_CHANNEL_TPM = 0x0B,
0090     TPM_VL_CONTROL = 0x00,
0091     TPM_INF_NAK = 0x15,
0092     TPM_CTRL_WTX = 0x10,
0093     TPM_CTRL_WTX_ABORT = 0x18,
0094     TPM_CTRL_WTX_ABORT_ACK = 0x18,
0095     TPM_CTRL_ERROR = 0x20,
0096     TPM_CTRL_CHAININGACK = 0x40,
0097     TPM_CTRL_CHAINING = 0x80,
0098     TPM_CTRL_DATA = 0x04,
0099     TPM_CTRL_DATA_CHA = 0x84,
0100     TPM_CTRL_DATA_CHA_ACK = 0xC4
0101 };
0102 
0103 enum infineon_tpm_register {
0104     WRFIFO = 0x00,
0105     RDFIFO = 0x01,
0106     STAT = 0x02,
0107     CMD = 0x03
0108 };
0109 
0110 enum infineon_tpm_command_bits {
0111     CMD_DIS = 0x00,
0112     CMD_LP = 0x01,
0113     CMD_RES = 0x02,
0114     CMD_IRQC = 0x06
0115 };
0116 
0117 enum infineon_tpm_status_bits {
0118     STAT_XFE = 0x00,
0119     STAT_LPA = 0x01,
0120     STAT_FOK = 0x02,
0121     STAT_TOK = 0x03,
0122     STAT_IRQA = 0x06,
0123     STAT_RDA = 0x07
0124 };
0125 
0126 /* some outgoing values */
0127 enum infineon_tpm_values {
0128     CHIP_ID1 = 0x20,
0129     CHIP_ID2 = 0x21,
0130     TPM_DAR = 0x30,
0131     RESET_LP_IRQC_DISABLE = 0x41,
0132     ENABLE_REGISTER_PAIR = 0x55,
0133     IOLIMH = 0x60,
0134     IOLIML = 0x61,
0135     DISABLE_REGISTER_PAIR = 0xAA,
0136     IDVENL = 0xF1,
0137     IDVENH = 0xF2,
0138     IDPDL = 0xF3,
0139     IDPDH = 0xF4
0140 };
0141 
0142 static int number_of_wtx;
0143 
0144 static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
0145 {
0146     int status;
0147     int check = 0;
0148     int i;
0149 
0150     if (clear_wrfifo) {
0151         for (i = 0; i < 4096; i++) {
0152             status = tpm_data_in(WRFIFO);
0153             if (status == 0xff) {
0154                 if (check == 5)
0155                     break;
0156                 else
0157                     check++;
0158             }
0159         }
0160     }
0161     /* Note: The values which are currently in the FIFO of the TPM
0162        are thrown away since there is no usage for them. Usually,
0163        this has nothing to say, since the TPM will give its answer
0164        immediately or will be aborted anyway, so the data here is
0165        usually garbage and useless.
0166        We have to clean this, because the next communication with
0167        the TPM would be rubbish, if there is still some old data
0168        in the Read FIFO.
0169      */
0170     i = 0;
0171     do {
0172         status = tpm_data_in(RDFIFO);
0173         status = tpm_data_in(STAT);
0174         i++;
0175         if (i == TPM_MAX_TRIES)
0176             return -EIO;
0177     } while ((status & (1 << STAT_RDA)) != 0);
0178     return 0;
0179 }
0180 
0181 static int wait(struct tpm_chip *chip, int wait_for_bit)
0182 {
0183     int status;
0184     int i;
0185     for (i = 0; i < TPM_MAX_TRIES; i++) {
0186         status = tpm_data_in(STAT);
0187         /* check the status-register if wait_for_bit is set */
0188         if (status & 1 << wait_for_bit)
0189             break;
0190         tpm_msleep(TPM_MSLEEP_TIME);
0191     }
0192     if (i == TPM_MAX_TRIES) {   /* timeout occurs */
0193         if (wait_for_bit == STAT_XFE)
0194             dev_err(&chip->dev, "Timeout in wait(STAT_XFE)\n");
0195         if (wait_for_bit == STAT_RDA)
0196             dev_err(&chip->dev, "Timeout in wait(STAT_RDA)\n");
0197         return -EIO;
0198     }
0199     return 0;
0200 };
0201 
0202 static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
0203 {
0204     wait(chip, STAT_XFE);
0205     tpm_data_out(sendbyte, WRFIFO);
0206 }
0207 
0208     /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
0209        calculation time, it sends a WTX-package, which has to be acknowledged
0210        or aborted. This usually occurs if you are hammering the TPM with key
0211        creation. Set the maximum number of WTX-packages in the definitions
0212        above, if the number is reached, the waiting-time will be denied
0213        and the TPM command has to be resend.
0214      */
0215 
0216 static void tpm_wtx(struct tpm_chip *chip)
0217 {
0218     number_of_wtx++;
0219     dev_info(&chip->dev, "Granting WTX (%02d / %02d)\n",
0220          number_of_wtx, TPM_MAX_WTX_PACKAGES);
0221     wait_and_send(chip, TPM_VL_VER);
0222     wait_and_send(chip, TPM_CTRL_WTX);
0223     wait_and_send(chip, 0x00);
0224     wait_and_send(chip, 0x00);
0225     tpm_msleep(TPM_WTX_MSLEEP_TIME);
0226 }
0227 
0228 static void tpm_wtx_abort(struct tpm_chip *chip)
0229 {
0230     dev_info(&chip->dev, "Aborting WTX\n");
0231     wait_and_send(chip, TPM_VL_VER);
0232     wait_and_send(chip, TPM_CTRL_WTX_ABORT);
0233     wait_and_send(chip, 0x00);
0234     wait_and_send(chip, 0x00);
0235     number_of_wtx = 0;
0236     tpm_msleep(TPM_WTX_MSLEEP_TIME);
0237 }
0238 
0239 static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count)
0240 {
0241     int i;
0242     int ret;
0243     u32 size = 0;
0244     number_of_wtx = 0;
0245 
0246 recv_begin:
0247     /* start receiving header */
0248     for (i = 0; i < 4; i++) {
0249         ret = wait(chip, STAT_RDA);
0250         if (ret)
0251             return -EIO;
0252         buf[i] = tpm_data_in(RDFIFO);
0253     }
0254 
0255     if (buf[0] != TPM_VL_VER) {
0256         dev_err(&chip->dev,
0257             "Wrong transport protocol implementation!\n");
0258         return -EIO;
0259     }
0260 
0261     if (buf[1] == TPM_CTRL_DATA) {
0262         /* size of the data received */
0263         size = ((buf[2] << 8) | buf[3]);
0264 
0265         for (i = 0; i < size; i++) {
0266             wait(chip, STAT_RDA);
0267             buf[i] = tpm_data_in(RDFIFO);
0268         }
0269 
0270         if ((size == 0x6D00) && (buf[1] == 0x80)) {
0271             dev_err(&chip->dev, "Error handling on vendor layer!\n");
0272             return -EIO;
0273         }
0274 
0275         for (i = 0; i < size; i++)
0276             buf[i] = buf[i + 6];
0277 
0278         size = size - 6;
0279         return size;
0280     }
0281 
0282     if (buf[1] == TPM_CTRL_WTX) {
0283         dev_info(&chip->dev, "WTX-package received\n");
0284         if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
0285             tpm_wtx(chip);
0286             goto recv_begin;
0287         } else {
0288             tpm_wtx_abort(chip);
0289             goto recv_begin;
0290         }
0291     }
0292 
0293     if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
0294         dev_info(&chip->dev, "WTX-abort acknowledged\n");
0295         return size;
0296     }
0297 
0298     if (buf[1] == TPM_CTRL_ERROR) {
0299         dev_err(&chip->dev, "ERROR-package received:\n");
0300         if (buf[4] == TPM_INF_NAK)
0301             dev_err(&chip->dev,
0302                 "-> Negative acknowledgement"
0303                 " - retransmit command!\n");
0304         return -EIO;
0305     }
0306     return -EIO;
0307 }
0308 
0309 static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
0310 {
0311     int i;
0312     int ret;
0313     u8 count_high, count_low, count_4, count_3, count_2, count_1;
0314 
0315     /* Disabling Reset, LP and IRQC */
0316     tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
0317 
0318     ret = empty_fifo(chip, 1);
0319     if (ret) {
0320         dev_err(&chip->dev, "Timeout while clearing FIFO\n");
0321         return -EIO;
0322     }
0323 
0324     ret = wait(chip, STAT_XFE);
0325     if (ret)
0326         return -EIO;
0327 
0328     count_4 = (count & 0xff000000) >> 24;
0329     count_3 = (count & 0x00ff0000) >> 16;
0330     count_2 = (count & 0x0000ff00) >> 8;
0331     count_1 = (count & 0x000000ff);
0332     count_high = ((count + 6) & 0xffffff00) >> 8;
0333     count_low = ((count + 6) & 0x000000ff);
0334 
0335     /* Sending Header */
0336     wait_and_send(chip, TPM_VL_VER);
0337     wait_and_send(chip, TPM_CTRL_DATA);
0338     wait_and_send(chip, count_high);
0339     wait_and_send(chip, count_low);
0340 
0341     /* Sending Data Header */
0342     wait_and_send(chip, TPM_VL_VER);
0343     wait_and_send(chip, TPM_VL_CHANNEL_TPM);
0344     wait_and_send(chip, count_4);
0345     wait_and_send(chip, count_3);
0346     wait_and_send(chip, count_2);
0347     wait_and_send(chip, count_1);
0348 
0349     /* Sending Data */
0350     for (i = 0; i < count; i++) {
0351         wait_and_send(chip, buf[i]);
0352     }
0353     return 0;
0354 }
0355 
0356 static void tpm_inf_cancel(struct tpm_chip *chip)
0357 {
0358     /*
0359        Since we are using the legacy mode to communicate
0360        with the TPM, we have no cancel functions, but have
0361        a workaround for interrupting the TPM through WTX.
0362      */
0363 }
0364 
0365 static u8 tpm_inf_status(struct tpm_chip *chip)
0366 {
0367     return tpm_data_in(STAT);
0368 }
0369 
0370 static const struct tpm_class_ops tpm_inf = {
0371     .recv = tpm_inf_recv,
0372     .send = tpm_inf_send,
0373     .cancel = tpm_inf_cancel,
0374     .status = tpm_inf_status,
0375     .req_complete_mask = 0,
0376     .req_complete_val = 0,
0377 };
0378 
0379 static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
0380     /* Infineon TPMs */
0381     {"IFX0101", 0},
0382     {"IFX0102", 0},
0383     {"", 0}
0384 };
0385 
0386 MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl);
0387 
0388 static int tpm_inf_pnp_probe(struct pnp_dev *dev,
0389                        const struct pnp_device_id *dev_id)
0390 {
0391     int rc = 0;
0392     u8 iol, ioh;
0393     int vendorid[2];
0394     int version[2];
0395     int productid[2];
0396     const char *chipname;
0397     struct tpm_chip *chip;
0398 
0399     /* read IO-ports through PnP */
0400     if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
0401         !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
0402 
0403         tpm_dev.iotype = TPM_INF_IO_PORT;
0404 
0405         tpm_dev.config_port = pnp_port_start(dev, 0);
0406         tpm_dev.config_size = pnp_port_len(dev, 0);
0407         tpm_dev.data_regs = pnp_port_start(dev, 1);
0408         tpm_dev.data_size = pnp_port_len(dev, 1);
0409         if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) {
0410             rc = -EINVAL;
0411             goto err_last;
0412         }
0413         dev_info(&dev->dev, "Found %s with ID %s\n",
0414              dev->name, dev_id->id);
0415         if (!((tpm_dev.data_regs >> 8) & 0xff)) {
0416             rc = -EINVAL;
0417             goto err_last;
0418         }
0419         /* publish my base address and request region */
0420         if (request_region(tpm_dev.data_regs, tpm_dev.data_size,
0421                    "tpm_infineon0") == NULL) {
0422             rc = -EINVAL;
0423             goto err_last;
0424         }
0425         if (request_region(tpm_dev.config_port, tpm_dev.config_size,
0426                    "tpm_infineon0") == NULL) {
0427             release_region(tpm_dev.data_regs, tpm_dev.data_size);
0428             rc = -EINVAL;
0429             goto err_last;
0430         }
0431     } else if (pnp_mem_valid(dev, 0) &&
0432            !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
0433 
0434         tpm_dev.iotype = TPM_INF_IO_MEM;
0435 
0436         tpm_dev.map_base = pnp_mem_start(dev, 0);
0437         tpm_dev.map_size = pnp_mem_len(dev, 0);
0438 
0439         dev_info(&dev->dev, "Found %s with ID %s\n",
0440              dev->name, dev_id->id);
0441 
0442         /* publish my base address and request region */
0443         if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size,
0444                        "tpm_infineon0") == NULL) {
0445             rc = -EINVAL;
0446             goto err_last;
0447         }
0448 
0449         tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size);
0450         if (tpm_dev.mem_base == NULL) {
0451             release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
0452             rc = -EINVAL;
0453             goto err_last;
0454         }
0455 
0456         /*
0457          * The only known MMIO based Infineon TPM system provides
0458          * a single large mem region with the device config
0459          * registers at the default TPM_ADDR.  The data registers
0460          * seem like they could be placed anywhere within the MMIO
0461          * region, but lets just put them at zero offset.
0462          */
0463         tpm_dev.index_off = TPM_ADDR;
0464         tpm_dev.data_regs = 0x0;
0465     } else {
0466         rc = -EINVAL;
0467         goto err_last;
0468     }
0469 
0470     /* query chip for its vendor, its version number a.s.o. */
0471     tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
0472     tpm_config_out(IDVENL, TPM_INF_ADDR);
0473     vendorid[1] = tpm_config_in(TPM_INF_DATA);
0474     tpm_config_out(IDVENH, TPM_INF_ADDR);
0475     vendorid[0] = tpm_config_in(TPM_INF_DATA);
0476     tpm_config_out(IDPDL, TPM_INF_ADDR);
0477     productid[1] = tpm_config_in(TPM_INF_DATA);
0478     tpm_config_out(IDPDH, TPM_INF_ADDR);
0479     productid[0] = tpm_config_in(TPM_INF_DATA);
0480     tpm_config_out(CHIP_ID1, TPM_INF_ADDR);
0481     version[1] = tpm_config_in(TPM_INF_DATA);
0482     tpm_config_out(CHIP_ID2, TPM_INF_ADDR);
0483     version[0] = tpm_config_in(TPM_INF_DATA);
0484 
0485     switch ((productid[0] << 8) | productid[1]) {
0486     case 6:
0487         chipname = " (SLD 9630 TT 1.1)";
0488         break;
0489     case 11:
0490         chipname = " (SLB 9635 TT 1.2)";
0491         break;
0492     default:
0493         chipname = " (unknown chip)";
0494         break;
0495     }
0496 
0497     if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
0498 
0499         /* configure TPM with IO-ports */
0500         tpm_config_out(IOLIMH, TPM_INF_ADDR);
0501         tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
0502         tpm_config_out(IOLIML, TPM_INF_ADDR);
0503         tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
0504 
0505         /* control if IO-ports are set correctly */
0506         tpm_config_out(IOLIMH, TPM_INF_ADDR);
0507         ioh = tpm_config_in(TPM_INF_DATA);
0508         tpm_config_out(IOLIML, TPM_INF_ADDR);
0509         iol = tpm_config_in(TPM_INF_DATA);
0510 
0511         if ((ioh << 8 | iol) != tpm_dev.data_regs) {
0512             dev_err(&dev->dev,
0513                 "Could not set IO-data registers to 0x%x\n",
0514                 tpm_dev.data_regs);
0515             rc = -EIO;
0516             goto err_release_region;
0517         }
0518 
0519         /* activate register */
0520         tpm_config_out(TPM_DAR, TPM_INF_ADDR);
0521         tpm_config_out(0x01, TPM_INF_DATA);
0522         tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
0523 
0524         /* disable RESET, LP and IRQC */
0525         tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
0526 
0527         /* Finally, we're done, print some infos */
0528         dev_info(&dev->dev, "TPM found: "
0529              "config base 0x%lx, "
0530              "data base 0x%lx, "
0531              "chip version 0x%02x%02x, "
0532              "vendor id 0x%x%x (Infineon), "
0533              "product id 0x%02x%02x"
0534              "%s\n",
0535              tpm_dev.iotype == TPM_INF_IO_PORT ?
0536              tpm_dev.config_port :
0537              tpm_dev.map_base + tpm_dev.index_off,
0538              tpm_dev.iotype == TPM_INF_IO_PORT ?
0539              tpm_dev.data_regs :
0540              tpm_dev.map_base + tpm_dev.data_regs,
0541              version[0], version[1],
0542              vendorid[0], vendorid[1],
0543              productid[0], productid[1], chipname);
0544 
0545         chip = tpmm_chip_alloc(&dev->dev, &tpm_inf);
0546         if (IS_ERR(chip)) {
0547             rc = PTR_ERR(chip);
0548             goto err_release_region;
0549         }
0550 
0551         rc = tpm_chip_register(chip);
0552         if (rc)
0553             goto err_release_region;
0554 
0555         return 0;
0556     } else {
0557         rc = -ENODEV;
0558         goto err_release_region;
0559     }
0560 
0561 err_release_region:
0562     if (tpm_dev.iotype == TPM_INF_IO_PORT) {
0563         release_region(tpm_dev.data_regs, tpm_dev.data_size);
0564         release_region(tpm_dev.config_port, tpm_dev.config_size);
0565     } else {
0566         iounmap(tpm_dev.mem_base);
0567         release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
0568     }
0569 
0570 err_last:
0571     return rc;
0572 }
0573 
0574 static void tpm_inf_pnp_remove(struct pnp_dev *dev)
0575 {
0576     struct tpm_chip *chip = pnp_get_drvdata(dev);
0577 
0578     tpm_chip_unregister(chip);
0579 
0580     if (tpm_dev.iotype == TPM_INF_IO_PORT) {
0581         release_region(tpm_dev.data_regs, tpm_dev.data_size);
0582         release_region(tpm_dev.config_port,
0583                    tpm_dev.config_size);
0584     } else {
0585         iounmap(tpm_dev.mem_base);
0586         release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
0587     }
0588 }
0589 
0590 #ifdef CONFIG_PM_SLEEP
0591 static int tpm_inf_resume(struct device *dev)
0592 {
0593     /* Re-configure TPM after suspending */
0594     tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
0595     tpm_config_out(IOLIMH, TPM_INF_ADDR);
0596     tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
0597     tpm_config_out(IOLIML, TPM_INF_ADDR);
0598     tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
0599     /* activate register */
0600     tpm_config_out(TPM_DAR, TPM_INF_ADDR);
0601     tpm_config_out(0x01, TPM_INF_DATA);
0602     tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
0603     /* disable RESET, LP and IRQC */
0604     tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
0605     return tpm_pm_resume(dev);
0606 }
0607 #endif
0608 static SIMPLE_DEV_PM_OPS(tpm_inf_pm, tpm_pm_suspend, tpm_inf_resume);
0609 
0610 static struct pnp_driver tpm_inf_pnp_driver = {
0611     .name = "tpm_inf_pnp",
0612     .id_table = tpm_inf_pnp_tbl,
0613     .probe = tpm_inf_pnp_probe,
0614     .remove = tpm_inf_pnp_remove,
0615     .driver = {
0616         .pm = &tpm_inf_pm,
0617     }
0618 };
0619 
0620 module_pnp_driver(tpm_inf_pnp_driver);
0621 
0622 MODULE_AUTHOR("Marcel Selhorst <tpmdd@sirrix.com>");
0623 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
0624 MODULE_VERSION("1.9.2");
0625 MODULE_LICENSE("GPL");