Commit 68f8ea18 authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman

mei: ME hardware reset needs to be synchronized

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: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7cb035d9
...@@ -151,6 +151,20 @@ static void mei_me_intr_disable(struct mei_device *dev) ...@@ -151,6 +151,20 @@ static void mei_me_intr_disable(struct mei_device *dev)
mei_hcsr_set(hw, hcsr); 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. * mei_me_hw_reset - resets fw via mei csr register.
* *
...@@ -169,18 +183,14 @@ static void mei_me_hw_reset(struct mei_device *dev, bool intr_enable) ...@@ -169,18 +183,14 @@ static void mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
if (intr_enable) if (intr_enable)
hcsr |= H_IE; hcsr |= H_IE;
else else
hcsr &= ~H_IE; hcsr |= ~H_IE;
mei_hcsr_set(hw, hcsr);
hcsr = mei_hcsr_read(hw) | H_IG;
hcsr &= ~H_RST;
mei_hcsr_set(hw, hcsr); 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));
} }
/** /**
...@@ -466,7 +476,8 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) ...@@ -466,7 +476,8 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
mutex_unlock(&dev->device_lock); mutex_unlock(&dev->device_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} else { } 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); mutex_unlock(&dev->device_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment