diff options
author | Bruce Losure <blosure@americas.sgi.com> | 2005-09-02 16:16:35 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2005-09-06 17:16:01 -0400 |
commit | 25732ad493b22b7d9f0d250c5a9ad17219f96a47 (patch) | |
tree | 6d2c753c248977fdca4b5d423b65d7fbf2f70186 /arch/ia64 | |
parent | 4706df3d3c42af802597d82c8b1542c3d52eab23 (diff) |
[IA64] Altix patch for fpga reset
1) workaround a h/w reset issue
2) to improve the determination of FPGA-based h/w in
the arch/ia64/sn/kernel/tiocx code.
Signed-off-by: Bruce Losure <blosure@sgi.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64')
-rw-r--r-- | arch/ia64/sn/kernel/tiocx.c | 62 |
1 files changed, 33 insertions, 29 deletions
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index 254fe15c064b..d8664715764b 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c | |||
@@ -183,11 +183,12 @@ int cx_driver_unregister(struct cx_drv *cx_driver) | |||
183 | * @part_num: device's part number | 183 | * @part_num: device's part number |
184 | * @mfg_num: device's manufacturer number | 184 | * @mfg_num: device's manufacturer number |
185 | * @hubdev: hub info associated with this device | 185 | * @hubdev: hub info associated with this device |
186 | * @bt: board type of the device | ||
186 | * | 187 | * |
187 | */ | 188 | */ |
188 | int | 189 | int |
189 | cx_device_register(nasid_t nasid, int part_num, int mfg_num, | 190 | cx_device_register(nasid_t nasid, int part_num, int mfg_num, |
190 | struct hubdev_info *hubdev) | 191 | struct hubdev_info *hubdev, int bt) |
191 | { | 192 | { |
192 | struct cx_dev *cx_dev; | 193 | struct cx_dev *cx_dev; |
193 | 194 | ||
@@ -200,6 +201,7 @@ cx_device_register(nasid_t nasid, int part_num, int mfg_num, | |||
200 | cx_dev->cx_id.mfg_num = mfg_num; | 201 | cx_dev->cx_id.mfg_num = mfg_num; |
201 | cx_dev->cx_id.nasid = nasid; | 202 | cx_dev->cx_id.nasid = nasid; |
202 | cx_dev->hubdev = hubdev; | 203 | cx_dev->hubdev = hubdev; |
204 | cx_dev->bt = bt; | ||
203 | 205 | ||
204 | cx_dev->dev.parent = NULL; | 206 | cx_dev->dev.parent = NULL; |
205 | cx_dev->dev.bus = &tiocx_bus_type; | 207 | cx_dev->dev.bus = &tiocx_bus_type; |
@@ -238,7 +240,8 @@ static int cx_device_reload(struct cx_dev *cx_dev) | |||
238 | { | 240 | { |
239 | cx_device_unregister(cx_dev); | 241 | cx_device_unregister(cx_dev); |
240 | return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num, | 242 | return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num, |
241 | cx_dev->cx_id.mfg_num, cx_dev->hubdev); | 243 | cx_dev->cx_id.mfg_num, cx_dev->hubdev, |
244 | cx_dev->bt); | ||
242 | } | 245 | } |
243 | 246 | ||
244 | static inline uint64_t tiocx_intr_alloc(nasid_t nasid, int widget, | 247 | static inline uint64_t tiocx_intr_alloc(nasid_t nasid, int widget, |
@@ -365,26 +368,20 @@ static void tio_corelet_reset(nasid_t nasid, int corelet) | |||
365 | udelay(2000); | 368 | udelay(2000); |
366 | } | 369 | } |
367 | 370 | ||
368 | static int tiocx_btchar_get(int nasid) | 371 | static int is_fpga_tio(int nasid, int *bt) |
369 | { | 372 | { |
370 | moduleid_t module_id; | 373 | int ioboard_type; |
371 | geoid_t geoid; | ||
372 | int cnodeid; | ||
373 | |||
374 | cnodeid = nasid_to_cnodeid(nasid); | ||
375 | geoid = cnodeid_get_geoid(cnodeid); | ||
376 | module_id = geo_module(geoid); | ||
377 | return MODULE_GET_BTCHAR(module_id); | ||
378 | } | ||
379 | 374 | ||
380 | static int is_fpga_brick(int nasid) | 375 | ioboard_type = ia64_sn_sysctl_ioboard_get(nasid); |
381 | { | 376 | |
382 | switch (tiocx_btchar_get(nasid)) { | 377 | switch (ioboard_type) { |
383 | case L1_BRICKTYPE_SA: | 378 | case L1_BRICKTYPE_SA: |
384 | case L1_BRICKTYPE_ATHENA: | 379 | case L1_BRICKTYPE_ATHENA: |
385 | case L1_BRICKTYPE_DAYTONA: | 380 | case L1_BOARDTYPE_DAYTONA: |
381 | *bt = ioboard_type; | ||
386 | return 1; | 382 | return 1; |
387 | } | 383 | } |
384 | |||
388 | return 0; | 385 | return 0; |
389 | } | 386 | } |
390 | 387 | ||
@@ -407,16 +404,22 @@ static int tiocx_reload(struct cx_dev *cx_dev) | |||
407 | 404 | ||
408 | if (bitstream_loaded(nasid)) { | 405 | if (bitstream_loaded(nasid)) { |
409 | uint64_t cx_id; | 406 | uint64_t cx_id; |
410 | 407 | int rv; | |
411 | cx_id = | 408 | |
412 | *(volatile uint64_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) + | 409 | rv = ia64_sn_sysctl_tio_clock_reset(nasid); |
410 | if (rv) { | ||
411 | printk(KERN_ALERT "CX port JTAG reset failed.\n"); | ||
412 | } else { | ||
413 | cx_id = *(volatile uint64_t *) | ||
414 | (TIO_SWIN_BASE(nasid, TIOCX_CORELET) + | ||
413 | WIDGET_ID); | 415 | WIDGET_ID); |
414 | part_num = XWIDGET_PART_NUM(cx_id); | 416 | part_num = XWIDGET_PART_NUM(cx_id); |
415 | mfg_num = XWIDGET_MFG_NUM(cx_id); | 417 | mfg_num = XWIDGET_MFG_NUM(cx_id); |
416 | DBG("part= 0x%x, mfg= 0x%x\n", part_num, mfg_num); | 418 | DBG("part= 0x%x, mfg= 0x%x\n", part_num, mfg_num); |
417 | /* just ignore it if it's a CE */ | 419 | /* just ignore it if it's a CE */ |
418 | if (part_num == TIO_CE_ASIC_PARTNUM) | 420 | if (part_num == TIO_CE_ASIC_PARTNUM) |
419 | return 0; | 421 | return 0; |
422 | } | ||
420 | } | 423 | } |
421 | 424 | ||
422 | cx_dev->cx_id.part_num = part_num; | 425 | cx_dev->cx_id.part_num = part_num; |
@@ -436,10 +439,10 @@ static ssize_t show_cxdev_control(struct device *dev, struct device_attribute *a | |||
436 | { | 439 | { |
437 | struct cx_dev *cx_dev = to_cx_dev(dev); | 440 | struct cx_dev *cx_dev = to_cx_dev(dev); |
438 | 441 | ||
439 | return sprintf(buf, "0x%x 0x%x 0x%x %d\n", | 442 | return sprintf(buf, "0x%x 0x%x 0x%x 0x%x\n", |
440 | cx_dev->cx_id.nasid, | 443 | cx_dev->cx_id.nasid, |
441 | cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num, | 444 | cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num, |
442 | tiocx_btchar_get(cx_dev->cx_id.nasid)); | 445 | cx_dev->bt); |
443 | } | 446 | } |
444 | 447 | ||
445 | static ssize_t store_cxdev_control(struct device *dev, struct device_attribute *attr, const char *buf, | 448 | static ssize_t store_cxdev_control(struct device *dev, struct device_attribute *attr, const char *buf, |
@@ -488,11 +491,12 @@ static int __init tiocx_init(void) | |||
488 | 491 | ||
489 | for (cnodeid = 0; cnodeid < MAX_COMPACT_NODES; cnodeid++) { | 492 | for (cnodeid = 0; cnodeid < MAX_COMPACT_NODES; cnodeid++) { |
490 | nasid_t nasid; | 493 | nasid_t nasid; |
494 | int bt; | ||
491 | 495 | ||
492 | if ((nasid = cnodeid_to_nasid(cnodeid)) < 0) | 496 | if ((nasid = cnodeid_to_nasid(cnodeid)) < 0) |
493 | break; /* No more nasids .. bail out of loop */ | 497 | break; /* No more nasids .. bail out of loop */ |
494 | 498 | ||
495 | if ((nasid & 0x1) && is_fpga_brick(nasid)) { | 499 | if ((nasid & 0x1) && is_fpga_tio(nasid, &bt)) { |
496 | struct hubdev_info *hubdev; | 500 | struct hubdev_info *hubdev; |
497 | struct xwidget_info *widgetp; | 501 | struct xwidget_info *widgetp; |
498 | 502 | ||
@@ -512,7 +516,7 @@ static int __init tiocx_init(void) | |||
512 | 516 | ||
513 | if (cx_device_register | 517 | if (cx_device_register |
514 | (nasid, widgetp->xwi_hwid.part_num, | 518 | (nasid, widgetp->xwi_hwid.part_num, |
515 | widgetp->xwi_hwid.mfg_num, hubdev) < 0) | 519 | widgetp->xwi_hwid.mfg_num, hubdev, bt) < 0) |
516 | return -ENXIO; | 520 | return -ENXIO; |
517 | else | 521 | else |
518 | found_tiocx_device++; | 522 | found_tiocx_device++; |