Skip to content

Commit

Permalink
mei: ME hardware reset needs to be synchronized
Browse files Browse the repository at this point in the history
This fixes failure during initialization on Lynx Point LP devices.

ME driver needs to release the device from the reset
only after the FW has completed its flow and indicated
it by delivering an interrupt to the host.

This is the correct behavior for all the ME devices yet the
the previous versions are less susceptive to the implementation
that ignored FW reset completion indication.

We add mei_me_hw_reset_release function which is called
after reset from the interrupt thread or directly
from mei_reset during power down.

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Tomas Winkler authored and Greg Kroah-Hartman committed Mar 15, 2013
1 parent 7cb035d commit 68f8ea1
Showing 1 changed file with 20 additions and 9 deletions.
29 changes: 20 additions & 9 deletions drivers/misc/mei/hw-me.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,20 @@ static void mei_me_intr_disable(struct mei_device *dev)
mei_hcsr_set(hw, hcsr);
}

/**
* mei_me_hw_reset_release - release device from the reset
*
* @dev: the device structure
*/
static void mei_me_hw_reset_release(struct mei_device *dev)
{
struct mei_me_hw *hw = to_me_hw(dev);
u32 hcsr = mei_hcsr_read(hw);

hcsr |= H_IG;
hcsr &= ~H_RST;
mei_hcsr_set(hw, hcsr);
}
/**
* mei_me_hw_reset - resets fw via mei csr register.
*
Expand All @@ -169,18 +183,14 @@ static void mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
if (intr_enable)
hcsr |= H_IE;
else
hcsr &= ~H_IE;

mei_hcsr_set(hw, hcsr);

hcsr = mei_hcsr_read(hw) | H_IG;
hcsr &= ~H_RST;
hcsr |= ~H_IE;

mei_hcsr_set(hw, hcsr);

hcsr = mei_hcsr_read(hw);
if (dev->dev_state == MEI_DEV_POWER_DOWN)
mei_me_hw_reset_release(dev);

dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", hcsr);
dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", mei_hcsr_read(hw));
}

/**
Expand Down Expand Up @@ -466,7 +476,8 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
mutex_unlock(&dev->device_lock);
return IRQ_HANDLED;
} else {
dev_dbg(&dev->pdev->dev, "FW not ready.\n");
dev_dbg(&dev->pdev->dev, "Reset Completed.\n");
mei_me_hw_reset_release(dev);
mutex_unlock(&dev->device_lock);
return IRQ_HANDLED;
}
Expand Down

0 comments on commit 68f8ea1

Please sign in to comment.