st33zp24.c (af782f339a5d6ea202652c9f06880e1a28c43813) | st33zp24.c (9e0d39d8a6a0a8805d05fba22e3fbe80b5c8c4cb) |
---|---|
1/* 2 * STMicroelectronics TPM Linux driver for TPM ST33ZP24 3 * Copyright (C) 2009 - 2016 STMicroelectronics 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. --- 80 unchanged lines hidden (view full) --- 89 90/* 91 * st33zp24_cancel, cancel the current command execution or 92 * set STS to COMMAND READY. 93 * @param: chip, the tpm_chip description as specified in driver/char/tpm/tpm.h 94 */ 95static void st33zp24_cancel(struct tpm_chip *chip) 96{ | 1/* 2 * STMicroelectronics TPM Linux driver for TPM ST33ZP24 3 * Copyright (C) 2009 - 2016 STMicroelectronics 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. --- 80 unchanged lines hidden (view full) --- 89 90/* 91 * st33zp24_cancel, cancel the current command execution or 92 * set STS to COMMAND READY. 93 * @param: chip, the tpm_chip description as specified in driver/char/tpm/tpm.h 94 */ 95static void st33zp24_cancel(struct tpm_chip *chip) 96{ |
97 struct st33zp24_dev *tpm_dev; | 97 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); |
98 u8 data; 99 | 98 u8 data; 99 |
100 tpm_dev = (struct st33zp24_dev *)TPM_VPRIV(chip); 101 | |
102 data = TPM_STS_COMMAND_READY; 103 tpm_dev->ops->send(tpm_dev->phy_id, TPM_STS, &data, 1); 104} /* st33zp24_cancel() */ 105 106/* 107 * st33zp24_status return the TPM_STS register 108 * @param: chip, the tpm chip description 109 * @return: the TPM_STS register value. 110 */ 111static u8 st33zp24_status(struct tpm_chip *chip) 112{ | 100 data = TPM_STS_COMMAND_READY; 101 tpm_dev->ops->send(tpm_dev->phy_id, TPM_STS, &data, 1); 102} /* st33zp24_cancel() */ 103 104/* 105 * st33zp24_status return the TPM_STS register 106 * @param: chip, the tpm chip description 107 * @return: the TPM_STS register value. 108 */ 109static u8 st33zp24_status(struct tpm_chip *chip) 110{ |
113 struct st33zp24_dev *tpm_dev; | 111 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); |
114 u8 data; 115 | 112 u8 data; 113 |
116 tpm_dev = (struct st33zp24_dev *)TPM_VPRIV(chip); 117 | |
118 tpm_dev->ops->recv(tpm_dev->phy_id, TPM_STS, &data, 1); 119 return data; 120} /* st33zp24_status() */ 121 122/* 123 * check_locality if the locality is active 124 * @param: chip, the tpm chip description 125 * @return: the active locality or -EACCESS. 126 */ 127static int check_locality(struct tpm_chip *chip) 128{ | 114 tpm_dev->ops->recv(tpm_dev->phy_id, TPM_STS, &data, 1); 115 return data; 116} /* st33zp24_status() */ 117 118/* 119 * check_locality if the locality is active 120 * @param: chip, the tpm chip description 121 * @return: the active locality or -EACCESS. 122 */ 123static int check_locality(struct tpm_chip *chip) 124{ |
129 struct st33zp24_dev *tpm_dev; | 125 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); |
130 u8 data; 131 u8 status; 132 | 126 u8 data; 127 u8 status; 128 |
133 tpm_dev = (struct st33zp24_dev *)TPM_VPRIV(chip); 134 | |
135 status = tpm_dev->ops->recv(tpm_dev->phy_id, TPM_ACCESS, &data, 1); 136 if (status && (data & 137 (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) == 138 (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) 139 return tpm_dev->locality; 140 141 return -EACCES; 142} /* check_locality() */ 143 144/* 145 * request_locality request the TPM locality 146 * @param: chip, the chip description 147 * @return: the active locality or negative value. 148 */ 149static int request_locality(struct tpm_chip *chip) 150{ | 129 status = tpm_dev->ops->recv(tpm_dev->phy_id, TPM_ACCESS, &data, 1); 130 if (status && (data & 131 (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) == 132 (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) 133 return tpm_dev->locality; 134 135 return -EACCES; 136} /* check_locality() */ 137 138/* 139 * request_locality request the TPM locality 140 * @param: chip, the chip description 141 * @return: the active locality or negative value. 142 */ 143static int request_locality(struct tpm_chip *chip) 144{ |
145 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); |
|
151 unsigned long stop; 152 long ret; | 146 unsigned long stop; 147 long ret; |
153 struct st33zp24_dev *tpm_dev; | |
154 u8 data; 155 | 148 u8 data; 149 |
156 tpm_dev = (struct st33zp24_dev *)TPM_VPRIV(chip); 157 | |
158 if (check_locality(chip) == tpm_dev->locality) 159 return tpm_dev->locality; 160 161 data = TPM_ACCESS_REQUEST_USE; 162 ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_ACCESS, &data, 1); 163 if (ret < 0) 164 return ret; 165 --- 11 unchanged lines hidden (view full) --- 177} /* request_locality() */ 178 179/* 180 * release_locality release the active locality 181 * @param: chip, the tpm chip description. 182 */ 183static void release_locality(struct tpm_chip *chip) 184{ | 150 if (check_locality(chip) == tpm_dev->locality) 151 return tpm_dev->locality; 152 153 data = TPM_ACCESS_REQUEST_USE; 154 ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_ACCESS, &data, 1); 155 if (ret < 0) 156 return ret; 157 --- 11 unchanged lines hidden (view full) --- 169} /* request_locality() */ 170 171/* 172 * release_locality release the active locality 173 * @param: chip, the tpm chip description. 174 */ 175static void release_locality(struct tpm_chip *chip) 176{ |
185 struct st33zp24_dev *tpm_dev; | 177 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); |
186 u8 data; 187 | 178 u8 data; 179 |
188 tpm_dev = (struct st33zp24_dev *)TPM_VPRIV(chip); | |
189 data = TPM_ACCESS_ACTIVE_LOCALITY; 190 191 tpm_dev->ops->send(tpm_dev->phy_id, TPM_ACCESS, &data, 1); 192} 193 194/* 195 * get_burstcount return the burstcount value 196 * @param: chip, the chip description 197 * return: the burstcount or negative value. 198 */ 199static int get_burstcount(struct tpm_chip *chip) 200{ | 180 data = TPM_ACCESS_ACTIVE_LOCALITY; 181 182 tpm_dev->ops->send(tpm_dev->phy_id, TPM_ACCESS, &data, 1); 183} 184 185/* 186 * get_burstcount return the burstcount value 187 * @param: chip, the chip description 188 * return: the burstcount or negative value. 189 */ 190static int get_burstcount(struct tpm_chip *chip) 191{ |
192 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); |
|
201 unsigned long stop; 202 int burstcnt, status; 203 u8 temp; | 193 unsigned long stop; 194 int burstcnt, status; 195 u8 temp; |
204 struct st33zp24_dev *tpm_dev; | |
205 | 196 |
206 tpm_dev = (struct st33zp24_dev *)TPM_VPRIV(chip); 207 | |
208 stop = jiffies + chip->timeout_d; 209 do { 210 status = tpm_dev->ops->recv(tpm_dev->phy_id, TPM_STS + 1, 211 &temp, 1); 212 if (status < 0) 213 return -EBUSY; 214 215 burstcnt = temp; --- 42 unchanged lines hidden (view full) --- 258 * @param: timeout, the timeout 259 * @param: queue, the wait queue. 260 * @param: check_cancel, does the command can be cancelled ? 261 * @return: the tpm status, 0 if success, -ETIME if timeout is reached. 262 */ 263static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, 264 wait_queue_head_t *queue, bool check_cancel) 265{ | 197 stop = jiffies + chip->timeout_d; 198 do { 199 status = tpm_dev->ops->recv(tpm_dev->phy_id, TPM_STS + 1, 200 &temp, 1); 201 if (status < 0) 202 return -EBUSY; 203 204 burstcnt = temp; --- 42 unchanged lines hidden (view full) --- 247 * @param: timeout, the timeout 248 * @param: queue, the wait queue. 249 * @param: check_cancel, does the command can be cancelled ? 250 * @return: the tpm status, 0 if success, -ETIME if timeout is reached. 251 */ 252static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, 253 wait_queue_head_t *queue, bool check_cancel) 254{ |
255 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); |
|
266 unsigned long stop; 267 int ret = 0; 268 bool canceled = false; 269 bool condition; 270 u32 cur_intrs; 271 u8 status; | 256 unsigned long stop; 257 int ret = 0; 258 bool canceled = false; 259 bool condition; 260 u32 cur_intrs; 261 u8 status; |
272 struct st33zp24_dev *tpm_dev; | |
273 | 262 |
274 tpm_dev = (struct st33zp24_dev *)TPM_VPRIV(chip); 275 | |
276 /* check current status */ 277 status = st33zp24_status(chip); 278 if ((status & mask) == mask) 279 return 0; 280 281 stop = jiffies + timeout; 282 283 if (chip->flags & TPM_CHIP_FLAG_IRQ) { --- 40 unchanged lines hidden (view full) --- 324 * recv_data receive data 325 * @param: chip, the tpm chip description 326 * @param: buf, the buffer where the data are received 327 * @param: count, the number of data to receive 328 * @return: the number of bytes read from TPM FIFO. 329 */ 330static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) 331{ | 263 /* check current status */ 264 status = st33zp24_status(chip); 265 if ((status & mask) == mask) 266 return 0; 267 268 stop = jiffies + timeout; 269 270 if (chip->flags & TPM_CHIP_FLAG_IRQ) { --- 40 unchanged lines hidden (view full) --- 311 * recv_data receive data 312 * @param: chip, the tpm chip description 313 * @param: buf, the buffer where the data are received 314 * @param: count, the number of data to receive 315 * @return: the number of bytes read from TPM FIFO. 316 */ 317static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) 318{ |
319 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); |
|
332 int size = 0, burstcnt, len, ret; | 320 int size = 0, burstcnt, len, ret; |
333 struct st33zp24_dev *tpm_dev; | |
334 | 321 |
335 tpm_dev = (struct st33zp24_dev *)TPM_VPRIV(chip); 336 | |
337 while (size < count && 338 wait_for_stat(chip, 339 TPM_STS_DATA_AVAIL | TPM_STS_VALID, 340 chip->timeout_c, 341 &tpm_dev->read_queue, true) == 0) { 342 burstcnt = get_burstcount(chip); 343 if (burstcnt < 0) 344 return burstcnt; --- 12 unchanged lines hidden (view full) --- 357 * tpm_ioserirq_handler the serirq irq handler 358 * @param: irq, the tpm chip description 359 * @param: dev_id, the description of the chip 360 * @return: the status of the handler. 361 */ 362static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id) 363{ 364 struct tpm_chip *chip = dev_id; | 322 while (size < count && 323 wait_for_stat(chip, 324 TPM_STS_DATA_AVAIL | TPM_STS_VALID, 325 chip->timeout_c, 326 &tpm_dev->read_queue, true) == 0) { 327 burstcnt = get_burstcount(chip); 328 if (burstcnt < 0) 329 return burstcnt; --- 12 unchanged lines hidden (view full) --- 342 * tpm_ioserirq_handler the serirq irq handler 343 * @param: irq, the tpm chip description 344 * @param: dev_id, the description of the chip 345 * @return: the status of the handler. 346 */ 347static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id) 348{ 349 struct tpm_chip *chip = dev_id; |
365 struct st33zp24_dev *tpm_dev; | 350 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); |
366 | 351 |
367 tpm_dev = (struct st33zp24_dev *)TPM_VPRIV(chip); 368 | |
369 tpm_dev->intrs++; 370 wake_up_interruptible(&tpm_dev->read_queue); 371 disable_irq_nosync(tpm_dev->irq); 372 373 return IRQ_HANDLED; 374} /* tpm_ioserirq_handler() */ 375 376/* 377 * st33zp24_send send TPM commands through the I2C bus. 378 * 379 * @param: chip, the tpm_chip description as specified in driver/char/tpm/tpm.h 380 * @param: buf, the buffer to send. 381 * @param: count, the number of bytes to send. 382 * @return: In case of success the number of bytes sent. 383 * In other case, a < 0 value describing the issue. 384 */ 385static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, 386 size_t len) 387{ | 352 tpm_dev->intrs++; 353 wake_up_interruptible(&tpm_dev->read_queue); 354 disable_irq_nosync(tpm_dev->irq); 355 356 return IRQ_HANDLED; 357} /* tpm_ioserirq_handler() */ 358 359/* 360 * st33zp24_send send TPM commands through the I2C bus. 361 * 362 * @param: chip, the tpm_chip description as specified in driver/char/tpm/tpm.h 363 * @param: buf, the buffer to send. 364 * @param: count, the number of bytes to send. 365 * @return: In case of success the number of bytes sent. 366 * In other case, a < 0 value describing the issue. 367 */ 368static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, 369 size_t len) 370{ |
371 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); |
|
388 u32 status, i, size, ordinal; 389 int burstcnt = 0; 390 int ret; 391 u8 data; | 372 u32 status, i, size, ordinal; 373 int burstcnt = 0; 374 int ret; 375 u8 data; |
392 struct st33zp24_dev *tpm_dev; | |
393 394 if (!chip) 395 return -EBUSY; 396 if (len < TPM_HEADER_SIZE) 397 return -EBUSY; 398 | 376 377 if (!chip) 378 return -EBUSY; 379 if (len < TPM_HEADER_SIZE) 380 return -EBUSY; 381 |
399 tpm_dev = (struct st33zp24_dev *)TPM_VPRIV(chip); 400 | |
401 ret = request_locality(chip); 402 if (ret < 0) 403 return ret; 404 405 status = st33zp24_status(chip); 406 if ((status & TPM_STS_COMMAND_READY) == 0) { 407 st33zp24_cancel(chip); 408 if (wait_for_stat --- 143 unchanged lines hidden (view full) --- 552 if (IS_ERR(chip)) 553 return PTR_ERR(chip); 554 555 tpm_dev = devm_kzalloc(dev, sizeof(struct st33zp24_dev), 556 GFP_KERNEL); 557 if (!tpm_dev) 558 return -ENOMEM; 559 | 382 ret = request_locality(chip); 383 if (ret < 0) 384 return ret; 385 386 status = st33zp24_status(chip); 387 if ((status & TPM_STS_COMMAND_READY) == 0) { 388 st33zp24_cancel(chip); 389 if (wait_for_stat --- 143 unchanged lines hidden (view full) --- 533 if (IS_ERR(chip)) 534 return PTR_ERR(chip); 535 536 tpm_dev = devm_kzalloc(dev, sizeof(struct st33zp24_dev), 537 GFP_KERNEL); 538 if (!tpm_dev) 539 return -ENOMEM; 540 |
560 TPM_VPRIV(chip) = tpm_dev; | |
561 tpm_dev->phy_id = phy_id; 562 tpm_dev->ops = ops; | 541 tpm_dev->phy_id = phy_id; 542 tpm_dev->ops = ops; |
543 dev_set_drvdata(&chip->dev, tpm_dev); |
|
563 564 chip->timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT); 565 chip->timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT); 566 chip->timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT); 567 chip->timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); 568 569 tpm_dev->locality = LOCALITY0; 570 --- 67 unchanged lines hidden (view full) --- 638 * st33zp24_pm_suspend suspend the TPM device 639 * @param: tpm_data, the tpm phy. 640 * @param: mesg, the power management message. 641 * @return: 0 in case of success. 642 */ 643int st33zp24_pm_suspend(struct device *dev) 644{ 645 struct tpm_chip *chip = dev_get_drvdata(dev); | 544 545 chip->timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT); 546 chip->timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT); 547 chip->timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT); 548 chip->timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); 549 550 tpm_dev->locality = LOCALITY0; 551 --- 67 unchanged lines hidden (view full) --- 619 * st33zp24_pm_suspend suspend the TPM device 620 * @param: tpm_data, the tpm phy. 621 * @param: mesg, the power management message. 622 * @return: 0 in case of success. 623 */ 624int st33zp24_pm_suspend(struct device *dev) 625{ 626 struct tpm_chip *chip = dev_get_drvdata(dev); |
646 struct st33zp24_dev *tpm_dev; | 627 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); 628 |
647 int ret = 0; 648 | 629 int ret = 0; 630 |
649 tpm_dev = (struct st33zp24_dev *)TPM_VPRIV(chip); 650 | |
651 if (gpio_is_valid(tpm_dev->io_lpcpd)) 652 gpio_set_value(tpm_dev->io_lpcpd, 0); 653 else 654 ret = tpm_pm_suspend(dev); 655 656 return ret; 657} /* st33zp24_pm_suspend() */ 658EXPORT_SYMBOL(st33zp24_pm_suspend); 659 660/* 661 * st33zp24_pm_resume resume the TPM device 662 * @param: tpm_data, the tpm phy. 663 * @return: 0 in case of success. 664 */ 665int st33zp24_pm_resume(struct device *dev) 666{ 667 struct tpm_chip *chip = dev_get_drvdata(dev); | 631 if (gpio_is_valid(tpm_dev->io_lpcpd)) 632 gpio_set_value(tpm_dev->io_lpcpd, 0); 633 else 634 ret = tpm_pm_suspend(dev); 635 636 return ret; 637} /* st33zp24_pm_suspend() */ 638EXPORT_SYMBOL(st33zp24_pm_suspend); 639 640/* 641 * st33zp24_pm_resume resume the TPM device 642 * @param: tpm_data, the tpm phy. 643 * @return: 0 in case of success. 644 */ 645int st33zp24_pm_resume(struct device *dev) 646{ 647 struct tpm_chip *chip = dev_get_drvdata(dev); |
668 struct st33zp24_dev *tpm_dev; | 648 struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev); |
669 int ret = 0; 670 | 649 int ret = 0; 650 |
671 tpm_dev = (struct st33zp24_dev *)TPM_VPRIV(chip); 672 | |
673 if (gpio_is_valid(tpm_dev->io_lpcpd)) { 674 gpio_set_value(tpm_dev->io_lpcpd, 1); 675 ret = wait_for_stat(chip, 676 TPM_STS_VALID, chip->timeout_b, 677 &tpm_dev->read_queue, false); 678 } else { 679 ret = tpm_pm_resume(dev); 680 if (!ret) 681 tpm_do_selftest(chip); 682 } 683 return ret; 684} /* st33zp24_pm_resume() */ 685EXPORT_SYMBOL(st33zp24_pm_resume); 686#endif 687 688MODULE_AUTHOR("TPM support (TPMsupport@list.st.com)"); 689MODULE_DESCRIPTION("ST33ZP24 TPM 1.2 driver"); 690MODULE_VERSION("1.3.0"); 691MODULE_LICENSE("GPL"); | 651 if (gpio_is_valid(tpm_dev->io_lpcpd)) { 652 gpio_set_value(tpm_dev->io_lpcpd, 1); 653 ret = wait_for_stat(chip, 654 TPM_STS_VALID, chip->timeout_b, 655 &tpm_dev->read_queue, false); 656 } else { 657 ret = tpm_pm_resume(dev); 658 if (!ret) 659 tpm_do_selftest(chip); 660 } 661 return ret; 662} /* st33zp24_pm_resume() */ 663EXPORT_SYMBOL(st33zp24_pm_resume); 664#endif 665 666MODULE_AUTHOR("TPM support (TPMsupport@list.st.com)"); 667MODULE_DESCRIPTION("ST33ZP24 TPM 1.2 driver"); 668MODULE_VERSION("1.3.0"); 669MODULE_LICENSE("GPL"); |