Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02214724 authored by Jarod Wilson's avatar Jarod Wilson Committed by Stefan Richter
Browse files

firewire: fw-ohci: make sure HCControl register LPS bit is set



I've now witnessed multiple occasions where one of my controllers (a very
poorly working JMicron PCIe card) fails to get its registers properly set
up in ohci_enable(), apparently due to an occasionally very slow to
initiate SClk. The easy fix for this problem is to add a tiny while loop
to try again a time or three after initially enabling LPS before we
move on (or give up).

Of course, the card still isn't fully functional yet, but this gets it at
least one tiny step closer...

Signed-off-by: default avatarJarod Wilson <jwilson@redhat.com>
Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
parent 130d5496
Loading
Loading
Loading
Loading
+15 −2
Original line number Original line Diff line number Diff line
@@ -1390,6 +1390,8 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
{
{
	struct fw_ohci *ohci = fw_ohci(card);
	struct fw_ohci *ohci = fw_ohci(card);
	struct pci_dev *dev = to_pci_dev(card->device);
	struct pci_dev *dev = to_pci_dev(card->device);
	u32 lps;
	int i;


	if (software_reset(ohci)) {
	if (software_reset(ohci)) {
		fw_error("Failed to reset ohci card.\n");
		fw_error("Failed to reset ohci card.\n");
@@ -1401,13 +1403,24 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
	 * most of the registers.  In fact, on some cards (ALI M5251),
	 * most of the registers.  In fact, on some cards (ALI M5251),
	 * accessing registers in the SClk domain without LPS enabled
	 * accessing registers in the SClk domain without LPS enabled
	 * will lock up the machine.  Wait 50msec to make sure we have
	 * will lock up the machine.  Wait 50msec to make sure we have
	 * full link enabled.
	 * full link enabled.  However, with some cards (well, at least
	 * a JMicron PCIe card), we have to try again sometimes.
	 */
	 */
	reg_write(ohci, OHCI1394_HCControlSet,
	reg_write(ohci, OHCI1394_HCControlSet,
		  OHCI1394_HCControl_LPS |
		  OHCI1394_HCControl_LPS |
		  OHCI1394_HCControl_postedWriteEnable);
		  OHCI1394_HCControl_postedWriteEnable);
	flush_writes(ohci);
	flush_writes(ohci);

	for (lps = 0, i = 0; !lps && i < 3; i++) {
		msleep(50);
		msleep(50);
		lps = reg_read(ohci, OHCI1394_HCControlSet) &
		      OHCI1394_HCControl_LPS;
	}

	if (!lps) {
		fw_error("Failed to set Link Power Status\n");
		return -EIO;
	}


	reg_write(ohci, OHCI1394_HCControlClear,
	reg_write(ohci, OHCI1394_HCControlClear,
		  OHCI1394_HCControl_noByteSwapData);
		  OHCI1394_HCControl_noByteSwapData);