From 47f60a017169d1d3c6cb086ece272f272f110845 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Thu, 2 Feb 2017 11:26:54 +0200 Subject: [PATCH] mei: me: generate an interrupt if the hw indicates reset. In rare case the driver may lose connection with the device after device reset due to a missed interrupt. The driver will unlock the flow by generating an interrupt towards the firmware (HIG) when the device is in the resetting state. The FW is able to ignore the interrupt during orderly flow. The effected platforms are skylake and newer. Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 23294b845c42..71216affcab1 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -393,6 +393,19 @@ static bool mei_me_hw_is_ready(struct mei_device *dev) return (mecsr & ME_RDY_HRA) == ME_RDY_HRA; } +/** + * mei_me_hw_is_resetting - check whether the me(hw) is in reset + * + * @dev: mei device + * Return: bool + */ +static bool mei_me_hw_is_resetting(struct mei_device *dev) +{ + u32 mecsr = mei_me_mecsr_read(dev); + + return (mecsr & ME_RST_HRA) == ME_RST_HRA; +} + /** * mei_me_hw_ready_wait - wait until the me(hw) has turned ready * or timeout is reached @@ -1219,6 +1232,9 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) goto end; } + if (mei_me_hw_is_resetting(dev)) + mei_hcsr_set_hig(dev); + mei_me_pg_intr(dev, me_intr_src(hcsr)); /* check if we need to start the dev */