diff options
| -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 |
