diff options
author | James Morris <james.l.morris@oracle.com> | 2013-04-20 12:00:45 -0400 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2013-04-20 12:00:45 -0400 |
commit | b7ae9f064bec903bd4a9f257a35da4d1e9bbcc99 (patch) | |
tree | ce1d1f40a1050f8ed1a3bd33c7ff226e250bf77e | |
parent | df2c2afba4fa867616436364633c7612ccfba84b (diff) | |
parent | 32d33b29ba077d6b45de35f2181e0a7411b162f4 (diff) |
Merge branch 'tpmdd-04-17-13' of git://github.com/shpedoikal/linux into my-next
-rw-r--r-- | Documentation/devicetree/bindings/i2c/trivial-devices.txt | 2 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.c | 31 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 3 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_i2c_infineon.c | 180 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_i2c_stm_st33.c | 64 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_ppi.c | 14 |
6 files changed, 207 insertions, 87 deletions
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index 446859fcdca4..ad6a73852f08 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt | |||
@@ -35,6 +35,8 @@ fsl,mc13892 MC13892: Power Management Integrated Circuit (PMIC) for i.MX35/51 | |||
35 | fsl,mma8450 MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer | 35 | fsl,mma8450 MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer |
36 | fsl,mpr121 MPR121: Proximity Capacitive Touch Sensor Controller | 36 | fsl,mpr121 MPR121: Proximity Capacitive Touch Sensor Controller |
37 | fsl,sgtl5000 SGTL5000: Ultra Low-Power Audio Codec | 37 | fsl,sgtl5000 SGTL5000: Ultra Low-Power Audio Codec |
38 | infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz) | ||
39 | infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz) | ||
38 | maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator | 40 | maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator |
39 | maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs | 41 | maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs |
40 | maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface | 42 | maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 0d2e82f95577..7c3b3dcbfbc8 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -1337,7 +1337,7 @@ int tpm_pm_suspend(struct device *dev) | |||
1337 | { | 1337 | { |
1338 | struct tpm_chip *chip = dev_get_drvdata(dev); | 1338 | struct tpm_chip *chip = dev_get_drvdata(dev); |
1339 | struct tpm_cmd_t cmd; | 1339 | struct tpm_cmd_t cmd; |
1340 | int rc; | 1340 | int rc, try; |
1341 | 1341 | ||
1342 | u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 }; | 1342 | u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 }; |
1343 | 1343 | ||
@@ -1355,9 +1355,32 @@ int tpm_pm_suspend(struct device *dev) | |||
1355 | } | 1355 | } |
1356 | 1356 | ||
1357 | /* now do the actual savestate */ | 1357 | /* now do the actual savestate */ |
1358 | cmd.header.in = savestate_header; | 1358 | for (try = 0; try < TPM_RETRY; try++) { |
1359 | rc = transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, | 1359 | cmd.header.in = savestate_header; |
1360 | "sending savestate before suspend"); | 1360 | rc = transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, NULL); |
1361 | |||
1362 | /* | ||
1363 | * If the TPM indicates that it is too busy to respond to | ||
1364 | * this command then retry before giving up. It can take | ||
1365 | * several seconds for this TPM to be ready. | ||
1366 | * | ||
1367 | * This can happen if the TPM has already been sent the | ||
1368 | * SaveState command before the driver has loaded. TCG 1.2 | ||
1369 | * specification states that any communication after SaveState | ||
1370 | * may cause the TPM to invalidate previously saved state. | ||
1371 | */ | ||
1372 | if (rc != TPM_WARN_RETRY) | ||
1373 | break; | ||
1374 | msleep(TPM_TIMEOUT_RETRY); | ||
1375 | } | ||
1376 | |||
1377 | if (rc) | ||
1378 | dev_err(chip->dev, | ||
1379 | "Error (%d) sending savestate before suspend\n", rc); | ||
1380 | else if (try > 0) | ||
1381 | dev_warn(chip->dev, "TPM savestate took %dms\n", | ||
1382 | try * TPM_TIMEOUT_RETRY); | ||
1383 | |||
1361 | return rc; | 1384 | return rc; |
1362 | } | 1385 | } |
1363 | EXPORT_SYMBOL_GPL(tpm_pm_suspend); | 1386 | EXPORT_SYMBOL_GPL(tpm_pm_suspend); |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 81b52015f669..0770d1d79366 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -32,10 +32,12 @@ enum tpm_const { | |||
32 | TPM_MINOR = 224, /* officially assigned */ | 32 | TPM_MINOR = 224, /* officially assigned */ |
33 | TPM_BUFSIZE = 4096, | 33 | TPM_BUFSIZE = 4096, |
34 | TPM_NUM_DEVICES = 256, | 34 | TPM_NUM_DEVICES = 256, |
35 | TPM_RETRY = 50, /* 5 seconds */ | ||
35 | }; | 36 | }; |
36 | 37 | ||
37 | enum tpm_timeout { | 38 | enum tpm_timeout { |
38 | TPM_TIMEOUT = 5, /* msecs */ | 39 | TPM_TIMEOUT = 5, /* msecs */ |
40 | TPM_TIMEOUT_RETRY = 100 /* msecs */ | ||
39 | }; | 41 | }; |
40 | 42 | ||
41 | /* TPM addresses */ | 43 | /* TPM addresses */ |
@@ -44,6 +46,7 @@ enum tpm_addr { | |||
44 | TPM_ADDR = 0x4E, | 46 | TPM_ADDR = 0x4E, |
45 | }; | 47 | }; |
46 | 48 | ||
49 | #define TPM_WARN_RETRY 0x800 | ||
47 | #define TPM_WARN_DOING_SELFTEST 0x802 | 50 | #define TPM_WARN_DOING_SELFTEST 0x802 |
48 | #define TPM_ERR_DEACTIVATED 0x6 | 51 | #define TPM_ERR_DEACTIVATED 0x6 |
49 | #define TPM_ERR_DISABLED 0x7 | 52 | #define TPM_ERR_DISABLED 0x7 |
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index 8fe7ac3d095b..37d5dcc10ea7 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2012 Infineon Technologies | 2 | * Copyright (C) 2012,2013 Infineon Technologies |
3 | * | 3 | * |
4 | * Authors: | 4 | * Authors: |
5 | * Peter Huewe <peter.huewe@infineon.com> | 5 | * Peter Huewe <peter.huewe@infineon.com> |
@@ -56,13 +56,21 @@ | |||
56 | #define TPM_TIMEOUT_US_HI (TPM_TIMEOUT_US_LOW + 2000) | 56 | #define TPM_TIMEOUT_US_HI (TPM_TIMEOUT_US_LOW + 2000) |
57 | 57 | ||
58 | /* expected value for DIDVID register */ | 58 | /* expected value for DIDVID register */ |
59 | #define TPM_TIS_I2C_DID_VID 0x000b15d1L | 59 | #define TPM_TIS_I2C_DID_VID_9635 0xd1150b00L |
60 | #define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L | ||
61 | |||
62 | enum i2c_chip_type { | ||
63 | SLB9635, | ||
64 | SLB9645, | ||
65 | UNKNOWN, | ||
66 | }; | ||
60 | 67 | ||
61 | /* Structure to store I2C TPM specific stuff */ | 68 | /* Structure to store I2C TPM specific stuff */ |
62 | struct tpm_inf_dev { | 69 | struct tpm_inf_dev { |
63 | struct i2c_client *client; | 70 | struct i2c_client *client; |
64 | u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */ | 71 | u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */ |
65 | struct tpm_chip *chip; | 72 | struct tpm_chip *chip; |
73 | enum i2c_chip_type chip_type; | ||
66 | }; | 74 | }; |
67 | 75 | ||
68 | static struct tpm_inf_dev tpm_dev; | 76 | static struct tpm_inf_dev tpm_dev; |
@@ -90,10 +98,20 @@ static struct i2c_driver tpm_tis_i2c_driver; | |||
90 | static int iic_tpm_read(u8 addr, u8 *buffer, size_t len) | 98 | static int iic_tpm_read(u8 addr, u8 *buffer, size_t len) |
91 | { | 99 | { |
92 | 100 | ||
93 | struct i2c_msg msg1 = { tpm_dev.client->addr, 0, 1, &addr }; | 101 | struct i2c_msg msg1 = { |
94 | struct i2c_msg msg2 = { tpm_dev.client->addr, I2C_M_RD, len, buffer }; | 102 | .addr = tpm_dev.client->addr, |
103 | .len = 1, | ||
104 | .buf = &addr | ||
105 | }; | ||
106 | struct i2c_msg msg2 = { | ||
107 | .addr = tpm_dev.client->addr, | ||
108 | .flags = I2C_M_RD, | ||
109 | .len = len, | ||
110 | .buf = buffer | ||
111 | }; | ||
112 | struct i2c_msg msgs[] = {msg1, msg2}; | ||
95 | 113 | ||
96 | int rc; | 114 | int rc = 0; |
97 | int count; | 115 | int count; |
98 | 116 | ||
99 | /* Lock the adapter for the duration of the whole sequence. */ | 117 | /* Lock the adapter for the duration of the whole sequence. */ |
@@ -101,30 +119,53 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len) | |||
101 | return -EOPNOTSUPP; | 119 | return -EOPNOTSUPP; |
102 | i2c_lock_adapter(tpm_dev.client->adapter); | 120 | i2c_lock_adapter(tpm_dev.client->adapter); |
103 | 121 | ||
104 | for (count = 0; count < MAX_COUNT; count++) { | 122 | if (tpm_dev.chip_type == SLB9645) { |
105 | rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1); | 123 | /* use a combined read for newer chips |
106 | if (rc > 0) | 124 | * unfortunately the smbus functions are not suitable due to |
107 | break; /* break here to skip sleep */ | 125 | * the 32 byte limit of the smbus. |
108 | 126 | * retries should usually not be needed, but are kept just to | |
109 | usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); | 127 | * be on the safe side. |
110 | } | 128 | */ |
111 | 129 | for (count = 0; count < MAX_COUNT; count++) { | |
112 | if (rc <= 0) | 130 | rc = __i2c_transfer(tpm_dev.client->adapter, msgs, 2); |
113 | goto out; | 131 | if (rc > 0) |
114 | 132 | break; /* break here to skip sleep */ | |
115 | /* After the TPM has successfully received the register address it needs | 133 | usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); |
116 | * some time, thus we're sleeping here again, before retrieving the data | 134 | } |
117 | */ | 135 | } else { |
118 | for (count = 0; count < MAX_COUNT; count++) { | 136 | /* slb9635 protocol should work in all cases */ |
119 | usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); | 137 | for (count = 0; count < MAX_COUNT; count++) { |
120 | rc = __i2c_transfer(tpm_dev.client->adapter, &msg2, 1); | 138 | rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1); |
121 | if (rc > 0) | 139 | if (rc > 0) |
122 | break; | 140 | break; /* break here to skip sleep */ |
141 | |||
142 | usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); | ||
143 | } | ||
123 | 144 | ||
145 | if (rc <= 0) | ||
146 | goto out; | ||
147 | |||
148 | /* After the TPM has successfully received the register address | ||
149 | * it needs some time, thus we're sleeping here again, before | ||
150 | * retrieving the data | ||
151 | */ | ||
152 | for (count = 0; count < MAX_COUNT; count++) { | ||
153 | usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); | ||
154 | rc = __i2c_transfer(tpm_dev.client->adapter, &msg2, 1); | ||
155 | if (rc > 0) | ||
156 | break; | ||
157 | } | ||
124 | } | 158 | } |
125 | 159 | ||
126 | out: | 160 | out: |
127 | i2c_unlock_adapter(tpm_dev.client->adapter); | 161 | i2c_unlock_adapter(tpm_dev.client->adapter); |
162 | /* take care of 'guard time' */ | ||
163 | usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); | ||
164 | |||
165 | /* __i2c_transfer returns the number of successfully transferred | ||
166 | * messages. | ||
167 | * So rc should be greater than 0 here otherwise we have an error. | ||
168 | */ | ||
128 | if (rc <= 0) | 169 | if (rc <= 0) |
129 | return -EIO; | 170 | return -EIO; |
130 | 171 | ||
@@ -138,7 +179,11 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len, | |||
138 | int rc = -EIO; | 179 | int rc = -EIO; |
139 | int count; | 180 | int count; |
140 | 181 | ||
141 | struct i2c_msg msg1 = { tpm_dev.client->addr, 0, len + 1, tpm_dev.buf }; | 182 | struct i2c_msg msg1 = { |
183 | .addr = tpm_dev.client->addr, | ||
184 | .len = len + 1, | ||
185 | .buf = tpm_dev.buf | ||
186 | }; | ||
142 | 187 | ||
143 | if (len > TPM_BUFSIZE) | 188 | if (len > TPM_BUFSIZE) |
144 | return -EINVAL; | 189 | return -EINVAL; |
@@ -154,16 +199,24 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len, | |||
154 | /* | 199 | /* |
155 | * NOTE: We have to use these special mechanisms here and unfortunately | 200 | * NOTE: We have to use these special mechanisms here and unfortunately |
156 | * cannot rely on the standard behavior of i2c_transfer. | 201 | * cannot rely on the standard behavior of i2c_transfer. |
202 | * Even for newer chips the smbus functions are not | ||
203 | * suitable due to the 32 byte limit of the smbus. | ||
157 | */ | 204 | */ |
158 | for (count = 0; count < max_count; count++) { | 205 | for (count = 0; count < max_count; count++) { |
159 | rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1); | 206 | rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1); |
160 | if (rc > 0) | 207 | if (rc > 0) |
161 | break; | 208 | break; |
162 | |||
163 | usleep_range(sleep_low, sleep_hi); | 209 | usleep_range(sleep_low, sleep_hi); |
164 | } | 210 | } |
165 | 211 | ||
166 | i2c_unlock_adapter(tpm_dev.client->adapter); | 212 | i2c_unlock_adapter(tpm_dev.client->adapter); |
213 | /* take care of 'guard time' */ | ||
214 | usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI); | ||
215 | |||
216 | /* __i2c_transfer returns the number of successfully transferred | ||
217 | * messages. | ||
218 | * So rc should be greater than 0 here otherwise we have an error. | ||
219 | */ | ||
167 | if (rc <= 0) | 220 | if (rc <= 0) |
168 | return -EIO; | 221 | return -EIO; |
169 | 222 | ||
@@ -283,11 +336,18 @@ static int request_locality(struct tpm_chip *chip, int loc) | |||
283 | static u8 tpm_tis_i2c_status(struct tpm_chip *chip) | 336 | static u8 tpm_tis_i2c_status(struct tpm_chip *chip) |
284 | { | 337 | { |
285 | /* NOTE: since I2C read may fail, return 0 in this case --> time-out */ | 338 | /* NOTE: since I2C read may fail, return 0 in this case --> time-out */ |
286 | u8 buf; | 339 | u8 buf = 0xFF; |
287 | if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0) | 340 | u8 i = 0; |
288 | return 0; | 341 | |
289 | else | 342 | do { |
290 | return buf; | 343 | if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0) |
344 | return 0; | ||
345 | |||
346 | i++; | ||
347 | /* if locallity is set STS should not be 0xFF */ | ||
348 | } while ((buf == 0xFF) && i < 10); | ||
349 | |||
350 | return buf; | ||
291 | } | 351 | } |
292 | 352 | ||
293 | static void tpm_tis_i2c_ready(struct tpm_chip *chip) | 353 | static void tpm_tis_i2c_ready(struct tpm_chip *chip) |
@@ -328,7 +388,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, | |||
328 | 388 | ||
329 | /* check current status */ | 389 | /* check current status */ |
330 | *status = tpm_tis_i2c_status(chip); | 390 | *status = tpm_tis_i2c_status(chip); |
331 | if ((*status & mask) == mask) | 391 | if ((*status != 0xFF) && (*status & mask) == mask) |
332 | return 0; | 392 | return 0; |
333 | 393 | ||
334 | stop = jiffies + timeout; | 394 | stop = jiffies + timeout; |
@@ -372,7 +432,6 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) | |||
372 | /* avoid endless loop in case of broken HW */ | 432 | /* avoid endless loop in case of broken HW */ |
373 | if (retries > MAX_COUNT_LONG) | 433 | if (retries > MAX_COUNT_LONG) |
374 | return -EIO; | 434 | return -EIO; |
375 | |||
376 | } | 435 | } |
377 | return size; | 436 | return size; |
378 | } | 437 | } |
@@ -480,7 +539,6 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len) | |||
480 | rc = -EIO; | 539 | rc = -EIO; |
481 | goto out_err; | 540 | goto out_err; |
482 | } | 541 | } |
483 | |||
484 | } | 542 | } |
485 | 543 | ||
486 | /* write last byte */ | 544 | /* write last byte */ |
@@ -568,6 +626,7 @@ static int tpm_tis_i2c_init(struct device *dev) | |||
568 | 626 | ||
569 | chip = tpm_register_hardware(dev, &tpm_tis_i2c); | 627 | chip = tpm_register_hardware(dev, &tpm_tis_i2c); |
570 | if (!chip) { | 628 | if (!chip) { |
629 | dev_err(dev, "could not register hardware\n"); | ||
571 | rc = -ENODEV; | 630 | rc = -ENODEV; |
572 | goto out_err; | 631 | goto out_err; |
573 | } | 632 | } |
@@ -582,20 +641,24 @@ static int tpm_tis_i2c_init(struct device *dev) | |||
582 | chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); | 641 | chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); |
583 | 642 | ||
584 | if (request_locality(chip, 0) != 0) { | 643 | if (request_locality(chip, 0) != 0) { |
644 | dev_err(dev, "could not request locality\n"); | ||
585 | rc = -ENODEV; | 645 | rc = -ENODEV; |
586 | goto out_vendor; | 646 | goto out_vendor; |
587 | } | 647 | } |
588 | 648 | ||
589 | /* read four bytes from DID_VID register */ | 649 | /* read four bytes from DID_VID register */ |
590 | if (iic_tpm_read(TPM_DID_VID(0), (u8 *)&vendor, 4) < 0) { | 650 | if (iic_tpm_read(TPM_DID_VID(0), (u8 *)&vendor, 4) < 0) { |
651 | dev_err(dev, "could not read vendor id\n"); | ||
591 | rc = -EIO; | 652 | rc = -EIO; |
592 | goto out_release; | 653 | goto out_release; |
593 | } | 654 | } |
594 | 655 | ||
595 | /* create DID_VID register value, after swapping to little-endian */ | 656 | if (vendor == TPM_TIS_I2C_DID_VID_9645) { |
596 | vendor = be32_to_cpu((__be32) vendor); | 657 | tpm_dev.chip_type = SLB9645; |
597 | 658 | } else if (vendor == TPM_TIS_I2C_DID_VID_9635) { | |
598 | if (vendor != TPM_TIS_I2C_DID_VID) { | 659 | tpm_dev.chip_type = SLB9635; |
660 | } else { | ||
661 | dev_err(dev, "vendor id did not match! ID was %08x\n", vendor); | ||
599 | rc = -ENODEV; | 662 | rc = -ENODEV; |
600 | goto out_release; | 663 | goto out_release; |
601 | } | 664 | } |
@@ -631,22 +694,53 @@ out_err: | |||
631 | 694 | ||
632 | static const struct i2c_device_id tpm_tis_i2c_table[] = { | 695 | static const struct i2c_device_id tpm_tis_i2c_table[] = { |
633 | {"tpm_i2c_infineon", 0}, | 696 | {"tpm_i2c_infineon", 0}, |
697 | {"slb9635tt", 0}, | ||
698 | {"slb9645tt", 1}, | ||
634 | {}, | 699 | {}, |
635 | }; | 700 | }; |
636 | 701 | ||
637 | MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_table); | 702 | MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_table); |
703 | |||
704 | #ifdef CONFIG_OF | ||
705 | static const struct of_device_id tpm_tis_i2c_of_match[] = { | ||
706 | { | ||
707 | .name = "tpm_i2c_infineon", | ||
708 | .type = "tpm", | ||
709 | .compatible = "infineon,tpm_i2c_infineon", | ||
710 | .data = (void *)0 | ||
711 | }, | ||
712 | { | ||
713 | .name = "slb9635tt", | ||
714 | .type = "tpm", | ||
715 | .compatible = "infineon,slb9635tt", | ||
716 | .data = (void *)0 | ||
717 | }, | ||
718 | { | ||
719 | .name = "slb9645tt", | ||
720 | .type = "tpm", | ||
721 | .compatible = "infineon,slb9645tt", | ||
722 | .data = (void *)1 | ||
723 | }, | ||
724 | {}, | ||
725 | }; | ||
726 | MODULE_DEVICE_TABLE(of, tpm_tis_i2c_of_match); | ||
727 | #endif | ||
728 | |||
638 | static SIMPLE_DEV_PM_OPS(tpm_tis_i2c_ops, tpm_pm_suspend, tpm_pm_resume); | 729 | static SIMPLE_DEV_PM_OPS(tpm_tis_i2c_ops, tpm_pm_suspend, tpm_pm_resume); |
639 | 730 | ||
640 | static int tpm_tis_i2c_probe(struct i2c_client *client, | 731 | static int tpm_tis_i2c_probe(struct i2c_client *client, |
641 | const struct i2c_device_id *id) | 732 | const struct i2c_device_id *id) |
642 | { | 733 | { |
643 | int rc; | 734 | int rc; |
644 | if (tpm_dev.client != NULL) | 735 | struct device *dev = &(client->dev); |
736 | |||
737 | if (tpm_dev.client != NULL) { | ||
738 | dev_err(dev, "This driver only supports one client at a time\n"); | ||
645 | return -EBUSY; /* We only support one client */ | 739 | return -EBUSY; /* We only support one client */ |
740 | } | ||
646 | 741 | ||
647 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | 742 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { |
648 | dev_err(&client->dev, | 743 | dev_err(dev, "no algorithms associated to the i2c bus\n"); |
649 | "no algorithms associated to the i2c bus\n"); | ||
650 | return -ENODEV; | 744 | return -ENODEV; |
651 | } | 745 | } |
652 | 746 | ||
@@ -682,7 +776,6 @@ static int tpm_tis_i2c_remove(struct i2c_client *client) | |||
682 | } | 776 | } |
683 | 777 | ||
684 | static struct i2c_driver tpm_tis_i2c_driver = { | 778 | static struct i2c_driver tpm_tis_i2c_driver = { |
685 | |||
686 | .id_table = tpm_tis_i2c_table, | 779 | .id_table = tpm_tis_i2c_table, |
687 | .probe = tpm_tis_i2c_probe, | 780 | .probe = tpm_tis_i2c_probe, |
688 | .remove = tpm_tis_i2c_remove, | 781 | .remove = tpm_tis_i2c_remove, |
@@ -690,11 +783,12 @@ static struct i2c_driver tpm_tis_i2c_driver = { | |||
690 | .name = "tpm_i2c_infineon", | 783 | .name = "tpm_i2c_infineon", |
691 | .owner = THIS_MODULE, | 784 | .owner = THIS_MODULE, |
692 | .pm = &tpm_tis_i2c_ops, | 785 | .pm = &tpm_tis_i2c_ops, |
786 | .of_match_table = of_match_ptr(tpm_tis_i2c_of_match), | ||
693 | }, | 787 | }, |
694 | }; | 788 | }; |
695 | 789 | ||
696 | module_i2c_driver(tpm_tis_i2c_driver); | 790 | module_i2c_driver(tpm_tis_i2c_driver); |
697 | MODULE_AUTHOR("Peter Huewe <peter.huewe@infineon.com>"); | 791 | MODULE_AUTHOR("Peter Huewe <peter.huewe@infineon.com>"); |
698 | MODULE_DESCRIPTION("TPM TIS I2C Infineon Driver"); | 792 | MODULE_DESCRIPTION("TPM TIS I2C Infineon Driver"); |
699 | MODULE_VERSION("2.1.5"); | 793 | MODULE_VERSION("2.2.0"); |
700 | MODULE_LICENSE("GPL"); | 794 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index 1f5f71e14abe..5bb8e2ddd3b3 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/i2c.h> | 36 | #include <linux/i2c.h> |
37 | #include <linux/fs.h> | 37 | #include <linux/fs.h> |
38 | #include <linux/miscdevice.h> | 38 | #include <linux/miscdevice.h> |
39 | #include <linux/module.h> | ||
40 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
41 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
42 | #include <linux/init.h> | 41 | #include <linux/init.h> |
@@ -50,7 +49,6 @@ | |||
50 | #include <linux/uaccess.h> | 49 | #include <linux/uaccess.h> |
51 | #include <linux/io.h> | 50 | #include <linux/io.h> |
52 | #include <linux/slab.h> | 51 | #include <linux/slab.h> |
53 | #include <linux/sched.h> | ||
54 | 52 | ||
55 | #include "tpm.h" | 53 | #include "tpm.h" |
56 | #include "tpm_i2c_stm_st33.h" | 54 | #include "tpm_i2c_stm_st33.h" |
@@ -178,7 +176,7 @@ static long _wait_for_interrupt_serirq_timeout(struct tpm_chip *chip, | |||
178 | struct i2c_client *client; | 176 | struct i2c_client *client; |
179 | struct st33zp24_platform_data *pin_infos; | 177 | struct st33zp24_platform_data *pin_infos; |
180 | 178 | ||
181 | client = (struct i2c_client *) TPM_VPRIV(chip); | 179 | client = (struct i2c_client *)TPM_VPRIV(chip); |
182 | pin_infos = client->dev.platform_data; | 180 | pin_infos = client->dev.platform_data; |
183 | 181 | ||
184 | status = wait_for_completion_interruptible_timeout( | 182 | status = wait_for_completion_interruptible_timeout( |
@@ -197,12 +195,12 @@ static int wait_for_serirq_timeout(struct tpm_chip *chip, bool condition, | |||
197 | int status = 2; | 195 | int status = 2; |
198 | struct i2c_client *client; | 196 | struct i2c_client *client; |
199 | 197 | ||
200 | client = (struct i2c_client *) TPM_VPRIV(chip); | 198 | client = (struct i2c_client *)TPM_VPRIV(chip); |
201 | 199 | ||
202 | status = _wait_for_interrupt_serirq_timeout(chip, timeout); | 200 | status = _wait_for_interrupt_serirq_timeout(chip, timeout); |
203 | if (!status) { | 201 | if (!status) { |
204 | status = -EBUSY; | 202 | status = -EBUSY; |
205 | } else{ | 203 | } else { |
206 | clear_interruption(client); | 204 | clear_interruption(client); |
207 | if (condition) | 205 | if (condition) |
208 | status = 1; | 206 | status = 1; |
@@ -219,7 +217,7 @@ static void tpm_stm_i2c_cancel(struct tpm_chip *chip) | |||
219 | struct i2c_client *client; | 217 | struct i2c_client *client; |
220 | u8 data; | 218 | u8 data; |
221 | 219 | ||
222 | client = (struct i2c_client *) TPM_VPRIV(chip); | 220 | client = (struct i2c_client *)TPM_VPRIV(chip); |
223 | 221 | ||
224 | data = TPM_STS_COMMAND_READY; | 222 | data = TPM_STS_COMMAND_READY; |
225 | I2C_WRITE_DATA(client, TPM_STS, &data, 1); | 223 | I2C_WRITE_DATA(client, TPM_STS, &data, 1); |
@@ -236,7 +234,7 @@ static u8 tpm_stm_i2c_status(struct tpm_chip *chip) | |||
236 | { | 234 | { |
237 | struct i2c_client *client; | 235 | struct i2c_client *client; |
238 | u8 data; | 236 | u8 data; |
239 | client = (struct i2c_client *) TPM_VPRIV(chip); | 237 | client = (struct i2c_client *)TPM_VPRIV(chip); |
240 | 238 | ||
241 | I2C_READ_DATA(client, TPM_STS, &data, 1); | 239 | I2C_READ_DATA(client, TPM_STS, &data, 1); |
242 | return data; | 240 | return data; |
@@ -254,7 +252,7 @@ static int check_locality(struct tpm_chip *chip) | |||
254 | u8 data; | 252 | u8 data; |
255 | u8 status; | 253 | u8 status; |
256 | 254 | ||
257 | client = (struct i2c_client *) TPM_VPRIV(chip); | 255 | client = (struct i2c_client *)TPM_VPRIV(chip); |
258 | 256 | ||
259 | status = I2C_READ_DATA(client, TPM_ACCESS, &data, 1); | 257 | status = I2C_READ_DATA(client, TPM_ACCESS, &data, 1); |
260 | if (status && (data & | 258 | if (status && (data & |
@@ -278,7 +276,7 @@ static int request_locality(struct tpm_chip *chip) | |||
278 | struct i2c_client *client; | 276 | struct i2c_client *client; |
279 | u8 data; | 277 | u8 data; |
280 | 278 | ||
281 | client = (struct i2c_client *) TPM_VPRIV(chip); | 279 | client = (struct i2c_client *)TPM_VPRIV(chip); |
282 | 280 | ||
283 | if (check_locality(chip) == chip->vendor.locality) | 281 | if (check_locality(chip) == chip->vendor.locality) |
284 | return chip->vendor.locality; | 282 | return chip->vendor.locality; |
@@ -294,7 +292,7 @@ static int request_locality(struct tpm_chip *chip) | |||
294 | chip->vendor.timeout_a); | 292 | chip->vendor.timeout_a); |
295 | if (rc > 0) | 293 | if (rc > 0) |
296 | return chip->vendor.locality; | 294 | return chip->vendor.locality; |
297 | } else{ | 295 | } else { |
298 | stop = jiffies + chip->vendor.timeout_a; | 296 | stop = jiffies + chip->vendor.timeout_a; |
299 | do { | 297 | do { |
300 | if (check_locality(chip) >= 0) | 298 | if (check_locality(chip) >= 0) |
@@ -316,7 +314,7 @@ static void release_locality(struct tpm_chip *chip) | |||
316 | struct i2c_client *client; | 314 | struct i2c_client *client; |
317 | u8 data; | 315 | u8 data; |
318 | 316 | ||
319 | client = (struct i2c_client *) TPM_VPRIV(chip); | 317 | client = (struct i2c_client *)TPM_VPRIV(chip); |
320 | data = TPM_ACCESS_ACTIVE_LOCALITY; | 318 | data = TPM_ACCESS_ACTIVE_LOCALITY; |
321 | 319 | ||
322 | I2C_WRITE_DATA(client, TPM_ACCESS, &data, 1); | 320 | I2C_WRITE_DATA(client, TPM_ACCESS, &data, 1); |
@@ -333,7 +331,7 @@ static int get_burstcount(struct tpm_chip *chip) | |||
333 | int burstcnt, status; | 331 | int burstcnt, status; |
334 | u8 tpm_reg, temp; | 332 | u8 tpm_reg, temp; |
335 | 333 | ||
336 | struct i2c_client *client = (struct i2c_client *) TPM_VPRIV(chip); | 334 | struct i2c_client *client = (struct i2c_client *)TPM_VPRIV(chip); |
337 | 335 | ||
338 | stop = jiffies + chip->vendor.timeout_d; | 336 | stop = jiffies + chip->vendor.timeout_d; |
339 | do { | 337 | do { |
@@ -379,7 +377,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, | |||
379 | mask), timeout); | 377 | mask), timeout); |
380 | if (rc > 0) | 378 | if (rc > 0) |
381 | return 0; | 379 | return 0; |
382 | } else{ | 380 | } else { |
383 | stop = jiffies + timeout; | 381 | stop = jiffies + timeout; |
384 | do { | 382 | do { |
385 | msleep(TPM_TIMEOUT); | 383 | msleep(TPM_TIMEOUT); |
@@ -403,7 +401,7 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) | |||
403 | int size = 0, burstcnt, len; | 401 | int size = 0, burstcnt, len; |
404 | struct i2c_client *client; | 402 | struct i2c_client *client; |
405 | 403 | ||
406 | client = (struct i2c_client *) TPM_VPRIV(chip); | 404 | client = (struct i2c_client *)TPM_VPRIV(chip); |
407 | 405 | ||
408 | while (size < count && | 406 | while (size < count && |
409 | wait_for_stat(chip, | 407 | wait_for_stat(chip, |
@@ -433,7 +431,7 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id) | |||
433 | 431 | ||
434 | disable_irq_nosync(irq); | 432 | disable_irq_nosync(irq); |
435 | 433 | ||
436 | client = (struct i2c_client *) TPM_VPRIV(chip); | 434 | client = (struct i2c_client *)TPM_VPRIV(chip); |
437 | pin_infos = client->dev.platform_data; | 435 | pin_infos = client->dev.platform_data; |
438 | 436 | ||
439 | complete(&pin_infos->irq_detection); | 437 | complete(&pin_infos->irq_detection); |
@@ -453,8 +451,7 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id) | |||
453 | static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf, | 451 | static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf, |
454 | size_t len) | 452 | size_t len) |
455 | { | 453 | { |
456 | u32 status, | 454 | u32 status, burstcnt = 0, i, size; |
457 | burstcnt = 0, i, size; | ||
458 | int ret; | 455 | int ret; |
459 | u8 data; | 456 | u8 data; |
460 | struct i2c_client *client; | 457 | struct i2c_client *client; |
@@ -483,7 +480,7 @@ static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf, | |||
483 | } | 480 | } |
484 | } | 481 | } |
485 | 482 | ||
486 | for (i = 0 ; i < len - 1 ;) { | 483 | for (i = 0; i < len - 1;) { |
487 | burstcnt = get_burstcount(chip); | 484 | burstcnt = get_burstcount(chip); |
488 | size = min_t(int, len - i - 1, burstcnt); | 485 | size = min_t(int, len - i - 1, burstcnt); |
489 | ret = I2C_WRITE_DATA(client, TPM_DATA_FIFO, buf, size); | 486 | ret = I2C_WRITE_DATA(client, TPM_DATA_FIFO, buf, size); |
@@ -547,7 +544,7 @@ static int tpm_stm_i2c_recv(struct tpm_chip *chip, unsigned char *buf, | |||
547 | goto out; | 544 | goto out; |
548 | } | 545 | } |
549 | 546 | ||
550 | expected = be32_to_cpu(*(__be32 *) (buf + 2)); | 547 | expected = be32_to_cpu(*(__be32 *)(buf + 2)); |
551 | if (expected > count) { | 548 | if (expected > count) { |
552 | size = -EIO; | 549 | size = -EIO; |
553 | goto out; | 550 | goto out; |
@@ -569,7 +566,7 @@ out: | |||
569 | 566 | ||
570 | static bool tpm_st33_i2c_req_canceled(struct tpm_chip *chip, u8 status) | 567 | static bool tpm_st33_i2c_req_canceled(struct tpm_chip *chip, u8 status) |
571 | { | 568 | { |
572 | return (status == TPM_STS_COMMAND_READY); | 569 | return (status == TPM_STS_COMMAND_READY); |
573 | } | 570 | } |
574 | 571 | ||
575 | static const struct file_operations tpm_st33_i2c_fops = { | 572 | static const struct file_operations tpm_st33_i2c_fops = { |
@@ -617,7 +614,7 @@ static struct tpm_vendor_specific st_i2c_tpm = { | |||
617 | .miscdev = {.fops = &tpm_st33_i2c_fops,}, | 614 | .miscdev = {.fops = &tpm_st33_i2c_fops,}, |
618 | }; | 615 | }; |
619 | 616 | ||
620 | static int interrupts ; | 617 | static int interrupts; |
621 | module_param(interrupts, int, 0444); | 618 | module_param(interrupts, int, 0444); |
622 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); | 619 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); |
623 | 620 | ||
@@ -714,7 +711,7 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
714 | "TPM SERIRQ management", chip); | 711 | "TPM SERIRQ management", chip); |
715 | if (err < 0) { | 712 | if (err < 0) { |
716 | dev_err(chip->dev , "TPM SERIRQ signals %d not available\n", | 713 | dev_err(chip->dev , "TPM SERIRQ signals %d not available\n", |
717 | gpio_to_irq(platform_data->io_serirq)); | 714 | gpio_to_irq(platform_data->io_serirq)); |
718 | goto _irq_set; | 715 | goto _irq_set; |
719 | } | 716 | } |
720 | 717 | ||
@@ -754,7 +751,7 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
754 | dev_info(chip->dev, "TPM I2C Initialized\n"); | 751 | dev_info(chip->dev, "TPM I2C Initialized\n"); |
755 | return 0; | 752 | return 0; |
756 | _irq_set: | 753 | _irq_set: |
757 | free_irq(gpio_to_irq(platform_data->io_serirq), (void *) chip); | 754 | free_irq(gpio_to_irq(platform_data->io_serirq), (void *)chip); |
758 | _gpio_init2: | 755 | _gpio_init2: |
759 | if (interrupts) | 756 | if (interrupts) |
760 | gpio_free(platform_data->io_serirq); | 757 | gpio_free(platform_data->io_serirq); |
@@ -784,7 +781,7 @@ static int tpm_st33_i2c_remove(struct i2c_client *client) | |||
784 | { | 781 | { |
785 | struct tpm_chip *chip = (struct tpm_chip *)i2c_get_clientdata(client); | 782 | struct tpm_chip *chip = (struct tpm_chip *)i2c_get_clientdata(client); |
786 | struct st33zp24_platform_data *pin_infos = | 783 | struct st33zp24_platform_data *pin_infos = |
787 | ((struct i2c_client *) TPM_VPRIV(chip))->dev.platform_data; | 784 | ((struct i2c_client *)TPM_VPRIV(chip))->dev.platform_data; |
788 | 785 | ||
789 | if (pin_infos != NULL) { | 786 | if (pin_infos != NULL) { |
790 | free_irq(pin_infos->io_serirq, chip); | 787 | free_irq(pin_infos->io_serirq, chip); |
@@ -823,9 +820,9 @@ static int tpm_st33_i2c_pm_suspend(struct device *dev) | |||
823 | struct st33zp24_platform_data *pin_infos = dev->platform_data; | 820 | struct st33zp24_platform_data *pin_infos = dev->platform_data; |
824 | int ret = 0; | 821 | int ret = 0; |
825 | 822 | ||
826 | if (power_mgt) | 823 | if (power_mgt) { |
827 | gpio_set_value(pin_infos->io_lpcpd, 0); | 824 | gpio_set_value(pin_infos->io_lpcpd, 0); |
828 | else{ | 825 | } else { |
829 | if (chip->data_buffer == NULL) | 826 | if (chip->data_buffer == NULL) |
830 | chip->data_buffer = pin_infos->tpm_i2c_buffer[0]; | 827 | chip->data_buffer = pin_infos->tpm_i2c_buffer[0]; |
831 | ret = tpm_pm_suspend(dev); | 828 | ret = tpm_pm_suspend(dev); |
@@ -851,12 +848,12 @@ static int tpm_st33_i2c_pm_resume(struct device *dev) | |||
851 | (chip->vendor.status(chip) & | 848 | (chip->vendor.status(chip) & |
852 | TPM_STS_VALID) == TPM_STS_VALID, | 849 | TPM_STS_VALID) == TPM_STS_VALID, |
853 | chip->vendor.timeout_b); | 850 | chip->vendor.timeout_b); |
854 | } else{ | 851 | } else { |
855 | if (chip->data_buffer == NULL) | 852 | if (chip->data_buffer == NULL) |
856 | chip->data_buffer = pin_infos->tpm_i2c_buffer[0]; | 853 | chip->data_buffer = pin_infos->tpm_i2c_buffer[0]; |
857 | ret = tpm_pm_resume(dev); | 854 | ret = tpm_pm_resume(dev); |
858 | if (!ret) | 855 | if (!ret) |
859 | tpm_do_selftest(chip); | 856 | tpm_do_selftest(chip); |
860 | } | 857 | } |
861 | return ret; | 858 | return ret; |
862 | } /* tpm_st33_i2c_pm_resume() */ | 859 | } /* tpm_st33_i2c_pm_resume() */ |
@@ -867,7 +864,8 @@ static const struct i2c_device_id tpm_st33_i2c_id[] = { | |||
867 | {} | 864 | {} |
868 | }; | 865 | }; |
869 | MODULE_DEVICE_TABLE(i2c, tpm_st33_i2c_id); | 866 | MODULE_DEVICE_TABLE(i2c, tpm_st33_i2c_id); |
870 | static SIMPLE_DEV_PM_OPS(tpm_st33_i2c_ops, tpm_st33_i2c_pm_suspend, tpm_st33_i2c_pm_resume); | 867 | static SIMPLE_DEV_PM_OPS(tpm_st33_i2c_ops, tpm_st33_i2c_pm_suspend, |
868 | tpm_st33_i2c_pm_resume); | ||
871 | static struct i2c_driver tpm_st33_i2c_driver = { | 869 | static struct i2c_driver tpm_st33_i2c_driver = { |
872 | .driver = { | 870 | .driver = { |
873 | .owner = THIS_MODULE, | 871 | .owner = THIS_MODULE, |
diff --git a/drivers/char/tpm/tpm_ppi.c b/drivers/char/tpm/tpm_ppi.c index 720ebcf29fdf..2168d15bc728 100644 --- a/drivers/char/tpm/tpm_ppi.c +++ b/drivers/char/tpm/tpm_ppi.c | |||
@@ -158,9 +158,9 @@ static ssize_t tpm_store_ppi_request(struct device *dev, | |||
158 | ACPI_TYPE_STRING); | 158 | ACPI_TYPE_STRING); |
159 | if (ACPI_FAILURE(status)) | 159 | if (ACPI_FAILURE(status)) |
160 | return -ENOMEM; | 160 | return -ENOMEM; |
161 | strncpy(version, | 161 | strlcpy(version, |
162 | ((union acpi_object *)output.pointer)->string.pointer, | 162 | ((union acpi_object *)output.pointer)->string.pointer, |
163 | PPI_VERSION_LEN); | 163 | PPI_VERSION_LEN + 1); |
164 | kfree(output.pointer); | 164 | kfree(output.pointer); |
165 | output.length = ACPI_ALLOCATE_BUFFER; | 165 | output.length = ACPI_ALLOCATE_BUFFER; |
166 | output.pointer = NULL; | 166 | output.pointer = NULL; |
@@ -237,9 +237,9 @@ static ssize_t tpm_show_ppi_transition_action(struct device *dev, | |||
237 | ACPI_TYPE_STRING); | 237 | ACPI_TYPE_STRING); |
238 | if (ACPI_FAILURE(status)) | 238 | if (ACPI_FAILURE(status)) |
239 | return -ENOMEM; | 239 | return -ENOMEM; |
240 | strncpy(version, | 240 | strlcpy(version, |
241 | ((union acpi_object *)output.pointer)->string.pointer, | 241 | ((union acpi_object *)output.pointer)->string.pointer, |
242 | PPI_VERSION_LEN); | 242 | PPI_VERSION_LEN + 1); |
243 | /* | 243 | /* |
244 | * PPI spec defines params[3].type as empty package, but some platforms | 244 | * PPI spec defines params[3].type as empty package, but some platforms |
245 | * (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for | 245 | * (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for |
@@ -351,7 +351,7 @@ cleanup: | |||
351 | static ssize_t show_ppi_operations(char *buf, u32 start, u32 end) | 351 | static ssize_t show_ppi_operations(char *buf, u32 start, u32 end) |
352 | { | 352 | { |
353 | char *str = buf; | 353 | char *str = buf; |
354 | char version[PPI_VERSION_LEN]; | 354 | char version[PPI_VERSION_LEN + 1]; |
355 | acpi_handle handle; | 355 | acpi_handle handle; |
356 | acpi_status status; | 356 | acpi_status status; |
357 | struct acpi_object_list input; | 357 | struct acpi_object_list input; |
@@ -381,9 +381,9 @@ static ssize_t show_ppi_operations(char *buf, u32 start, u32 end) | |||
381 | if (ACPI_FAILURE(status)) | 381 | if (ACPI_FAILURE(status)) |
382 | return -ENOMEM; | 382 | return -ENOMEM; |
383 | 383 | ||
384 | strncpy(version, | 384 | strlcpy(version, |
385 | ((union acpi_object *)output.pointer)->string.pointer, | 385 | ((union acpi_object *)output.pointer)->string.pointer, |
386 | PPI_VERSION_LEN); | 386 | PPI_VERSION_LEN + 1); |
387 | kfree(output.pointer); | 387 | kfree(output.pointer); |
388 | output.length = ACPI_ALLOCATE_BUFFER; | 388 | output.length = ACPI_ALLOCATE_BUFFER; |
389 | output.pointer = NULL; | 389 | output.pointer = NULL; |