aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorMichael Albaugh <Michael.Albaugh@qlogic.com>2008-04-17 00:09:27 -0400
committerRoland Dreier <rolandd@cisco.com>2008-04-17 00:09:27 -0400
commitd84e0b28d3a0b41fc574ea50d60522ae0fba75f4 (patch)
tree25244e8c9e8d0cd3e3475c9bc02cc44c24135dcf /drivers/infiniband
parentd98b1937768c9f4e4420bd25406e5f0304d224bb (diff)
IB/ipath: EEPROM support for 7220 devices, robustness improvements, cleanup
Add support for reading newer card's EEPROMs while continuing to support older EEPROMs. Also, add support for the temperature sensor if present. Signed-off-by: Michael Albaugh <Michael.Albaugh@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_eeprom.c426
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h7
-rw-r--r--drivers/infiniband/hw/ipath/ipath_sysfs.c73
3 files changed, 439 insertions, 67 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_eeprom.c b/drivers/infiniband/hw/ipath/ipath_eeprom.c
index e28a42f53769..72f90e8d5f76 100644
--- a/drivers/infiniband/hw/ipath/ipath_eeprom.c
+++ b/drivers/infiniband/hw/ipath/ipath_eeprom.c
@@ -62,6 +62,33 @@
62 * accessing eeprom contents from within the kernel, only via sysfs. 62 * accessing eeprom contents from within the kernel, only via sysfs.
63 */ 63 */
64 64
65/* Added functionality for IBA7220-based cards */
66#define IPATH_EEPROM_DEV_V1 0xA0
67#define IPATH_EEPROM_DEV_V2 0xA2
68#define IPATH_TEMP_DEV 0x98
69#define IPATH_BAD_DEV (IPATH_EEPROM_DEV_V2+2)
70#define IPATH_NO_DEV (0xFF)
71
72/*
73 * The number of I2C chains is proliferating. Table below brings
74 * some order to the madness. The basic principle is that the
75 * table is scanned from the top, and a "probe" is made to the
76 * device probe_dev. If that succeeds, the chain is considered
77 * to be of that type, and dd->i2c_chain_type is set to the index+1
78 * of the entry.
79 * The +1 is so static initialization can mean "unknown, do probe."
80 */
81static struct i2c_chain_desc {
82 u8 probe_dev; /* If seen at probe, chain is this type */
83 u8 eeprom_dev; /* Dev addr (if any) for EEPROM */
84 u8 temp_dev; /* Dev Addr (if any) for Temp-sense */
85} i2c_chains[] = {
86 { IPATH_BAD_DEV, IPATH_NO_DEV, IPATH_NO_DEV }, /* pre-iba7220 bds */
87 { IPATH_EEPROM_DEV_V1, IPATH_EEPROM_DEV_V1, IPATH_TEMP_DEV}, /* V1 */
88 { IPATH_EEPROM_DEV_V2, IPATH_EEPROM_DEV_V2, IPATH_TEMP_DEV}, /* V2 */
89 { IPATH_NO_DEV }
90};
91
65enum i2c_type { 92enum i2c_type {
66 i2c_line_scl = 0, 93 i2c_line_scl = 0,
67 i2c_line_sda 94 i2c_line_sda
@@ -75,13 +102,6 @@ enum i2c_state {
75#define READ_CMD 1 102#define READ_CMD 1
76#define WRITE_CMD 0 103#define WRITE_CMD 0
77 104
78static int eeprom_init;
79
80/*
81 * The gpioval manipulation really should be protected by spinlocks
82 * or be converted to use atomic operations.
83 */
84
85/** 105/**
86 * i2c_gpio_set - set a GPIO line 106 * i2c_gpio_set - set a GPIO line
87 * @dd: the infinipath device 107 * @dd: the infinipath device
@@ -241,6 +261,27 @@ static int i2c_ackrcv(struct ipath_devdata *dd)
241} 261}
242 262
243/** 263/**
264 * rd_byte - read a byte, leaving ACK, STOP, etc up to caller
265 * @dd: the infinipath device
266 *
267 * Returns byte shifted out of device
268 */
269static int rd_byte(struct ipath_devdata *dd)
270{
271 int bit_cntr, data;
272
273 data = 0;
274
275 for (bit_cntr = 7; bit_cntr >= 0; --bit_cntr) {
276 data <<= 1;
277 scl_out(dd, i2c_line_high);
278 data |= sda_in(dd, 0);
279 scl_out(dd, i2c_line_low);
280 }
281 return data;
282}
283
284/**
244 * wr_byte - write a byte, one bit at a time 285 * wr_byte - write a byte, one bit at a time
245 * @dd: the infinipath device 286 * @dd: the infinipath device
246 * @data: the byte to write 287 * @data: the byte to write
@@ -331,7 +372,6 @@ static int eeprom_reset(struct ipath_devdata *dd)
331 ipath_cdbg(VERBOSE, "Resetting i2c eeprom; initial gpioout reg " 372 ipath_cdbg(VERBOSE, "Resetting i2c eeprom; initial gpioout reg "
332 "is %llx\n", (unsigned long long) *gpioval); 373 "is %llx\n", (unsigned long long) *gpioval);
333 374
334 eeprom_init = 1;
335 /* 375 /*
336 * This is to get the i2c into a known state, by first going low, 376 * This is to get the i2c into a known state, by first going low,
337 * then tristate sda (and then tristate scl as first thing 377 * then tristate sda (and then tristate scl as first thing
@@ -340,12 +380,17 @@ static int eeprom_reset(struct ipath_devdata *dd)
340 scl_out(dd, i2c_line_low); 380 scl_out(dd, i2c_line_low);
341 sda_out(dd, i2c_line_high); 381 sda_out(dd, i2c_line_high);
342 382
383 /* Clock up to 9 cycles looking for SDA hi, then issue START and STOP */
343 while (clock_cycles_left--) { 384 while (clock_cycles_left--) {
344 scl_out(dd, i2c_line_high); 385 scl_out(dd, i2c_line_high);
345 386
387 /* SDA seen high, issue START by dropping it while SCL high */
346 if (sda_in(dd, 0)) { 388 if (sda_in(dd, 0)) {
347 sda_out(dd, i2c_line_low); 389 sda_out(dd, i2c_line_low);
348 scl_out(dd, i2c_line_low); 390 scl_out(dd, i2c_line_low);
391 /* ATMEL spec says must be followed by STOP. */
392 scl_out(dd, i2c_line_high);
393 sda_out(dd, i2c_line_high);
349 ret = 0; 394 ret = 0;
350 goto bail; 395 goto bail;
351 } 396 }
@@ -359,29 +404,121 @@ bail:
359 return ret; 404 return ret;
360} 405}
361 406
362/** 407/*
363 * ipath_eeprom_read - receives bytes from the eeprom via I2C 408 * Probe for I2C device at specified address. Returns 0 for "success"
364 * @dd: the infinipath device 409 * to match rest of this file.
365 * @eeprom_offset: address to read from 410 * Leave bus in "reasonable" state for further commands.
366 * @buffer: where to store result
367 * @len: number of bytes to receive
368 */ 411 */
412static int i2c_probe(struct ipath_devdata *dd, int devaddr)
413{
414 int ret = 0;
415
416 ret = eeprom_reset(dd);
417 if (ret) {
418 ipath_dev_err(dd, "Failed reset probing device 0x%02X\n",
419 devaddr);
420 return ret;
421 }
422 /*
423 * Reset no longer leaves bus in start condition, so normal
424 * i2c_startcmd() will do.
425 */
426 ret = i2c_startcmd(dd, devaddr | READ_CMD);
427 if (ret)
428 ipath_cdbg(VERBOSE, "Failed startcmd for device 0x%02X\n",
429 devaddr);
430 else {
431 /*
432 * Device did respond. Complete a single-byte read, because some
433 * devices apparently cannot handle STOP immediately after they
434 * ACK the start-cmd.
435 */
436 int data;
437 data = rd_byte(dd);
438 stop_cmd(dd);
439 ipath_cdbg(VERBOSE, "Response from device 0x%02X\n", devaddr);
440 }
441 return ret;
442}
443
444/*
445 * Returns the "i2c type". This is a pointer to a struct that describes
446 * the I2C chain on this board. To minimize impact on struct ipath_devdata,
447 * the (small integer) index into the table is actually memoized, rather
448 * then the pointer.
449 * Memoization is because the type is determined on the first call per chip.
450 * An alternative would be to move type determination to early
451 * init code.
452 */
453static struct i2c_chain_desc *ipath_i2c_type(struct ipath_devdata *dd)
454{
455 int idx;
456
457 /* Get memoized index, from previous successful probes */
458 idx = dd->ipath_i2c_chain_type - 1;
459 if (idx >= 0 && idx < (ARRAY_SIZE(i2c_chains) - 1))
460 goto done;
461
462 idx = 0;
463 while (i2c_chains[idx].probe_dev != IPATH_NO_DEV) {
464 /* if probe succeeds, this is type */
465 if (!i2c_probe(dd, i2c_chains[idx].probe_dev))
466 break;
467 ++idx;
468 }
469
470 /*
471 * Old EEPROM (first entry) may require a reset after probe,
472 * rather than being able to "start" after "stop"
473 */
474 if (idx == 0)
475 eeprom_reset(dd);
476
477 if (i2c_chains[idx].probe_dev == IPATH_NO_DEV)
478 idx = -1;
479 else
480 dd->ipath_i2c_chain_type = idx + 1;
481done:
482 return (idx >= 0) ? i2c_chains + idx : NULL;
483}
369 484
370static int ipath_eeprom_internal_read(struct ipath_devdata *dd, 485static int ipath_eeprom_internal_read(struct ipath_devdata *dd,
371 u8 eeprom_offset, void *buffer, int len) 486 u8 eeprom_offset, void *buffer, int len)
372{ 487{
373 /* compiler complains unless initialized */
374 u8 single_byte = 0;
375 int bit_cntr;
376 int ret; 488 int ret;
489 struct i2c_chain_desc *icd;
490 u8 *bp = buffer;
377 491
378 if (!eeprom_init) 492 ret = 1;
379 eeprom_reset(dd); 493 icd = ipath_i2c_type(dd);
380 494 if (!icd)
381 eeprom_offset = (eeprom_offset << 1) | READ_CMD; 495 goto bail;
382 496
383 if (i2c_startcmd(dd, eeprom_offset)) { 497 if (icd->eeprom_dev == IPATH_NO_DEV) {
384 ipath_dbg("Failed startcmd\n"); 498 /* legacy not-really-I2C */
499 ipath_cdbg(VERBOSE, "Start command only address\n");
500 eeprom_offset = (eeprom_offset << 1) | READ_CMD;
501 ret = i2c_startcmd(dd, eeprom_offset);
502 } else {
503 /* Actual I2C */
504 ipath_cdbg(VERBOSE, "Start command uses devaddr\n");
505 if (i2c_startcmd(dd, icd->eeprom_dev | WRITE_CMD)) {
506 ipath_dbg("Failed EEPROM startcmd\n");
507 stop_cmd(dd);
508 ret = 1;
509 goto bail;
510 }
511 ret = wr_byte(dd, eeprom_offset);
512 stop_cmd(dd);
513 if (ret) {
514 ipath_dev_err(dd, "Failed to write EEPROM address\n");
515 ret = 1;
516 goto bail;
517 }
518 ret = i2c_startcmd(dd, icd->eeprom_dev | READ_CMD);
519 }
520 if (ret) {
521 ipath_dbg("Failed startcmd for dev %02X\n", icd->eeprom_dev);
385 stop_cmd(dd); 522 stop_cmd(dd);
386 ret = 1; 523 ret = 1;
387 goto bail; 524 goto bail;
@@ -392,22 +529,11 @@ static int ipath_eeprom_internal_read(struct ipath_devdata *dd,
392 * incrementing the address. 529 * incrementing the address.
393 */ 530 */
394 while (len-- > 0) { 531 while (len-- > 0) {
395 /* get data */ 532 /* get and store data */
396 single_byte = 0; 533 *bp++ = rd_byte(dd);
397 for (bit_cntr = 8; bit_cntr; bit_cntr--) {
398 u8 bit;
399 scl_out(dd, i2c_line_high);
400 bit = sda_in(dd, 0);
401 single_byte |= bit << (bit_cntr - 1);
402 scl_out(dd, i2c_line_low);
403 }
404
405 /* send ack if not the last byte */ 534 /* send ack if not the last byte */
406 if (len) 535 if (len)
407 send_ack(dd); 536 send_ack(dd);
408
409 *((u8 *) buffer) = single_byte;
410 buffer++;
411 } 537 }
412 538
413 stop_cmd(dd); 539 stop_cmd(dd);
@@ -418,31 +544,40 @@ bail:
418 return ret; 544 return ret;
419} 545}
420 546
421
422/**
423 * ipath_eeprom_write - writes data to the eeprom via I2C
424 * @dd: the infinipath device
425 * @eeprom_offset: where to place data
426 * @buffer: data to write
427 * @len: number of bytes to write
428 */
429static int ipath_eeprom_internal_write(struct ipath_devdata *dd, u8 eeprom_offset, 547static int ipath_eeprom_internal_write(struct ipath_devdata *dd, u8 eeprom_offset,
430 const void *buffer, int len) 548 const void *buffer, int len)
431{ 549{
432 u8 single_byte;
433 int sub_len; 550 int sub_len;
434 const u8 *bp = buffer; 551 const u8 *bp = buffer;
435 int max_wait_time, i; 552 int max_wait_time, i;
436 int ret; 553 int ret;
554 struct i2c_chain_desc *icd;
437 555
438 if (!eeprom_init) 556 ret = 1;
439 eeprom_reset(dd); 557 icd = ipath_i2c_type(dd);
558 if (!icd)
559 goto bail;
440 560
441 while (len > 0) { 561 while (len > 0) {
442 if (i2c_startcmd(dd, (eeprom_offset << 1) | WRITE_CMD)) { 562 if (icd->eeprom_dev == IPATH_NO_DEV) {
443 ipath_dbg("Failed to start cmd offset %u\n", 563 if (i2c_startcmd(dd,
444 eeprom_offset); 564 (eeprom_offset << 1) | WRITE_CMD)) {
445 goto failed_write; 565 ipath_dbg("Failed to start cmd offset %u\n",
566 eeprom_offset);
567 goto failed_write;
568 }
569 } else {
570 /* Real I2C */
571 if (i2c_startcmd(dd, icd->eeprom_dev | WRITE_CMD)) {
572 ipath_dbg("Failed EEPROM startcmd\n");
573 goto failed_write;
574 }
575 ret = wr_byte(dd, eeprom_offset);
576 if (ret) {
577 ipath_dev_err(dd, "Failed to write EEPROM "
578 "address\n");
579 goto failed_write;
580 }
446 } 581 }
447 582
448 sub_len = min(len, 4); 583 sub_len = min(len, 4);
@@ -468,9 +603,11 @@ static int ipath_eeprom_internal_write(struct ipath_devdata *dd, u8 eeprom_offse
468 * the writes have completed. We do this inline to avoid 603 * the writes have completed. We do this inline to avoid
469 * the debug prints that are in the real read routine 604 * the debug prints that are in the real read routine
470 * if the startcmd fails. 605 * if the startcmd fails.
606 * We also use the proper device address, so it doesn't matter
607 * whether we have real eeprom_dev. legacy likes any address.
471 */ 608 */
472 max_wait_time = 100; 609 max_wait_time = 100;
473 while (i2c_startcmd(dd, READ_CMD)) { 610 while (i2c_startcmd(dd, icd->eeprom_dev | READ_CMD)) {
474 stop_cmd(dd); 611 stop_cmd(dd);
475 if (!--max_wait_time) { 612 if (!--max_wait_time) {
476 ipath_dbg("Did not get successful read to " 613 ipath_dbg("Did not get successful read to "
@@ -478,15 +615,8 @@ static int ipath_eeprom_internal_write(struct ipath_devdata *dd, u8 eeprom_offse
478 goto failed_write; 615 goto failed_write;
479 } 616 }
480 } 617 }
481 /* now read the zero byte */ 618 /* now read (and ignore) the resulting byte */
482 for (i = single_byte = 0; i < 8; i++) { 619 rd_byte(dd);
483 u8 bit;
484 scl_out(dd, i2c_line_high);
485 bit = sda_in(dd, 0);
486 scl_out(dd, i2c_line_low);
487 single_byte <<= 1;
488 single_byte |= bit;
489 }
490 stop_cmd(dd); 620 stop_cmd(dd);
491 } 621 }
492 622
@@ -501,9 +631,12 @@ bail:
501 return ret; 631 return ret;
502} 632}
503 633
504/* 634/**
505 * The public entry-points ipath_eeprom_read() and ipath_eeprom_write() 635 * ipath_eeprom_read - receives bytes from the eeprom via I2C
506 * are now just wrappers around the internal functions. 636 * @dd: the infinipath device
637 * @eeprom_offset: address to read from
638 * @buffer: where to store result
639 * @len: number of bytes to receive
507 */ 640 */
508int ipath_eeprom_read(struct ipath_devdata *dd, u8 eeprom_offset, 641int ipath_eeprom_read(struct ipath_devdata *dd, u8 eeprom_offset,
509 void *buff, int len) 642 void *buff, int len)
@@ -519,6 +652,13 @@ int ipath_eeprom_read(struct ipath_devdata *dd, u8 eeprom_offset,
519 return ret; 652 return ret;
520} 653}
521 654
655/**
656 * ipath_eeprom_write - writes data to the eeprom via I2C
657 * @dd: the infinipath device
658 * @eeprom_offset: where to place data
659 * @buffer: data to write
660 * @len: number of bytes to write
661 */
522int ipath_eeprom_write(struct ipath_devdata *dd, u8 eeprom_offset, 662int ipath_eeprom_write(struct ipath_devdata *dd, u8 eeprom_offset,
523 const void *buff, int len) 663 const void *buff, int len)
524{ 664{
@@ -820,7 +960,7 @@ int ipath_update_eeprom_log(struct ipath_devdata *dd)
820 * if we log an hour at 31 minutes, then we would need to set 960 * if we log an hour at 31 minutes, then we would need to set
821 * active_time to -29 to accurately count the _next_ hour. 961 * active_time to -29 to accurately count the _next_ hour.
822 */ 962 */
823 if (new_time > 3600) { 963 if (new_time >= 3600) {
824 new_hrs = new_time / 3600; 964 new_hrs = new_time / 3600;
825 atomic_sub((new_hrs * 3600), &dd->ipath_active_time); 965 atomic_sub((new_hrs * 3600), &dd->ipath_active_time);
826 new_hrs += dd->ipath_eep_hrs; 966 new_hrs += dd->ipath_eep_hrs;
@@ -885,3 +1025,159 @@ void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr)
885 spin_unlock_irqrestore(&dd->ipath_eep_st_lock, flags); 1025 spin_unlock_irqrestore(&dd->ipath_eep_st_lock, flags);
886 return; 1026 return;
887} 1027}
1028
1029static int ipath_tempsense_internal_read(struct ipath_devdata *dd, u8 regnum)
1030{
1031 int ret;
1032 struct i2c_chain_desc *icd;
1033
1034 ret = -ENOENT;
1035
1036 icd = ipath_i2c_type(dd);
1037 if (!icd)
1038 goto bail;
1039
1040 if (icd->temp_dev == IPATH_NO_DEV) {
1041 /* tempsense only exists on new, real-I2C boards */
1042 ret = -ENXIO;
1043 goto bail;
1044 }
1045
1046 if (i2c_startcmd(dd, icd->temp_dev | WRITE_CMD)) {
1047 ipath_dbg("Failed tempsense startcmd\n");
1048 stop_cmd(dd);
1049 ret = -ENXIO;
1050 goto bail;
1051 }
1052 ret = wr_byte(dd, regnum);
1053 stop_cmd(dd);
1054 if (ret) {
1055 ipath_dev_err(dd, "Failed tempsense WR command %02X\n",
1056 regnum);
1057 ret = -ENXIO;
1058 goto bail;
1059 }
1060 if (i2c_startcmd(dd, icd->temp_dev | READ_CMD)) {
1061 ipath_dbg("Failed tempsense RD startcmd\n");
1062 stop_cmd(dd);
1063 ret = -ENXIO;
1064 goto bail;
1065 }
1066 /*
1067 * We can only clock out one byte per command, sensibly
1068 */
1069 ret = rd_byte(dd);
1070 stop_cmd(dd);
1071
1072bail:
1073 return ret;
1074}
1075
1076#define VALID_TS_RD_REG_MASK 0xBF
1077
1078/**
1079 * ipath_tempsense_read - read register of temp sensor via I2C
1080 * @dd: the infinipath device
1081 * @regnum: register to read from
1082 *
1083 * returns reg contents (0..255) or < 0 for error
1084 */
1085int ipath_tempsense_read(struct ipath_devdata *dd, u8 regnum)
1086{
1087 int ret;
1088
1089 if (regnum > 7)
1090 return -EINVAL;
1091
1092 /* return a bogus value for (the one) register we do not have */
1093 if (!((1 << regnum) & VALID_TS_RD_REG_MASK))
1094 return 0;
1095
1096 ret = mutex_lock_interruptible(&dd->ipath_eep_lock);
1097 if (!ret) {
1098 ret = ipath_tempsense_internal_read(dd, regnum);
1099 mutex_unlock(&dd->ipath_eep_lock);
1100 }
1101
1102 /*
1103 * There are three possibilities here:
1104 * ret is actual value (0..255)
1105 * ret is -ENXIO or -EINVAL from code in this file
1106 * ret is -EINTR from mutex_lock_interruptible.
1107 */
1108 return ret;
1109}
1110
1111static int ipath_tempsense_internal_write(struct ipath_devdata *dd,
1112 u8 regnum, u8 data)
1113{
1114 int ret = -ENOENT;
1115 struct i2c_chain_desc *icd;
1116
1117 icd = ipath_i2c_type(dd);
1118 if (!icd)
1119 goto bail;
1120
1121 if (icd->temp_dev == IPATH_NO_DEV) {
1122 /* tempsense only exists on new, real-I2C boards */
1123 ret = -ENXIO;
1124 goto bail;
1125 }
1126 if (i2c_startcmd(dd, icd->temp_dev | WRITE_CMD)) {
1127 ipath_dbg("Failed tempsense startcmd\n");
1128 stop_cmd(dd);
1129 ret = -ENXIO;
1130 goto bail;
1131 }
1132 ret = wr_byte(dd, regnum);
1133 if (ret) {
1134 stop_cmd(dd);
1135 ipath_dev_err(dd, "Failed to write tempsense command %02X\n",
1136 regnum);
1137 ret = -ENXIO;
1138 goto bail;
1139 }
1140 ret = wr_byte(dd, data);
1141 stop_cmd(dd);
1142 ret = i2c_startcmd(dd, icd->temp_dev | READ_CMD);
1143 if (ret) {
1144 ipath_dev_err(dd, "Failed tempsense data wrt to %02X\n",
1145 regnum);
1146 ret = -ENXIO;
1147 }
1148
1149bail:
1150 return ret;
1151}
1152
1153#define VALID_TS_WR_REG_MASK ((1 << 9) | (1 << 0xB) | (1 << 0xD))
1154
1155/**
1156 * ipath_tempsense_write - write register of temp sensor via I2C
1157 * @dd: the infinipath device
1158 * @regnum: register to write
1159 * @data: data to write
1160 *
1161 * returns 0 for success or < 0 for error
1162 */
1163int ipath_tempsense_write(struct ipath_devdata *dd, u8 regnum, u8 data)
1164{
1165 int ret;
1166
1167 if (regnum > 15 || !((1 << regnum) & VALID_TS_WR_REG_MASK))
1168 return -EINVAL;
1169
1170 ret = mutex_lock_interruptible(&dd->ipath_eep_lock);
1171 if (!ret) {
1172 ret = ipath_tempsense_internal_write(dd, regnum, data);
1173 mutex_unlock(&dd->ipath_eep_lock);
1174 }
1175
1176 /*
1177 * There are three possibilities here:
1178 * ret is 0 for success
1179 * ret is -ENXIO or -EINVAL from code in this file
1180 * ret is -EINTR from mutex_lock_interruptible.
1181 */
1182 return ret;
1183}
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 3a15af26b093..398de7f7e2e4 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -654,8 +654,9 @@ struct ipath_devdata {
654 * Register bits for selecting i2c direction and values, used for 654 * Register bits for selecting i2c direction and values, used for
655 * I2C serial flash. 655 * I2C serial flash.
656 */ 656 */
657 u16 ipath_gpio_sda_num; 657 u8 ipath_gpio_sda_num;
658 u16 ipath_gpio_scl_num; 658 u8 ipath_gpio_scl_num;
659 u8 ipath_i2c_chain_type;
659 u64 ipath_gpio_sda; 660 u64 ipath_gpio_sda;
660 u64 ipath_gpio_scl; 661 u64 ipath_gpio_scl;
661 662
@@ -906,6 +907,8 @@ void ipath_release_user_pages(struct page **, size_t);
906void ipath_release_user_pages_on_close(struct page **, size_t); 907void ipath_release_user_pages_on_close(struct page **, size_t);
907int ipath_eeprom_read(struct ipath_devdata *, u8, void *, int); 908int ipath_eeprom_read(struct ipath_devdata *, u8, void *, int);
908int ipath_eeprom_write(struct ipath_devdata *, u8, const void *, int); 909int ipath_eeprom_write(struct ipath_devdata *, u8, const void *, int);
910int ipath_tempsense_read(struct ipath_devdata *, u8 regnum);
911int ipath_tempsense_write(struct ipath_devdata *, u8 regnum, u8 data);
909 912
910/* these are used for the registers that vary with port */ 913/* these are used for the registers that vary with port */
911void ipath_write_kreg_port(const struct ipath_devdata *, ipath_kreg, 914void ipath_write_kreg_port(const struct ipath_devdata *, ipath_kreg,
diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c
index bb41c3f6aad3..7961d26404f1 100644
--- a/drivers/infiniband/hw/ipath/ipath_sysfs.c
+++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c
@@ -943,6 +943,7 @@ invalid:
943bail: 943bail:
944 return ret; 944 return ret;
945} 945}
946
946/* 947/*
947 * Get/Set RX lane-reversal enable. 0=no, 1=yes. 948 * Get/Set RX lane-reversal enable. 0=no, 1=yes.
948 */ 949 */
@@ -997,6 +998,75 @@ static struct attribute_group driver_attr_group = {
997 .attrs = driver_attributes 998 .attrs = driver_attributes
998}; 999};
999 1000
1001static ssize_t store_tempsense(struct device *dev,
1002 struct device_attribute *attr,
1003 const char *buf,
1004 size_t count)
1005{
1006 struct ipath_devdata *dd = dev_get_drvdata(dev);
1007 int ret, stat;
1008 u16 val;
1009
1010 ret = ipath_parse_ushort(buf, &val);
1011 if (ret <= 0) {
1012 ipath_dev_err(dd, "attempt to set invalid tempsense config\n");
1013 goto bail;
1014 }
1015 /* If anything but the highest limit, enable T_CRIT_A "interrupt" */
1016 stat = ipath_tempsense_write(dd, 9, (val == 0x7f7f) ? 0x80 : 0);
1017 if (stat) {
1018 ipath_dev_err(dd, "Unable to set tempsense config\n");
1019 ret = -1;
1020 goto bail;
1021 }
1022 stat = ipath_tempsense_write(dd, 0xB, (u8) (val & 0xFF));
1023 if (stat) {
1024 ipath_dev_err(dd, "Unable to set local Tcrit\n");
1025 ret = -1;
1026 goto bail;
1027 }
1028 stat = ipath_tempsense_write(dd, 0xD, (u8) (val >> 8));
1029 if (stat) {
1030 ipath_dev_err(dd, "Unable to set remote Tcrit\n");
1031 ret = -1;
1032 goto bail;
1033 }
1034
1035bail:
1036 return ret;
1037}
1038
1039/*
1040 * dump tempsense regs. in decimal, to ease shell-scripts.
1041 */
1042static ssize_t show_tempsense(struct device *dev,
1043 struct device_attribute *attr,
1044 char *buf)
1045{
1046 struct ipath_devdata *dd = dev_get_drvdata(dev);
1047 int ret;
1048 int idx;
1049 u8 regvals[8];
1050
1051 ret = -ENXIO;
1052 for (idx = 0; idx < 8; ++idx) {
1053 if (idx == 6)
1054 continue;
1055 ret = ipath_tempsense_read(dd, idx);
1056 if (ret < 0)
1057 break;
1058 regvals[idx] = ret;
1059 }
1060 if (idx == 8)
1061 ret = scnprintf(buf, PAGE_SIZE, "%d %d %02X %02X %d %d\n",
1062 *(signed char *)(regvals),
1063 *(signed char *)(regvals + 1),
1064 regvals[2], regvals[3],
1065 *(signed char *)(regvals + 5),
1066 *(signed char *)(regvals + 7));
1067 return ret;
1068}
1069
1000struct attribute_group *ipath_driver_attr_groups[] = { 1070struct attribute_group *ipath_driver_attr_groups[] = {
1001 &driver_attr_group, 1071 &driver_attr_group,
1002 NULL, 1072 NULL,
@@ -1025,6 +1095,8 @@ static DEVICE_ATTR(jint_max_packets, S_IWUSR | S_IRUGO,
1025 show_jint_max_packets, store_jint_max_packets); 1095 show_jint_max_packets, store_jint_max_packets);
1026static DEVICE_ATTR(jint_idle_ticks, S_IWUSR | S_IRUGO, 1096static DEVICE_ATTR(jint_idle_ticks, S_IWUSR | S_IRUGO,
1027 show_jint_idle_ticks, store_jint_idle_ticks); 1097 show_jint_idle_ticks, store_jint_idle_ticks);
1098static DEVICE_ATTR(tempsense, S_IWUSR | S_IRUGO,
1099 show_tempsense, store_tempsense);
1028 1100
1029static struct attribute *dev_attributes[] = { 1101static struct attribute *dev_attributes[] = {
1030 &dev_attr_guid.attr, 1102 &dev_attr_guid.attr,
@@ -1044,6 +1116,7 @@ static struct attribute *dev_attributes[] = {
1044 &dev_attr_rx_pol_inv.attr, 1116 &dev_attr_rx_pol_inv.attr,
1045 &dev_attr_led_override.attr, 1117 &dev_attr_led_override.attr,
1046 &dev_attr_logged_errors.attr, 1118 &dev_attr_logged_errors.attr,
1119 &dev_attr_tempsense.attr,
1047 &dev_attr_localbus_info.attr, 1120 &dev_attr_localbus_info.attr,
1048 NULL 1121 NULL
1049}; 1122};