aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2010-04-10 10:04:56 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2010-04-10 10:51:14 -0400
commit35d999b12037b5ea0152889232629c25d45b0e26 (patch)
tree4c9838cd44e7f2539f986ff3acbe4c45ce12bc8e /drivers/firewire
parent54672386ccf36ffa21d1de8e75624af83f9b0eeb (diff)
firewire: ohci: wait for PHY register accesses to complete
Rather than having the arbitrary msleep(2) pause, let read_phy_reg() loop until the link--phy access was finished. Factor write_phy_reg() out of ohci_update_phy_reg() and of read_paged_phy_reg() and let it loop too until the link--phy access was finished. Like in the older ohci1394 driver, a timeout of 100 milliseconds is chosen. Unlike the old driver, we sleep instead of busy-wait in each waiting loop iteration. Instead of a loop, the waiting could probably also be implemented interrupt driven, but why bother. It would require up and running interrupt handling before the link was fully configured and enabled. Also modify functions a bit: Error return and value return can be combined in read_phy_reg() since the domain of values is only u8. Likewise in read_paged_phy_reg(). Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/ohci.c112
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
466static int read_phy_reg(struct fw_card *card, int addr, u32 *value) 466static 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; 484static 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
485static int ohci_update_phy_reg(struct fw_card *card, int addr, 502static 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
510static int read_paged_phy_reg(struct fw_card *card, 522static 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
531static int ar_context_add_page(struct ar_context *ctx) 533static 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)
1538static int configure_1394a_enhancements(struct fw_ohci *ohci) 1540static 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, &reg) < 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