diff options
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r-- | drivers/firewire/ohci.c | 112 |
1 files changed, 57 insertions, 55 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 6a27a0ef3b63..5bbf42eb3f9a 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -463,35 +463,51 @@ static inline void flush_writes(const struct fw_ohci *ohci) | |||
463 | reg_read(ohci, OHCI1394_Version); | 463 | reg_read(ohci, OHCI1394_Version); |
464 | } | 464 | } |
465 | 465 | ||
466 | static int read_phy_reg(struct fw_card *card, int addr, u32 *value) | 466 | static int read_phy_reg(struct fw_ohci *ohci, int addr) |
467 | { | 467 | { |
468 | struct fw_ohci *ohci = fw_ohci(card); | ||
469 | u32 val; | 468 | u32 val; |
469 | int i; | ||
470 | 470 | ||
471 | reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr)); | 471 | reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr)); |
472 | flush_writes(ohci); | 472 | for (i = 0; i < 10; i++) { |
473 | msleep(2); | 473 | val = reg_read(ohci, OHCI1394_PhyControl); |
474 | val = reg_read(ohci, OHCI1394_PhyControl); | 474 | if (val & OHCI1394_PhyControl_ReadDone) |
475 | if ((val & OHCI1394_PhyControl_ReadDone) == 0) { | 475 | return OHCI1394_PhyControl_ReadData(val); |
476 | fw_error("failed to read phy reg bits\n"); | 476 | |
477 | return -EBUSY; | 477 | msleep(1); |
478 | } | 478 | } |
479 | fw_error("failed to read phy reg\n"); | ||
479 | 480 | ||
480 | *value = OHCI1394_PhyControl_ReadData(val); | 481 | return -EBUSY; |
482 | } | ||
481 | 483 | ||
482 | return 0; | 484 | static int write_phy_reg(const struct fw_ohci *ohci, int addr, u32 val) |
485 | { | ||
486 | int i; | ||
487 | |||
488 | reg_write(ohci, OHCI1394_PhyControl, | ||
489 | OHCI1394_PhyControl_Write(addr, val)); | ||
490 | for (i = 0; i < 100; i++) { | ||
491 | val = reg_read(ohci, OHCI1394_PhyControl); | ||
492 | if (!(val & OHCI1394_PhyControl_WritePending)) | ||
493 | return 0; | ||
494 | |||
495 | msleep(1); | ||
496 | } | ||
497 | fw_error("failed to write phy reg\n"); | ||
498 | |||
499 | return -EBUSY; | ||
483 | } | 500 | } |
484 | 501 | ||
485 | static int ohci_update_phy_reg(struct fw_card *card, int addr, | 502 | static int ohci_update_phy_reg(struct fw_card *card, int addr, |
486 | int clear_bits, int set_bits) | 503 | int clear_bits, int set_bits) |
487 | { | 504 | { |
488 | struct fw_ohci *ohci = fw_ohci(card); | 505 | struct fw_ohci *ohci = fw_ohci(card); |
489 | u32 old; | 506 | int ret; |
490 | int err; | ||
491 | 507 | ||
492 | err = read_phy_reg(card, addr, &old); | 508 | ret = read_phy_reg(ohci, addr); |
493 | if (err < 0) | 509 | if (ret < 0) |
494 | return err; | 510 | return ret; |
495 | 511 | ||
496 | /* | 512 | /* |
497 | * The interrupt status bits are cleared by writing a one bit. | 513 | * The interrupt status bits are cleared by writing a one bit. |
@@ -500,32 +516,18 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr, | |||
500 | if (addr == 5) | 516 | if (addr == 5) |
501 | clear_bits |= PHY_INT_STATUS_BITS; | 517 | clear_bits |= PHY_INT_STATUS_BITS; |
502 | 518 | ||
503 | old = (old & ~clear_bits) | set_bits; | 519 | return write_phy_reg(ohci, addr, (ret & ~clear_bits) | set_bits); |
504 | reg_write(ohci, OHCI1394_PhyControl, | ||
505 | OHCI1394_PhyControl_Write(addr, old)); | ||
506 | |||
507 | return 0; | ||
508 | } | 520 | } |
509 | 521 | ||
510 | static int read_paged_phy_reg(struct fw_card *card, | 522 | static int read_paged_phy_reg(struct fw_ohci *ohci, int page, int addr) |
511 | int page, int addr, u32 *value) | ||
512 | { | 523 | { |
513 | struct fw_ohci *ohci = fw_ohci(card); | 524 | int ret; |
514 | u32 reg; | ||
515 | int err; | ||
516 | 525 | ||
517 | err = ohci_update_phy_reg(card, 7, PHY_PAGE_SELECT, page << 5); | 526 | ret = ohci_update_phy_reg(&ohci->card, 7, PHY_PAGE_SELECT, page << 5); |
518 | if (err < 0) | 527 | if (ret < 0) |
519 | return err; | 528 | return ret; |
520 | flush_writes(ohci); | ||
521 | msleep(2); | ||
522 | reg = reg_read(ohci, OHCI1394_PhyControl); | ||
523 | if ((reg & OHCI1394_PhyControl_WritePending) != 0) { | ||
524 | fw_error("failed to write phy reg bits\n"); | ||
525 | return -EBUSY; | ||
526 | } | ||
527 | 529 | ||
528 | return read_phy_reg(card, addr, value); | 530 | return read_phy_reg(ohci, addr); |
529 | } | 531 | } |
530 | 532 | ||
531 | static int ar_context_add_page(struct ar_context *ctx) | 533 | static int ar_context_add_page(struct ar_context *ctx) |
@@ -1538,8 +1540,7 @@ static void copy_config_rom(__be32 *dest, const __be32 *src, size_t length) | |||
1538 | static int configure_1394a_enhancements(struct fw_ohci *ohci) | 1540 | static int configure_1394a_enhancements(struct fw_ohci *ohci) |
1539 | { | 1541 | { |
1540 | bool enable_1394a; | 1542 | bool enable_1394a; |
1541 | u32 reg, phy_compliance; | 1543 | int ret, clear, set, offset; |
1542 | int clear, set, offset; | ||
1543 | 1544 | ||
1544 | /* Check if the driver should configure link and PHY. */ | 1545 | /* Check if the driver should configure link and PHY. */ |
1545 | if (!(reg_read(ohci, OHCI1394_HCControlSet) & | 1546 | if (!(reg_read(ohci, OHCI1394_HCControlSet) & |
@@ -1548,12 +1549,14 @@ static int configure_1394a_enhancements(struct fw_ohci *ohci) | |||
1548 | 1549 | ||
1549 | /* Paranoia: check whether the PHY supports 1394a, too. */ | 1550 | /* Paranoia: check whether the PHY supports 1394a, too. */ |
1550 | enable_1394a = false; | 1551 | enable_1394a = false; |
1551 | if (read_phy_reg(&ohci->card, 2, ®) < 0) | 1552 | ret = read_phy_reg(ohci, 2); |
1552 | return -EIO; | 1553 | if (ret < 0) |
1553 | if ((reg & PHY_EXTENDED_REGISTERS) == PHY_EXTENDED_REGISTERS) { | 1554 | return ret; |
1554 | if (read_paged_phy_reg(&ohci->card, 1, 8, &phy_compliance) < 0) | 1555 | if ((ret & PHY_EXTENDED_REGISTERS) == PHY_EXTENDED_REGISTERS) { |
1555 | return -EIO; | 1556 | ret = read_paged_phy_reg(ohci, 1, 8); |
1556 | if (phy_compliance >= 1) | 1557 | if (ret < 0) |
1558 | return ret; | ||
1559 | if (ret >= 1) | ||
1557 | enable_1394a = true; | 1560 | enable_1394a = true; |
1558 | } | 1561 | } |
1559 | 1562 | ||
@@ -1568,10 +1571,9 @@ static int configure_1394a_enhancements(struct fw_ohci *ohci) | |||
1568 | clear = PHY_ENABLE_ACCEL | PHY_ENABLE_MULTI; | 1571 | clear = PHY_ENABLE_ACCEL | PHY_ENABLE_MULTI; |
1569 | set = 0; | 1572 | set = 0; |
1570 | } | 1573 | } |
1571 | if (ohci_update_phy_reg(&ohci->card, 5, clear, set) < 0) | 1574 | ret = ohci_update_phy_reg(&ohci->card, 5, clear, set); |
1572 | return -EIO; | 1575 | if (ret < 0) |
1573 | flush_writes(ohci); | 1576 | return ret; |
1574 | msleep(2); | ||
1575 | 1577 | ||
1576 | if (enable_1394a) | 1578 | if (enable_1394a) |
1577 | offset = OHCI1394_HCControlSet; | 1579 | offset = OHCI1394_HCControlSet; |
@@ -1592,7 +1594,7 @@ static int ohci_enable(struct fw_card *card, | |||
1592 | struct fw_ohci *ohci = fw_ohci(card); | 1594 | struct fw_ohci *ohci = fw_ohci(card); |
1593 | struct pci_dev *dev = to_pci_dev(card->device); | 1595 | struct pci_dev *dev = to_pci_dev(card->device); |
1594 | u32 lps; | 1596 | u32 lps; |
1595 | int i, err; | 1597 | int i, ret; |
1596 | 1598 | ||
1597 | if (software_reset(ohci)) { | 1599 | if (software_reset(ohci)) { |
1598 | fw_error("Failed to reset ohci card.\n"); | 1600 | fw_error("Failed to reset ohci card.\n"); |
@@ -1656,14 +1658,14 @@ static int ohci_enable(struct fw_card *card, | |||
1656 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) | 1658 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) |
1657 | reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); | 1659 | reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); |
1658 | 1660 | ||
1659 | err = configure_1394a_enhancements(ohci); | 1661 | ret = configure_1394a_enhancements(ohci); |
1660 | if (err < 0) | 1662 | if (ret < 0) |
1661 | return err; | 1663 | return ret; |
1662 | 1664 | ||
1663 | /* Activate link_on bit and contender bit in our self ID packets.*/ | 1665 | /* Activate link_on bit and contender bit in our self ID packets.*/ |
1664 | if (ohci_update_phy_reg(card, 4, 0, | 1666 | ret = ohci_update_phy_reg(card, 4, 0, PHY_LINK_ACTIVE | PHY_CONTENDER); |
1665 | PHY_LINK_ACTIVE | PHY_CONTENDER) < 0) | 1667 | if (ret < 0) |
1666 | return -EIO; | 1668 | return ret; |
1667 | 1669 | ||
1668 | /* | 1670 | /* |
1669 | * When the link is not yet enabled, the atomic config rom | 1671 | * When the link is not yet enabled, the atomic config rom |