Loading Documentation/devicetree/bindings/i2c/trivial-devices.txt +2 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ fsl,mc13892 MC13892: Power Management Integrated Circuit (PMIC) for i.MX35/51 fsl,mma8450 MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer fsl,mpr121 MPR121: Proximity Capacitive Touch Sensor Controller fsl,sgtl5000 SGTL5000: Ultra Low-Power Audio Codec infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz) infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz) maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface Loading drivers/char/tpm/tpm.c +27 −4 Original line number Diff line number Diff line Loading @@ -1337,7 +1337,7 @@ int tpm_pm_suspend(struct device *dev) { struct tpm_chip *chip = dev_get_drvdata(dev); struct tpm_cmd_t cmd; int rc; int rc, try; u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 }; Loading @@ -1355,9 +1355,32 @@ int tpm_pm_suspend(struct device *dev) } /* now do the actual savestate */ for (try = 0; try < TPM_RETRY; try++) { cmd.header.in = savestate_header; rc = transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, "sending savestate before suspend"); rc = transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, NULL); /* * If the TPM indicates that it is too busy to respond to * this command then retry before giving up. It can take * several seconds for this TPM to be ready. * * This can happen if the TPM has already been sent the * SaveState command before the driver has loaded. TCG 1.2 * specification states that any communication after SaveState * may cause the TPM to invalidate previously saved state. */ if (rc != TPM_WARN_RETRY) break; msleep(TPM_TIMEOUT_RETRY); } if (rc) dev_err(chip->dev, "Error (%d) sending savestate before suspend\n", rc); else if (try > 0) dev_warn(chip->dev, "TPM savestate took %dms\n", try * TPM_TIMEOUT_RETRY); return rc; } EXPORT_SYMBOL_GPL(tpm_pm_suspend); Loading drivers/char/tpm/tpm.h +3 −0 Original line number Diff line number Diff line Loading @@ -32,10 +32,12 @@ enum tpm_const { TPM_MINOR = 224, /* officially assigned */ TPM_BUFSIZE = 4096, TPM_NUM_DEVICES = 256, TPM_RETRY = 50, /* 5 seconds */ }; enum tpm_timeout { TPM_TIMEOUT = 5, /* msecs */ TPM_TIMEOUT_RETRY = 100 /* msecs */ }; /* TPM addresses */ Loading @@ -44,6 +46,7 @@ enum tpm_addr { TPM_ADDR = 0x4E, }; #define TPM_WARN_RETRY 0x800 #define TPM_WARN_DOING_SELFTEST 0x802 #define TPM_ERR_DEACTIVATED 0x6 #define TPM_ERR_DISABLED 0x7 Loading drivers/char/tpm/tpm_i2c_infineon.c +137 −43 Original line number Diff line number Diff line /* * Copyright (C) 2012 Infineon Technologies * Copyright (C) 2012,2013 Infineon Technologies * * Authors: * Peter Huewe <peter.huewe@infineon.com> Loading Loading @@ -56,13 +56,21 @@ #define TPM_TIMEOUT_US_HI (TPM_TIMEOUT_US_LOW + 2000) /* expected value for DIDVID register */ #define TPM_TIS_I2C_DID_VID 0x000b15d1L #define TPM_TIS_I2C_DID_VID_9635 0xd1150b00L #define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L enum i2c_chip_type { SLB9635, SLB9645, UNKNOWN, }; /* Structure to store I2C TPM specific stuff */ struct tpm_inf_dev { struct i2c_client *client; u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */ struct tpm_chip *chip; enum i2c_chip_type chip_type; }; static struct tpm_inf_dev tpm_dev; Loading Loading @@ -90,10 +98,20 @@ static struct i2c_driver tpm_tis_i2c_driver; static int iic_tpm_read(u8 addr, u8 *buffer, size_t len) { struct i2c_msg msg1 = { tpm_dev.client->addr, 0, 1, &addr }; struct i2c_msg msg2 = { tpm_dev.client->addr, I2C_M_RD, len, buffer }; struct i2c_msg msg1 = { .addr = tpm_dev.client->addr, .len = 1, .buf = &addr }; struct i2c_msg msg2 = { .addr = tpm_dev.client->addr, .flags = I2C_M_RD, .len = len, .buf = buffer }; struct i2c_msg msgs[] = {msg1, msg2}; int rc; int rc = 0; int count; /* Lock the adapter for the duration of the whole sequence. */ Loading @@ -101,6 +119,21 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len) return -EOPNOTSUPP; i2c_lock_adapter(tpm_dev.client->adapter); if (tpm_dev.chip_type == SLB9645) { /* use a combined read for newer chips * unfortunately the smbus functions are not suitable due to * the 32 byte limit of the smbus. * retries should usually not be needed, but are kept just to * be on the safe side. */ for (count = 0; count < MAX_COUNT; count++) { rc = __i2c_transfer(tpm_dev.client->adapter, msgs, 2); if (rc > 0) break; /* break here to skip sleep */ usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); } } else { /* slb9635 protocol should work in all cases */ for (count = 0; count < MAX_COUNT; count++) { rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1); if (rc > 0) Loading @@ -112,19 +145,27 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len) if (rc <= 0) goto out; /* After the TPM has successfully received the register address it needs * some time, thus we're sleeping here again, before retrieving the data /* After the TPM has successfully received the register address * it needs some time, thus we're sleeping here again, before * retrieving the data */ for (count = 0; count < MAX_COUNT; count++) { usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); rc = __i2c_transfer(tpm_dev.client->adapter, &msg2, 1); if (rc > 0) break; } } out: i2c_unlock_adapter(tpm_dev.client->adapter); /* take care of 'guard time' */ usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); /* __i2c_transfer returns the number of successfully transferred * messages. * So rc should be greater than 0 here otherwise we have an error. */ if (rc <= 0) return -EIO; Loading @@ -138,7 +179,11 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len, int rc = -EIO; int count; struct i2c_msg msg1 = { tpm_dev.client->addr, 0, len + 1, tpm_dev.buf }; struct i2c_msg msg1 = { .addr = tpm_dev.client->addr, .len = len + 1, .buf = tpm_dev.buf }; if (len > TPM_BUFSIZE) return -EINVAL; Loading @@ -154,16 +199,24 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len, /* * NOTE: We have to use these special mechanisms here and unfortunately * cannot rely on the standard behavior of i2c_transfer. * Even for newer chips the smbus functions are not * suitable due to the 32 byte limit of the smbus. */ for (count = 0; count < max_count; count++) { rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1); if (rc > 0) break; usleep_range(sleep_low, sleep_hi); } i2c_unlock_adapter(tpm_dev.client->adapter); /* take care of 'guard time' */ usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); /* __i2c_transfer returns the number of successfully transferred * messages. * So rc should be greater than 0 here otherwise we have an error. */ if (rc <= 0) return -EIO; Loading Loading @@ -283,10 +336,17 @@ static int request_locality(struct tpm_chip *chip, int loc) static u8 tpm_tis_i2c_status(struct tpm_chip *chip) { /* NOTE: since I2C read may fail, return 0 in this case --> time-out */ u8 buf; u8 buf = 0xFF; u8 i = 0; do { if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0) return 0; else i++; /* if locallity is set STS should not be 0xFF */ } while ((buf == 0xFF) && i < 10); return buf; } Loading Loading @@ -328,7 +388,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, /* check current status */ *status = tpm_tis_i2c_status(chip); if ((*status & mask) == mask) if ((*status != 0xFF) && (*status & mask) == mask) return 0; stop = jiffies + timeout; Loading Loading @@ -372,7 +432,6 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) /* avoid endless loop in case of broken HW */ if (retries > MAX_COUNT_LONG) return -EIO; } return size; } Loading Loading @@ -480,7 +539,6 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len) rc = -EIO; goto out_err; } } /* write last byte */ Loading Loading @@ -568,6 +626,7 @@ static int tpm_tis_i2c_init(struct device *dev) chip = tpm_register_hardware(dev, &tpm_tis_i2c); if (!chip) { dev_err(dev, "could not register hardware\n"); rc = -ENODEV; goto out_err; } Loading @@ -582,20 +641,24 @@ static int tpm_tis_i2c_init(struct device *dev) chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); if (request_locality(chip, 0) != 0) { dev_err(dev, "could not request locality\n"); rc = -ENODEV; goto out_vendor; } /* read four bytes from DID_VID register */ if (iic_tpm_read(TPM_DID_VID(0), (u8 *)&vendor, 4) < 0) { dev_err(dev, "could not read vendor id\n"); rc = -EIO; goto out_release; } /* create DID_VID register value, after swapping to little-endian */ vendor = be32_to_cpu((__be32) vendor); if (vendor != TPM_TIS_I2C_DID_VID) { if (vendor == TPM_TIS_I2C_DID_VID_9645) { tpm_dev.chip_type = SLB9645; } else if (vendor == TPM_TIS_I2C_DID_VID_9635) { tpm_dev.chip_type = SLB9635; } else { dev_err(dev, "vendor id did not match! ID was %08x\n", vendor); rc = -ENODEV; goto out_release; } Loading Loading @@ -631,22 +694,53 @@ out_err: static const struct i2c_device_id tpm_tis_i2c_table[] = { {"tpm_i2c_infineon", 0}, {"slb9635tt", 0}, {"slb9645tt", 1}, {}, }; MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_table); #ifdef CONFIG_OF static const struct of_device_id tpm_tis_i2c_of_match[] = { { .name = "tpm_i2c_infineon", .type = "tpm", .compatible = "infineon,tpm_i2c_infineon", .data = (void *)0 }, { .name = "slb9635tt", .type = "tpm", .compatible = "infineon,slb9635tt", .data = (void *)0 }, { .name = "slb9645tt", .type = "tpm", .compatible = "infineon,slb9645tt", .data = (void *)1 }, {}, }; MODULE_DEVICE_TABLE(of, tpm_tis_i2c_of_match); #endif static SIMPLE_DEV_PM_OPS(tpm_tis_i2c_ops, tpm_pm_suspend, tpm_pm_resume); static int tpm_tis_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int rc; if (tpm_dev.client != NULL) struct device *dev = &(client->dev); if (tpm_dev.client != NULL) { dev_err(dev, "This driver only supports one client at a time\n"); return -EBUSY; /* We only support one client */ } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "no algorithms associated to the i2c bus\n"); dev_err(dev, "no algorithms associated to the i2c bus\n"); return -ENODEV; } Loading Loading @@ -682,7 +776,6 @@ static int tpm_tis_i2c_remove(struct i2c_client *client) } static struct i2c_driver tpm_tis_i2c_driver = { .id_table = tpm_tis_i2c_table, .probe = tpm_tis_i2c_probe, .remove = tpm_tis_i2c_remove, Loading @@ -690,11 +783,12 @@ static struct i2c_driver tpm_tis_i2c_driver = { .name = "tpm_i2c_infineon", .owner = THIS_MODULE, .pm = &tpm_tis_i2c_ops, .of_match_table = of_match_ptr(tpm_tis_i2c_of_match), }, }; module_i2c_driver(tpm_tis_i2c_driver); MODULE_AUTHOR("Peter Huewe <peter.huewe@infineon.com>"); MODULE_DESCRIPTION("TPM TIS I2C Infineon Driver"); MODULE_VERSION("2.1.5"); MODULE_VERSION("2.2.0"); MODULE_LICENSE("GPL"); drivers/char/tpm/tpm_i2c_stm_st33.c +31 −33 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ #include <linux/i2c.h> #include <linux/fs.h> #include <linux/miscdevice.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/init.h> Loading @@ -50,7 +49,6 @@ #include <linux/uaccess.h> #include <linux/io.h> #include <linux/slab.h> #include <linux/sched.h> #include "tpm.h" #include "tpm_i2c_stm_st33.h" Loading Loading @@ -453,8 +451,7 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id) static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf, size_t len) { u32 status, burstcnt = 0, i, size; u32 status, burstcnt = 0, i, size; int ret; u8 data; struct i2c_client *client; Loading Loading @@ -823,9 +820,9 @@ static int tpm_st33_i2c_pm_suspend(struct device *dev) struct st33zp24_platform_data *pin_infos = dev->platform_data; int ret = 0; if (power_mgt) if (power_mgt) { gpio_set_value(pin_infos->io_lpcpd, 0); else{ } else { if (chip->data_buffer == NULL) chip->data_buffer = pin_infos->tpm_i2c_buffer[0]; ret = tpm_pm_suspend(dev); Loading Loading @@ -867,7 +864,8 @@ static const struct i2c_device_id tpm_st33_i2c_id[] = { {} }; MODULE_DEVICE_TABLE(i2c, tpm_st33_i2c_id); static SIMPLE_DEV_PM_OPS(tpm_st33_i2c_ops, tpm_st33_i2c_pm_suspend, tpm_st33_i2c_pm_resume); static SIMPLE_DEV_PM_OPS(tpm_st33_i2c_ops, tpm_st33_i2c_pm_suspend, tpm_st33_i2c_pm_resume); static struct i2c_driver tpm_st33_i2c_driver = { .driver = { .owner = THIS_MODULE, Loading Loading
Documentation/devicetree/bindings/i2c/trivial-devices.txt +2 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ fsl,mc13892 MC13892: Power Management Integrated Circuit (PMIC) for i.MX35/51 fsl,mma8450 MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer fsl,mpr121 MPR121: Proximity Capacitive Touch Sensor Controller fsl,sgtl5000 SGTL5000: Ultra Low-Power Audio Codec infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz) infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz) maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface Loading
drivers/char/tpm/tpm.c +27 −4 Original line number Diff line number Diff line Loading @@ -1337,7 +1337,7 @@ int tpm_pm_suspend(struct device *dev) { struct tpm_chip *chip = dev_get_drvdata(dev); struct tpm_cmd_t cmd; int rc; int rc, try; u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 }; Loading @@ -1355,9 +1355,32 @@ int tpm_pm_suspend(struct device *dev) } /* now do the actual savestate */ for (try = 0; try < TPM_RETRY; try++) { cmd.header.in = savestate_header; rc = transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, "sending savestate before suspend"); rc = transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, NULL); /* * If the TPM indicates that it is too busy to respond to * this command then retry before giving up. It can take * several seconds for this TPM to be ready. * * This can happen if the TPM has already been sent the * SaveState command before the driver has loaded. TCG 1.2 * specification states that any communication after SaveState * may cause the TPM to invalidate previously saved state. */ if (rc != TPM_WARN_RETRY) break; msleep(TPM_TIMEOUT_RETRY); } if (rc) dev_err(chip->dev, "Error (%d) sending savestate before suspend\n", rc); else if (try > 0) dev_warn(chip->dev, "TPM savestate took %dms\n", try * TPM_TIMEOUT_RETRY); return rc; } EXPORT_SYMBOL_GPL(tpm_pm_suspend); Loading
drivers/char/tpm/tpm.h +3 −0 Original line number Diff line number Diff line Loading @@ -32,10 +32,12 @@ enum tpm_const { TPM_MINOR = 224, /* officially assigned */ TPM_BUFSIZE = 4096, TPM_NUM_DEVICES = 256, TPM_RETRY = 50, /* 5 seconds */ }; enum tpm_timeout { TPM_TIMEOUT = 5, /* msecs */ TPM_TIMEOUT_RETRY = 100 /* msecs */ }; /* TPM addresses */ Loading @@ -44,6 +46,7 @@ enum tpm_addr { TPM_ADDR = 0x4E, }; #define TPM_WARN_RETRY 0x800 #define TPM_WARN_DOING_SELFTEST 0x802 #define TPM_ERR_DEACTIVATED 0x6 #define TPM_ERR_DISABLED 0x7 Loading
drivers/char/tpm/tpm_i2c_infineon.c +137 −43 Original line number Diff line number Diff line /* * Copyright (C) 2012 Infineon Technologies * Copyright (C) 2012,2013 Infineon Technologies * * Authors: * Peter Huewe <peter.huewe@infineon.com> Loading Loading @@ -56,13 +56,21 @@ #define TPM_TIMEOUT_US_HI (TPM_TIMEOUT_US_LOW + 2000) /* expected value for DIDVID register */ #define TPM_TIS_I2C_DID_VID 0x000b15d1L #define TPM_TIS_I2C_DID_VID_9635 0xd1150b00L #define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L enum i2c_chip_type { SLB9635, SLB9645, UNKNOWN, }; /* Structure to store I2C TPM specific stuff */ struct tpm_inf_dev { struct i2c_client *client; u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */ struct tpm_chip *chip; enum i2c_chip_type chip_type; }; static struct tpm_inf_dev tpm_dev; Loading Loading @@ -90,10 +98,20 @@ static struct i2c_driver tpm_tis_i2c_driver; static int iic_tpm_read(u8 addr, u8 *buffer, size_t len) { struct i2c_msg msg1 = { tpm_dev.client->addr, 0, 1, &addr }; struct i2c_msg msg2 = { tpm_dev.client->addr, I2C_M_RD, len, buffer }; struct i2c_msg msg1 = { .addr = tpm_dev.client->addr, .len = 1, .buf = &addr }; struct i2c_msg msg2 = { .addr = tpm_dev.client->addr, .flags = I2C_M_RD, .len = len, .buf = buffer }; struct i2c_msg msgs[] = {msg1, msg2}; int rc; int rc = 0; int count; /* Lock the adapter for the duration of the whole sequence. */ Loading @@ -101,6 +119,21 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len) return -EOPNOTSUPP; i2c_lock_adapter(tpm_dev.client->adapter); if (tpm_dev.chip_type == SLB9645) { /* use a combined read for newer chips * unfortunately the smbus functions are not suitable due to * the 32 byte limit of the smbus. * retries should usually not be needed, but are kept just to * be on the safe side. */ for (count = 0; count < MAX_COUNT; count++) { rc = __i2c_transfer(tpm_dev.client->adapter, msgs, 2); if (rc > 0) break; /* break here to skip sleep */ usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); } } else { /* slb9635 protocol should work in all cases */ for (count = 0; count < MAX_COUNT; count++) { rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1); if (rc > 0) Loading @@ -112,19 +145,27 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len) if (rc <= 0) goto out; /* After the TPM has successfully received the register address it needs * some time, thus we're sleeping here again, before retrieving the data /* After the TPM has successfully received the register address * it needs some time, thus we're sleeping here again, before * retrieving the data */ for (count = 0; count < MAX_COUNT; count++) { usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); rc = __i2c_transfer(tpm_dev.client->adapter, &msg2, 1); if (rc > 0) break; } } out: i2c_unlock_adapter(tpm_dev.client->adapter); /* take care of 'guard time' */ usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); /* __i2c_transfer returns the number of successfully transferred * messages. * So rc should be greater than 0 here otherwise we have an error. */ if (rc <= 0) return -EIO; Loading @@ -138,7 +179,11 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len, int rc = -EIO; int count; struct i2c_msg msg1 = { tpm_dev.client->addr, 0, len + 1, tpm_dev.buf }; struct i2c_msg msg1 = { .addr = tpm_dev.client->addr, .len = len + 1, .buf = tpm_dev.buf }; if (len > TPM_BUFSIZE) return -EINVAL; Loading @@ -154,16 +199,24 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len, /* * NOTE: We have to use these special mechanisms here and unfortunately * cannot rely on the standard behavior of i2c_transfer. * Even for newer chips the smbus functions are not * suitable due to the 32 byte limit of the smbus. */ for (count = 0; count < max_count; count++) { rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1); if (rc > 0) break; usleep_range(sleep_low, sleep_hi); } i2c_unlock_adapter(tpm_dev.client->adapter); /* take care of 'guard time' */ usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); /* __i2c_transfer returns the number of successfully transferred * messages. * So rc should be greater than 0 here otherwise we have an error. */ if (rc <= 0) return -EIO; Loading Loading @@ -283,10 +336,17 @@ static int request_locality(struct tpm_chip *chip, int loc) static u8 tpm_tis_i2c_status(struct tpm_chip *chip) { /* NOTE: since I2C read may fail, return 0 in this case --> time-out */ u8 buf; u8 buf = 0xFF; u8 i = 0; do { if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0) return 0; else i++; /* if locallity is set STS should not be 0xFF */ } while ((buf == 0xFF) && i < 10); return buf; } Loading Loading @@ -328,7 +388,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, /* check current status */ *status = tpm_tis_i2c_status(chip); if ((*status & mask) == mask) if ((*status != 0xFF) && (*status & mask) == mask) return 0; stop = jiffies + timeout; Loading Loading @@ -372,7 +432,6 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) /* avoid endless loop in case of broken HW */ if (retries > MAX_COUNT_LONG) return -EIO; } return size; } Loading Loading @@ -480,7 +539,6 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len) rc = -EIO; goto out_err; } } /* write last byte */ Loading Loading @@ -568,6 +626,7 @@ static int tpm_tis_i2c_init(struct device *dev) chip = tpm_register_hardware(dev, &tpm_tis_i2c); if (!chip) { dev_err(dev, "could not register hardware\n"); rc = -ENODEV; goto out_err; } Loading @@ -582,20 +641,24 @@ static int tpm_tis_i2c_init(struct device *dev) chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); if (request_locality(chip, 0) != 0) { dev_err(dev, "could not request locality\n"); rc = -ENODEV; goto out_vendor; } /* read four bytes from DID_VID register */ if (iic_tpm_read(TPM_DID_VID(0), (u8 *)&vendor, 4) < 0) { dev_err(dev, "could not read vendor id\n"); rc = -EIO; goto out_release; } /* create DID_VID register value, after swapping to little-endian */ vendor = be32_to_cpu((__be32) vendor); if (vendor != TPM_TIS_I2C_DID_VID) { if (vendor == TPM_TIS_I2C_DID_VID_9645) { tpm_dev.chip_type = SLB9645; } else if (vendor == TPM_TIS_I2C_DID_VID_9635) { tpm_dev.chip_type = SLB9635; } else { dev_err(dev, "vendor id did not match! ID was %08x\n", vendor); rc = -ENODEV; goto out_release; } Loading Loading @@ -631,22 +694,53 @@ out_err: static const struct i2c_device_id tpm_tis_i2c_table[] = { {"tpm_i2c_infineon", 0}, {"slb9635tt", 0}, {"slb9645tt", 1}, {}, }; MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_table); #ifdef CONFIG_OF static const struct of_device_id tpm_tis_i2c_of_match[] = { { .name = "tpm_i2c_infineon", .type = "tpm", .compatible = "infineon,tpm_i2c_infineon", .data = (void *)0 }, { .name = "slb9635tt", .type = "tpm", .compatible = "infineon,slb9635tt", .data = (void *)0 }, { .name = "slb9645tt", .type = "tpm", .compatible = "infineon,slb9645tt", .data = (void *)1 }, {}, }; MODULE_DEVICE_TABLE(of, tpm_tis_i2c_of_match); #endif static SIMPLE_DEV_PM_OPS(tpm_tis_i2c_ops, tpm_pm_suspend, tpm_pm_resume); static int tpm_tis_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int rc; if (tpm_dev.client != NULL) struct device *dev = &(client->dev); if (tpm_dev.client != NULL) { dev_err(dev, "This driver only supports one client at a time\n"); return -EBUSY; /* We only support one client */ } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "no algorithms associated to the i2c bus\n"); dev_err(dev, "no algorithms associated to the i2c bus\n"); return -ENODEV; } Loading Loading @@ -682,7 +776,6 @@ static int tpm_tis_i2c_remove(struct i2c_client *client) } static struct i2c_driver tpm_tis_i2c_driver = { .id_table = tpm_tis_i2c_table, .probe = tpm_tis_i2c_probe, .remove = tpm_tis_i2c_remove, Loading @@ -690,11 +783,12 @@ static struct i2c_driver tpm_tis_i2c_driver = { .name = "tpm_i2c_infineon", .owner = THIS_MODULE, .pm = &tpm_tis_i2c_ops, .of_match_table = of_match_ptr(tpm_tis_i2c_of_match), }, }; module_i2c_driver(tpm_tis_i2c_driver); MODULE_AUTHOR("Peter Huewe <peter.huewe@infineon.com>"); MODULE_DESCRIPTION("TPM TIS I2C Infineon Driver"); MODULE_VERSION("2.1.5"); MODULE_VERSION("2.2.0"); MODULE_LICENSE("GPL");
drivers/char/tpm/tpm_i2c_stm_st33.c +31 −33 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ #include <linux/i2c.h> #include <linux/fs.h> #include <linux/miscdevice.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/init.h> Loading @@ -50,7 +49,6 @@ #include <linux/uaccess.h> #include <linux/io.h> #include <linux/slab.h> #include <linux/sched.h> #include "tpm.h" #include "tpm_i2c_stm_st33.h" Loading Loading @@ -453,8 +451,7 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id) static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf, size_t len) { u32 status, burstcnt = 0, i, size; u32 status, burstcnt = 0, i, size; int ret; u8 data; struct i2c_client *client; Loading Loading @@ -823,9 +820,9 @@ static int tpm_st33_i2c_pm_suspend(struct device *dev) struct st33zp24_platform_data *pin_infos = dev->platform_data; int ret = 0; if (power_mgt) if (power_mgt) { gpio_set_value(pin_infos->io_lpcpd, 0); else{ } else { if (chip->data_buffer == NULL) chip->data_buffer = pin_infos->tpm_i2c_buffer[0]; ret = tpm_pm_suspend(dev); Loading Loading @@ -867,7 +864,8 @@ static const struct i2c_device_id tpm_st33_i2c_id[] = { {} }; MODULE_DEVICE_TABLE(i2c, tpm_st33_i2c_id); static SIMPLE_DEV_PM_OPS(tpm_st33_i2c_ops, tpm_st33_i2c_pm_suspend, tpm_st33_i2c_pm_resume); static SIMPLE_DEV_PM_OPS(tpm_st33_i2c_ops, tpm_st33_i2c_pm_suspend, tpm_st33_i2c_pm_resume); static struct i2c_driver tpm_st33_i2c_driver = { .driver = { .owner = THIS_MODULE, Loading